使用 Stream - anyMatch 比较两个集合

2022-09-02 23:20:50

我想比较一下a中的任何对象是否存在于.list2list1

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

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

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

当我这样做时,我经常得到,即使我期望一个.怎么会这样?falsetrue


答案 1

从您的注释中,您有两个列表,和 .您想要查明 中是否至少包含一个元素。list1list2list2list1

使用流 API,您可以获取 的 .然后,调用 anyMatch(谓词)返回此流的某个元素是否与给定谓词匹配,在本例中,该谓词将测试该元素是否包含在 中。Streamlist2list1

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

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

通过将 转换为 ,可以保证恒定时间查找,从而获得更好的性能:list1Set

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

答案 2

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

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

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

Tunaki关于性能的评论也适用于这里:为了获得更好的性能,最好的方法是将你变成一个,因为它的方法是一般的。该方法实际上检查其任何参数是否为 a,并循环访问不是 的集合。因此,在您的情况下,您所要做的就是从您的:list1HashSetcontains()O(1)Collections.disjoint()SetSetHashSetlist1

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

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


推荐