2015-06-24 15 views
6

phép nói rằng tôi cóTôi có thể lọc một dòng <T> theo lớp của phần tử để có được một Dòng <U> trong một bước không?

class Dog extends Animal {} 
class Cat extends Animal {} 

Và tôi có một danh sách các vật Sử dụng Ổi FluentIterable Tôi có thể lọc và chuyển đổi trong một bước

List<Cat> cats = FluentIterable.from(animals) 
    .filter(Cat.class) 
    .toList(); 

Sử dụng Java8 tôi cần phải làm

List<Cat> cats = animals.stream() 
    .filter(c -> c instanceof Cat) 
    .map(c -> (Cat) c) 
    .collect(Collectors.toList()); 

Không có cách nào tôi có thể làm cho bộ lọc & bản đồ trong một bước, phải không?

+0

Trong C# đó là 'Enumerable.OfType ' phương pháp khuyến nông, nhưng tôi không biết nó là gì trong java. –

+0

ma thuật 'flatMap()' .... nhưng không làm điều đó :) – ZhongYu

+1

cũng thử '.filter (Cat.class :: isInstance) .map (Cat.class :: cast)' - nó không phải là tốt hơn tất nhiên. – ZhongYu

Trả lời

3

Bước map không cần thiết khi chạy (chỉ đơn giản là không có gì), bạn cần nó để bỏ qua việc kiểm tra kiểu trong quá trình biên dịch. Hoặc bạn có thể sử dụng dàn diễn viên không được kiểm soát bẩn:

List<Cat> cats = ((Stream<Cat>) (Stream<?>) animals.stream().filter(
     c -> c instanceof Cat)).collect(Collectors.toList()); 

Thật không may là không có cách nào tiêu chuẩn để thực hiện việc này trong một bước, nhưng bạn có thể sử dụng thư viện của bên thứ ba. Ví dụ, trong thư viện StreamEx tôi có một phương pháp selectsolves this problem:

List<Cat> cats = StreamEx.of(animals).select(Cat.class).toList(); 
+0

Tôi đã không nhận ra đó là một điều chỉ biên dịch ... –

Các vấn đề liên quan