Saturday, October 31, 2015

Java 8 Streams API: Finding and matching

The Streams API provides some useful methods to determine whether elements in a stream match a given condition.

anyMatch
The anyMatch method can be used to check if there exists an element in the stream that matches a given predicate. For example, to find out whether a stream of random numbers has a number greater than 5:

IntStream randomStream = new Random(100, 1, 11);
if (randomStream.anyMatch(i -> i > 5)) {
 System.out.println("The stream has a number greater than 5");
}

allMatch
The allMatch method can be used to check if all elements in the stream match a given predicate. For example, to find out whether a stream of random numbers only contains positive numbers:

boolean isPositive = randomStream.allMatch(i -> i > 0);

noneMatch
noneMatch is the opposite of allMatch and can be used to check that no elements in the stream match a given predicate. The previous example could be rewritten using noneMatch as follows:

boolean isPositive = randomStream.noneMatch(i -> i <= 0);

findAny
The findAny method returns an arbitrary element of the stream. It returns an Optional because it's possible that no element might be returned by findAny. For example, to find a number greater than 5 in our random number stream:

OptionalInt number = randomStream.filter(i -> i > 5)
                                 .findAny();

findFirst
findFirst is similar to findAny but returns the first element in the stream. For example, to find the first number greater than 5 in our random number stream:

OptionalInt number = randomStream.filter(i -> i > 5)
                                 .findFirst();

The difference between findAny and findFirst arises when using parallel streams. Finding an arbitrary element in a stream is less constraining than finding the first element, when running in parallel mode, so findAny may perform better. So, if you don't care about which element is returned, use findAny.

An interesting thing to note is that the operations described above use short-circuiting i.e. they don't need to process the entire stream to produce a result. As soon as an appropriate element is found, a result is returned.