2016-02-19 35 views
9

Tôi quan tâm đến việc xác định một phương pháp trả về một danh sách các phần tử không bao gồm các phần tử trong danh sách khác.Luồng Java 8. tất cả các phần tử EXCEPT các yếu tố khác

ví dụ

List<Integer> multiplesOfThree = ... // 3,6,9,12 etc 
List<Integer> evens = ... // 2,4,6,8 etc 
List<Integer> others = multiplesOfThree.except(evens) // should return a list of elements that are not in the other list 

làm thế nào để bạn làm điều này? tôi tìm thấy một cách tiếp cận đó là một chút thời gian và khó khăn để đọc ....

multiplesOfThree.stream() 
.filter(intval -> evens.stream().noneMatch(even -> even.intValue() == intval.intValue())) 

Trả lời

12

Bạn có thể sử dụng Stream's filter method, đi qua một Predicate đảm bảo rằng các phần tử không tồn tại trong evens.

List<Integer> others = multiplesOfThree.stream() 
     .filter(i -> !evens.contains(i)) 
     .collect(Collectors.toList()); 

Nhưng giả sử bạn có một có thể thay đổi List (ví dụ ArrayList), bạn thậm chí không cần suối, chỉ Collections's removeAll method.

multiplesOfThree.removeAll(evens); 
+0

removeAll là giải pháp tuyệt vời. –

5

Bạn có thể sử dụng

multipleOfThree.stream() 
       .filter(((Predicate<Integer>) evens::contains).negate()) 

hoặc hiệu quả hơn cho even danh sách lớn

HashSet<Integer> evenSet = new HashSet<>(even); 
multipleOfThree.stream() 
       .filter(((Predicate<Integer>) evenSet::contains).negate()) 
1

Có một vài giải pháp.

Thứ nhất, mà không sử dụng con suối, bạn có thể chỉ cần tạo một danh sách mới và loại bỏ tất cả các yếu tố từ một bộ sưu tập từ nó ...

final List<Integer> multiplesOfThree = Arrays.asList(3,6,9,12); 
final List<Integer> evens = Arrays.asList(2,4,6,8,10,12); 
final List<Integer> others1 = new ArrayList<>(multiplesOfThree); 
others1.removeAll(evens); 

giải pháp sẽ được để vượt qua dòng thông qua một bộ lọc():

final List<Integer> others2 = multiplesOfThree 
    .stream() 
    .filter(x -> !evens.contains(x)) 
    .collect(Collectors.toList()); 

(Bạn có thể cân nhắc thực hiện evens một Set trong trường hợp này).

Và cuối cùng, bạn có thể sửa đổi logic ở trên để đại diện cho "evens" làm hàm thay vì tập hợp tất cả các số chẵn. Về cơ bản, điều này giống như ở trên, nhưng bạn không cần phải có bộ sưu tập thứ hai.

final List<Integer> others3 = multiplesOfThree 
    .stream() 
    .filter(x -> x % 2 != 0) 
    .collect(Collectors.toList()); 
Các vấn đề liên quan