Câu trả lời này chỉ áp dụng cho tập hợp các số nguyên, không phải tập hợp chung. Nhưng đối với một người tìm kiếm tốc độ, đôi khi danh sách các số nguyên là một trường hợp tốt cho bitmap nén. Bạn nên kiểm tra xem nhóm nguyên của bạn độc đáo và trong một số trường hợp, bạn có thể giành chiến thắng vài bậc độ lớn vào tốc độ nếu bạn làm điều này (sử dụng com.googlecode.javaewah32, Apache 2.0):
Set<Integer> foo = ImmutableSet.of(1,2,3,4,8,9);
Set<Integer> bar = ImmutableSet.of(1,3,8,5,11);
EWAHCompressedBitmap32 fooBitmap = new EWAHCompressedBitmap32();
EWAHCompressedBitmap32 barBitmap = new EWAHCompressedBitmap32();
//fill bitmaps
foo.stream().forEach(fooBitmap::set);
bar.stream().forEach(barBitmap::set);
//fooBitmap.and(barBitmap) returns intersection of sets now. fast!
ImmutableSet<Integer> intersection = ImmutableSet.<Integer>builder()
.addAll(fooBitmap.and(barBitmap))
.build();
System.out.println(intersection);
Mã này chỉ là một ví dụ. Bạn có thể/nên sử dụng một cách tiếp cận khác để chuyển đổi thành tập hợp kết quả. EWAHCompressedBitmap32
là Iterable<Integer>
vì vậy, không có giới hạn về trí tưởng tượng.
Bây giờ, mã ở trên chỉ cắt 2 bộ. Để cắt tất cả các bộ trong danh sách, bạn có thể làm như thường lệ giảm:
Set<Integer> foo = ImmutableSet.of(1,2,3,4,8,9);
Set<Integer> bar = ImmutableSet.of(1,3,8,5,11);
List<Set<Integer>> sets = ImmutableList.of(foo,bar);
EWAHCompressedBitmap32 res = sets.stream().map(l -> {
EWAHCompressedBitmap32 b = new EWAHCompressedBitmap32();
l.stream().forEach(b::set);
return b;
}).reduce(null, (l, r) -> l == null ? r : l.and(r));
System.out.println(res);
Tuy nhiên, thay thế khác là sử dụng giảm thu:
EWAHCompressedBitmap32 res = sets.stream().collect(Collectors.reducing(
//identity
null,
//mapper set -> compressedBitmap
l -> {
EWAHCompressedBitmap32 b = new EWAHCompressedBitmap32();
l.stream().forEach(b::set);
return b;
},
//and-reducer
(l, r) -> l == null ? r : l.and(r)
));
http://stackoverflow.com/questions/31683375/java-8-lambda-intersection-of-two-lists – Wilson
Thay vì 'ImmutableList.of (foo, bar) .stream()' bạn chỉ có thể sử dụng ' Stream.of (foo, bar) '… – Holger
@Wilson: Tôi đã thấy câu hỏi đó. Tôi cần một giao lộ, chứ không phải hai bộ chỉ –