测试两组是否与Java流共享3个元素

时间:2019-05-14 14:50:03

标签: java set java-stream

我需要Java流操作来测试两组是否至少具有3个公共元素。

这是我的Java 7代码,可以正常工作:

@Test
public void testContainement(){
    Set<Integer> setOne = IntStream.of(0,1,4,3)
                                   .boxed()
                                   .collect(Collectors.toCollection(HashSet::new));

    Set<Integer> setTwo = IntStream.of(0,1,4,5)
            .boxed()
            .collect(Collectors.toCollection(HashSet::new));

    Assertions.assertEquals(true,testSets(setOne,setTwo));

}

private boolean testSets( Set<Integer> setOne, Set<Integer> setTwo ) {
    int counter=0;
    for (int x: setOne){
        if (setTwo.contains(x))
            counter++;
    }
    return counter > 2;
}

如何用Java流操作做到这一点?

3 个答案:

答案 0 :(得分:11)

您可以简单地使用Set.retainAll(Collection)

setOne.retainAll(setTwo);
boolean isMoreTwo = setOne.size() > 2

如果您不想修改setOne,请创建Set的新实例:

Set<Integer> newSetOne = new HashSet<>(setOne)
newSetOne.retainAll(setTwo);
boolean isMoreTwo = newSetOne.size() > 2

请注意,实际显示的解决您需求的所有方法(在您的问题中,我的答案以及Naman的一种方法)都不是在单元测试中执行断言的正确方法。
如果断言失败,则断言应该产生有用的错误消息。
因此,这对您毫无帮助,因为布尔值是对还是错,仅此而已:

Assertions.assertEquals(true,testSets(setOne,setTwo));

此外,它的写法也应类似于:

Assertions.assertTrue(testSets(setOne,setTwo));

要满足您的要求,您应该计算集合之间匹配元素的数量,并在达到所需目标后立即停止。

long nbMatchLimitedToThree = setOne.stream().filter(setTwo::contains).limit(3).count();
Assertions.assertEqual(3, nbMatchLimitedToThree, "At least 3 matches expected but actually only " +  nbMatchLimitedToThree +". setOne=" + setOne + ",setTwo=" + setTwo);  

性能更高,这是编写单元测试的正确方法。

答案 1 :(得分:6)

使用Stream.count作为

private boolean testSets(Set<Integer> setOne, Set<Integer> setTwo) {
    return setOne.stream().filter(setTwo::contains).count() > 2;
}

或添加到其中,如果在早期发现了两个以上的元素,则避免遍历整个集合,请使用limit作为

return setOne.stream().filter(setTwo::contains).limit(3).count() > 2;

答案 2 :(得分:2)

番石榴很容易阅读:

private boolean testSets( Set<Integer> setOne, Set<Integer> setTwo ) {
     return Sets.intersection(setOne, setTwo).size() > 2;
}