zak*_*zak 10 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;
}
Run Code Online (Sandbox Code Playgroud)
我们如何使用Java流操作来做到这一点?
dav*_*xxx 11
您可以简单地使用Set.retainAll(Collection):
setOne.retainAll(setTwo);
boolean isMoreTwo = setOne.size() > 2
Run Code Online (Sandbox Code Playgroud)
如果您不想修改setOne,请创建Set的新实例:
Set<Integer> newSetOne = new HashSet<>(setOne)
newSetOne.retainAll(setTwo);
boolean isMoreTwo = newSetOne.size() > 2
Run Code Online (Sandbox Code Playgroud)
请注意,实际显示的解决您需求的所有方法(在您的问题中,我的答案以及Naman的一种方法)都不是在单元测试中执行断言的正确方法。
如果断言失败,则断言应该产生有用的错误消息。
所以这实际上对您没有帮助,因为布尔值是对还是错,仅此而已:
Assertions.assertEquals(true,testSets(setOne,setTwo));
Run Code Online (Sandbox Code Playgroud)
此外,它也应该写成这样:
Assertions.assertTrue(testSets(setOne,setTwo));
Run Code Online (Sandbox Code Playgroud)
为了满足您的要求,您应该计算集合之间匹配元素的数量,并在达到所需目标后立即停止。
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);
Run Code Online (Sandbox Code Playgroud)
这样可以提高性能,这是编写单元测试的正确方法。
使用Stream.count如
private boolean testSets(Set<Integer> setOne, Set<Integer> setTwo) {
return setOne.stream().filter(setTwo::contains).count() > 2;
}
Run Code Online (Sandbox Code Playgroud)
或添加它,如果在早期发现了两个以上的元素,则避免迭代整个集合,请limit用作:
return setOne.stream().filter(setTwo::contains).limit(3).count() > 2;
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
101 次 |
| 最近记录: |