如何计算两个以上HashSets之间的交集?

时间:2016-06-14 02:49:03

标签: java intersection hashset retain

考虑下面的代码以及4 HashSet在其他地方填充的事实。

我的目标是包含所有4个HashSets中常见的所有元素。

我的问题是,首先,我做得对吗?其次,如果我做得对,有没有更好的方法呢?如果没有,那么我对此问题有什么解决方案?

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);
}

3 个答案:

答案 0 :(得分:9)

我认为你可以简单地在第一组上调用retainAll(),使用第二,第三和第四组作为参数:

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;
}

答案 1 :(得分:3)

我对Java 8有点新鲜,但这看起来很可读:

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

这是一个快速试验的Junit测试:

@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);
}

答案 2 :(得分:0)

我认为处理这个问题的最佳方法是使用Groovy。我知道你并没有要求时髦,但任何时候我都可以将所有代码转换成一行,这很难抗拒。

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