使用 Stream 比较两个集合 - anyMatch

新手上路,请多包涵

我想比较 list2 中的任何对象是否存在于 list1 中。

我可以遍历两个列表并使用 .contains() 比较所有元素,但我想知道是否没有更有效的方法。我发现 了这个,我正在尝试实施建议的方法:

 List<Item> list1;
List<Item> list2;

boolean anyMatch = list1.stream().anyMatch(x -> x.equals(list2.stream()));
System.out.println(anyMatch);

当我这样做时,我经常得到 false ,即使我期望 true 。怎么来的?

原文由 k88 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 1.9k
2 个回答

根据您的评论,您有两个列表 list1list2 。您想要确定 list2 中的元素是否至少包含在 list1 中。

使用 Stream API,您可以获得 Streamlist2 。然后,调用 anyMatch(predicate) 返回此流的元素之一是否与给定谓词匹配,在这种情况下,它测试该元素是否包含在 list1 中。

 boolean anyMatch = list2.stream().anyMatch(list1::contains);

这使用 方法引用 作为谓词。

通过将 list1 转换为 Set ,您可以获得更好的性能,这保证了恒定时间查找:

 boolean anyMatch = list2.stream().anyMatch(new HashSet<>(list1)::contains);

原文由 Tunaki 发布,翻译遵循 CC BY-SA 3.0 许可协议

尽管 @Tunaki 的回答 是正确的,但这是另一种更简洁的方法(虽然它不使用 Stream.anyMatch() 方法):

 boolean anyMatch = !Collections.disjoint(list1, list2);

这使用 Collections.disjoint() 方法,当两个集合没有共同的元素时返回 true

Tunaki 关于性能的评论也适用于此:为了获得更好的性能,最好将 list1 变成 O(1) HashSet ,因为它的 contains() 方法是 --- 平均。 Collections.disjoint() 方法实际上检查它的任何参数是否是 Set 并迭代不是 Set 的集合所以在你的情况下,你所要做的就是从你的 --- 创建一个 HashSet list1

 boolean anyMatch = !Collections.disjoint(new HashSet<>(list1), list2);

注意:毕竟,我的答案只比 Tunaki 的答案短 5 个字符 :)

原文由 fps 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
logo
Stack Overflow 翻译
子站问答
访问
宣传栏