有效地确定两个集合在Java中是否有任何共同项

有效地确定两个集合在Java中是否有任何共同项,java,collections,set,intersection,Java,Collections,Set,Intersection,我知道,在Java中,我可以通过将其中一个集合转换为一个集合,然后迭代另一个集合来手动确定两个集合是否有重叠: <T> boolean anyInCommon(Iterable<T> collection1, Set<T> collection2) { for (T item : collection1) if (collection2.contains(item)) return true; retur

我知道,在Java中,我可以通过将其中一个集合转换为一个集合,然后迭代另一个集合来手动确定两个集合是否有重叠:

<T> boolean anyInCommon(Iterable<T> collection1, Set<T> collection2) {
    for (T item : collection1)
        if (collection2.contains(item))
            return true;
    return false;
}
boolean anyInCommon(Iterable collection1,Set collection2){
对于(T项:集合1)
if(集合2.包含(项目))
返回true;
返回false;
}
或者:

<T> boolean anyInCommon(Iterable<T> collection1, Set<T> collection2) {
    return collection1.stream().anyMatch(collection2::contains);
}
boolean anyInCommon(Iterable collection1,Set collection2){
返回collection1.stream().anyMatch(collection2::contains);
}
但是,现有的实用程序方法是否可以做到这一点,并智能地选择迭代哪个集合、将哪个集合转换为一个集合、利用一个集合已经是一个集合的优势,等等?我知道番石榴有
集合.intersection
,但它计算整个交叉点,而不仅仅是它是否为空


请注意,我更希望在找到任何常见项目后立即进行比较,而不是短路。检查两个大型集合是否重叠所需的时间应与非重叠项目的数量(或更好)成比例,而不是项目的总数。

部分回答集合已设置的时间

set.intersection
实际上比我想象的更接近我想要的,因为它的结果不是预先计算的。而不是动态计算的交点

看看:


这不会迭代较小的集合而不是较大的集合,也不会处理非集合集合,但它通常很有用。

不回答您的问题,但如果目标只是确定是否存在交集,那么我怀疑在许多情况下,将其转换为集合可能是浪费时间。当然,这取决于你有多少份副本。这只取决于副本的数量吗?我认为最重要的区别是
contains
测试的成本,它在
集合
中比在任何其他类型的
集合
中都要好。此外,如果使用的.contains()是
哈希集
的,则摊销时间为O(1),因此得到O(n)交叉method@cornuz如果集合很小,这是正确的,但是对于大型集合来说,将
O(1)
时间改为
O(n)
时间是绝对值得的,因为从
O(n*m)
改为
O(n+m)
。短路可以让你在有很多重叠的情况下做得更好。是的,我完全同意使用交叉路口比在找到第一个匹配点后停车慢几个数量级。创建一个新的集合比仅仅计算匹配数要昂贵得多,而计算匹配数比在第一个匹配后停止要昂贵得多。@PeterLawrey是的,这就是为什么这个答案解释并显示
set.intersection.isEmpty
在第一个匹配后停止,并且不会创建一个完整的新集合。无论如何,它必须创建一个对象来调用
isEmpty
,因此这将比一个以相同方式工作但不创建对象的方法要慢。@Peter是的,但问题的主体是询问已经至少在某种程度上有效地完成这项工作的现有方法。这是我找到的最接近的一个。
final Predicate<Object> inSet2 = Predicates.in(set2);
return new SetView<E>() {
  @Override public Iterator<E> iterator() {
    return Iterators.filter(set1.iterator(), inSet2);
  }
  @Override public int size() {
    return Iterators.size(iterator());
  }
  @Override public boolean isEmpty() {
    return !iterator().hasNext();
  }
  @Override public boolean contains(Object object) {
    return set1.contains(object) && set2.contains(object);
  }
  @Override public boolean containsAll(Collection<?> collection) {
    return set1.containsAll(collection)
        && set2.containsAll(collection);
  }
};
boolean overlaps = !Sets.intersections(set1, set2).isEmpty();