查找流交叉是否为非空

Bas*_*ass 9 java algorithm java-8 java-stream

获取两个流的交集,或者查找它们的交集是否为空在Java中通常是不可能的,因为流只能使用一次,并且通用解决方案具有 O(m*n个) 复杂.

如果我们对底层供应商的性质一无所知,我们最多可以获得一个流和一个集合:

<T> boolean intersects(final Stream<T> c1, final Collection<T> c2) {
    return c1.filter(c2::contains).findAny().isPresent();
}
Run Code Online (Sandbox Code Playgroud)

不过,如果有什么我们的供应商代表有序集合使用相同的比较器(在最简单的情况下,两个分类TreeSetComparableS)?在这种情况下,解决方案将具有线性复杂性(或者更确切地说,O(m*n个),看到这个答案).

现在的问题是:上述线性解决方案是否只能使用Stream API实现(即使用两个流作为输入)?

Tun*_*aki 8

您可以将第二个Stream收集到a中,Set并询问该集合中是否包含第一个Stream的任何元素:

<T> boolean intersects(final Stream<T> c1, final Stream<T> c2) {
    return c1.anyMatch(c2.collect(Collectors.toSet())::contains);
}
Run Code Online (Sandbox Code Playgroud)

使得该集合c1在其中的元素数量方面是线性的,并且contains是恒定时间操作.

  • @Bass简短回答:没有.答案很长:noooooo.基本上,并非没有将流转换回迭代器. (3认同)
  • @Bass并且有一个迭代器的问题是你不能轻易地"窥视"一个元素.你需要使用`next()`来使用它,所以只推进两个迭代器中的一个是很困难的. (2认同)