Trong Java 8 với các luồng, nó thực sự khá đơn giản. CHỈNH SỬA: Có thể hiệu quả mà không cần luồng, xem thấp hơn.
List<String> listA = Arrays.asList("2009-05-18","2009-05-19","2009-05-21");
List<String> listB = Arrays.asList("2009-05-18","2009-05-18","2009-05-19","2009-05-19",
"2009-05-20","2009-05-21","2009-05-21","2009-05-22");
List<String> result = listB.stream()
.filter(not(new HashSet<>(listA)::contains))
.collect(Collectors.toList());
Lưu ý rằng tập hợp băm chỉ được tạo một lần: Tham chiếu phương thức được gắn với phương thức chứa của nó. Làm tương tự với lambda sẽ yêu cầu phải có tập hợp trong một biến. Tạo một biến không phải là một ý tưởng tồi, đặc biệt nếu bạn thấy nó khó coi hoặc khó hiểu hơn.
Bạn không thể dễ dàng phủ định vị từ mà không có một cái gì đó như phương thức tiện ích này (hoặc ép kiểu rõ ràng), vì bạn không thể gọi trực tiếp tham chiếu phương thức phủ định (trước tiên cần có suy luận kiểu).
private static <T> Predicate<T> not(Predicate<T> predicate) {
return predicate.negate();
}
Nếu các luồng có một filterOut
phương pháp hoặc một cái gì đó, nó sẽ trông đẹp hơn.
Ngoài ra, @Holger đã cho tôi một ý tưởng. ArrayList
có removeAll
phương pháp được tối ưu hóa cho nhiều lần xóa, nó chỉ sắp xếp lại các phần tử của nó một lần. Tuy nhiên, nó sử dụng contains
phương pháp được cung cấp bởi bộ sưu tập nhất định, vì vậy chúng ta cần tối ưu hóa phần đó nếu listA
là bất cứ thứ gì ngoại trừ nhỏ.
Với listA
và được listB
khai báo trước đó, giải pháp này không cần Java 8 và nó rất hiệu quả.
List<String> result = new ArrayList(listB);
result.removeAll(new HashSet<>(listA));