This answer is only applicable for sets of Integers, not generic sets. But for someone looking for speed, sometimes lists of integers are a good case for compressed bitmaps. You should check if your integers group nicely and in some cases you can win couple of orders of magnitude on speed if you do this (using com.googlecode.javaewah32, Apache 2.0 license):
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);
This code is just an example. You might/should use a different approach to convert to resulting set. EWAHCompressedBitmap32
is Iterable<Integer>
so, there is no limit to imagination.
Now, the code above just intersects 2 sets. To intersect all sets in the list, you can do the usual reduce:
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);
Yet another alternative is to use reducing collector:
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)
));