How to calculate the intersection between more than two HashSets?

Given the code below and the fact that 4 HashSet populated elsewhere.

My goal is to contain all the elements (elements) that are common to all 4 HashSets.

My question is, first of all, am I doing this right? Secondly, if I do it right, is there a better way to do this? If not, what solution do I have for this problem?

 static Set<String> one=new HashSet<>(); static Set<String> two=new HashSet<>(); static Set<String> three=new HashSet<>(); static Set<String> four=new HashSet<>(); private static void createIntersectionQrels() { ArrayList<String> temp = new ArrayList<>(); Set<String> interQrels = new HashSet<>(); temp.addAll(one); one.retainAll(two); interQrels.addAll(one); one.addAll(temp); one.retainAll(three); interQrels.addAll(one); one.addAll(temp); one.retainAll(four); interQrels.addAll(one); one.addAll(temp); interQrels.retainAll(two); interQrels.retainAll(three); interQrels.retainAll(four); } 
+6
source share
3 answers

I think you can just call retainAll() on the first set, using the second, third and fourth sets as parameters:

 private static Set<String> getIntersectionSet() { // create a deep copy of one (in case you don't wish to modify it) Set<String> interQrels = new HashSet<>(one); interQrels.retainAll(two); // intersection with two (and one) interQrels.retainAll(three); // intersection with three (and two, one) interQrels.retainAll(four); // intersection four (and three, two, one) return interQrels; } 
+9
source

I'm a little new to Java 8, but this seems pretty readable:

  Set<String> intersection = one.stream() .filter(two::contains) .filter(three::contains) .filter(four::contains) .collect(Collectors.toSet()); 

Here is a quick Junit test to try out:

 @Test public void testIntersectionBetweenSets() { Collection<String> one = new HashSet<>(4); one.add("Larry"); one.add("Mark"); one.add("Henry"); one.add("Andrew"); Set<String> two = new HashSet<>(2); two.add("Mark"); two.add("Andrew"); Set<String> three = new HashSet<>(3); three.add("Mark"); three.add("Mary"); three.add("Andrew"); Set<String> four = new HashSet<>(3); four.add("Mark"); four.add("John"); four.add("Andrew"); Set<String> intersection = one.stream() .filter(two::contains) .filter(three::contains) .filter(four::contains) .collect(Collectors.toSet()); Collection<String> expected = new HashSet<>(2); expected.add("Andrew"); expected.add("Mark"); Assert.assertEquals(expected, intersection); } 
+3
source

I think the best way to handle this is Groovy. I know that you did not ask groovy, but at any time I can convert all this code to one line, it is difficult to resist.

 println one.intersect(two).intersect(three).intersect(four) 
0
source

All Articles