Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Finding whether stream intersection is non-empty

Obtaining an intersection of two streams, or finding whether their intersection is empty or not is generally not possible in Java, since streams can only be used once, and the generic solution has a O(m*n) complexity.

If we don't know anything about the nature of the underlying supplier, we can get away with at most one stream and one collection:

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

Still, what if both our suppliers represent ordered collections sorted using the same comparator (in the most simple case, two TreeSets of Comparables)? In this case, solution will have linear complexity (or, more precise, O(m*n), see this answer).

Now the question: can the above linear solution be implemented using only Stream API (i. e. using two streams as the input)?

like image 679
Bass Avatar asked May 26 '16 13:05

Bass


1 Answers

You can just collect the second Stream into a Set and ask whether any element of the first Stream is contained in this set:

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

Making the set out of c1 is linear in terms of the number of elements in it, and contains is a constant-time operation.

like image 175
Tunaki Avatar answered Sep 22 '22 15:09

Tunaki