Java集合中是否包含“包含任何内容”之类的内容?


307

我有两个相同类型的集合A和B。

我必须查找A是否包含集合B中的任何元素。

在不迭代集合的情况下做到这一点的最佳方法是什么?Set库具有contains(object)and containsAll(collection),但没有containsAny(collection)


4
您是否出于效率原因或代码清洁性而避免迭代?
yshavit 2012年

Answers:


527

不行Collections.disjoint(A, B)吗 从文档中:

true如果两个指定的集合没有共同的元素,则返回。

因此,false如果集合包含任何公共元素,则该方法返回。


17
最好不要使用其他解决方案,因为它不会修改任何集合或创建新集合。
devconsole 2012年

7
并且是标准的JRE,并且可以与任何Collections一起使用,而不仅仅是设置。
皮埃尔·亨利

4
我认为这不是最快的方法,当找到相交的第一个元素时不会短路。
本·霍纳

7
实际上,它会在找到第一个公共元素后立即短路
Xipo


156

Stream::anyMatch

从Java 8开始,您可以使用Stream::anyMatch

setA.stream().anyMatch(setB::contains)

1
这正是我想要的!谢谢:-)我也不知道您可以在::语法中使用变量!
dantiston '16

1
@blevert,你能解释一下anyMatch内部发生什么吗?
克里斯蒂亚诺

7
@Cristiano在这里,anyMatch将流式传输所有元素setA并调用setB.contains()它们。如果对任何元素返回“ true”,则整个表达式的计算结果将为true。希望这会有所帮助。
Alex Vulaj


31

实现GuetsAny的好方法是使用Guava Sets.intersection()

containsAny会返回boolean,因此调用如下所示:

Sets.intersection(set1, set2).isEmpty()

如果集合不相交,则返回true,否则返回false。此方法的时间复杂度可能比keepAll好一点,因为您不必进行任何克隆操作即可避免修改原始集。


3
使用这种方法的唯一缺点是必须包含番石榴库。我认为这不是不利条件,因为Google集合API非常强大。
Mohammad Adnan 2014年

@DidierL的大多数Guava Collections实用程序功能(包括此功能)都将返回数据结构的视图。因此,在这种情况下,无需担心“构建集合”。实现有趣的是,读到这里,和/或看到的Javadoc:google.github.io/guava/releases/21.0/api/docs/com/google/common/...
chut

@MohammadAdnan另一个缺点是,它会计算完整的交集-如果set1和set2非常大,这将比仅检查它们是否有任何共同点要消耗更多的资源(在CPU和内存方面)。
6


16

我使用 org.apache.commons.collections.CollectionUtils

CollectionUtils.containsAny(someCollection1, someCollection2)

就这些!如果两个集合中至少有一个元素,则 返回true

使用简单,函数名称更具启发性。


5

使用retainAll()在设置界面。此方法提供了两个集合中共有的元素的交集。有关更多信息,请参见API文档。


如果避免迭代的目的是为了提高效率,则retainAll可能无济于事。它的实现AbstractCollection反复进行。
yshavit 2012年

1
yshavit是正确的。假设OP正在查看两个集合中是否存在任何元素,那么适当的算法O(1)在最佳情况下将具有运行时间,而retainAll在类似情况下将具有某种运行时间O(N)(这仅取决于1个集合的大小)最佳情况下的运行时间。
Zéychin

3

我建议HashMap从集合A 创建一个,然后遍历集合B并检查B中是否有任何元素在A中。这将O(|A|+|B|)及时运行(因为不会发生冲突),而retainAll(Collection<?> c)必须及时运行O(|A|*|B|)


3

有一些粗糙的方法可以做到这一点。当且仅当A集包含比呼叫多的B元素

A.removeAll(B)

将修改A集。在这种情况下,removeAll将返回true(如removeAll docs所述)。但是,您可能不想修改A集,因此您可能会考虑对副本执行以下操作:

new HashSet(A).removeAll(B)

如果集合没有区别,即它们具有非空交集,则返回值将为true。

另请参阅Apache Commons Collections


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.