查找流交叉是否为非空

时间:2016-05-26 13:59:41

标签: 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();
}

但是,如果我们的供应商都代表使用相同比较器排序的有序集合(在最简单的情况下,TreeSet的两个Comparable),该怎么办?在这种情况下,解决方案将具有线性复杂度(或者更确切地说,O(m*n),请参阅this回答)。

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

1 个答案:

答案 0 :(得分:8)

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

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

使c1的集合在其中的元素数量方面是线性的,contains是一个恒定时间操作。