Search for data by using search methods of the Stream classes including findFirst, findAny, anyMatch, allMatch, noneMatch.
Searching is a common operation when you have a set of data.
The Stream API has two types of operation for searching.
Methods starting with Find:
Optional<T> findAny()
Optional<T> findFirst()
That search for an element in a stream. Since there's a possibility that an element couldn't be found (if the stream is empty, for example), the return type of this methods is an Optional
.
And method ending with Match:
boolean allMatch(Predicate<? super T> predicate)
boolean anyMatch(Predicate<? super T> predicate)
boolean noneMatch(Predicate<? super T> predicate)
That indicate if a certain element matches the given predicate, that's why they return a boolean
.
Since all these methods return a type different than a stream, they are considered TERMINAL operations.
findAny()
and findFirst()
practically do the same, they return the first element they find in a stream:
IntStream stream = IntStream.of(1, 2, 3, 4, 5, 6, 7);
stream.findFirst()
.ifPresent(System.out::println); // 1
IntStream stream2 = IntStream.of(1, 2, 3, 4, 5, 6, 7);
stream2.findAny()
.ifPresent(System.out::println); // 1
If the stream is empty, they return an empty Optional
:
Stream<String> stream = Stream.empty();
System.out.println(
stream.findAny().isPresent()
); // false
Of course, you can combine these methods with other stream operations:
IntStream stream = IntStream.of(1, 2, 3, 4, 5, 6, 7);
stream
.filter(i -> i > 4)
.findFirst()
.ifPresent(System.out::println); // 5
When to use findAny()
and when to use findFirst()
?
When working with parallel streams, it's harder to find the first element. In this case, it's better to use findAny()
if you don't really mind which element is returned.
anyMatch()
returns true if any of the elements in a stream matches the given predicate:
IntStream stream = IntStream.of(1, 2, 3, 4, 5, 6, 7);
System.out.println(
stream.anyMatch(i -> i%3 == 0)
); // true
If the stream is empty or if there's no matching element, this method returns false
:
IntStream stream = IntStream.empty();
System.out.println(
stream.anyMatch(i -> i%3 == 0)
); // false
IntStream stream2 = IntStream.of(1, 2, 3, 4, 5, 6, 7);
System.out.println(
stream2.anyMatch(i -> i%10 == 0)
); // false
allMatch()
returns true only if ALL elements in the stream match the given predicate:
IntStream stream = IntStream.of(1, 2, 3, 4, 5, 6, 7);
System.out.println(
stream.allMatch(i -> i > 0)
); // true
IntStream stream2 = IntStream.of(1, 2, 3, 4, 5, 6, 7);
System.out.println(
stream2.allMatch(i -> i%3 == 0)
); // false
If the stream is empty, this method returns TRUE without evaluating the predicate:
IntStream stream = IntStream.empty();
System.out.println(
stream.allMatch(i -> i%3 == 0)
); // true
noneMatch()
is the opposite of allMatch()
, it returns true if NONE of the elements in the stream match the given predicate:
IntStream stream = IntStream.of(1, 2, 3, 4, 5, 6, 7);
System.out.println(
stream.noneMatch(i -> i > 0)
); // false
IntStream stream2 = IntStream.of(1, 2, 3, 4, 5, 6, 7);
System.out.println(
stream2.noneMatch(i -> i%3 == 0)
); // false
IntStream stream3 = IntStream.of(1, 2, 3, 4, 5, 6, 7);
System.out.println(
stream3.noneMatch(i -> i > 10)
); // true
If the stream is empty, this method returns also TRUE without evaluating the predicate:
IntStream stream = IntStream.empty();
System.out.println(
stream.noneMatch(i -> i%3 == 0)
); // true
All of these operations use something similar to the short-circuiting of &&
and ||
operators.
Short-circuiting means that the evaluation stops once a result is found.
In the case of the find* operations, it's obvious that they stop at the first found element.
But in the case of the *Match operations, think about it, why would you evaluate all the elements of a stream when by evaluating the third element (for example) you can know if all or none (for example) of the elements will match?
Consider this code:
IntStream stream = IntStream.of(1, 2, 3, 4, 5, 6, 7);
boolean b = stream
.filter(i -> {
System.out.println("Filter:" + i);
return i % 2 == 0; })
.allMatch(i -> {
System.out.println("AllMatch:" + i);
return i < 3;
});
System.out.println(b);
What would you think the output will be?
The output:
Filter:1
Filter:2
AllMatch:2
Filter:3
Filter:4
AllMatch:4
false
As you can see, first of all, operations on a stream are not evaluated sequentially (in this case, first filter all the elements and then evaluate if all elements match the predicate of allMatch()
).
Second, we can see that as soon as an element passes the filter predicate (like 2
) the predicate of allMatch()
is evaluated.
Finally, we can see short-circuiting in action. As soon as the predicate of allMatch()
finds an element that doesn't evaluate to true (like 4
), the two stream operations are canceled, no further elements are processed and the result is returned.
Just remember:
Optional<T> findAny()
Optional<T> findFirst()
boolean allMatch(Predicate<? super T> predicate)
boolean anyMatch(Predicate<? super T> predicate)
boolean noneMatch(Predicate<? super T> predicate)
findAny()
and findFirst()
practically do the same, they return the first element they find in a stream. If the stream is empty, they return an empty Optional
.findAny()
if you don't really mind which element is returned.anyMatch()
returns true if any of the elements in a stream matches the given predicate. If the stream is empty or if there's no matching element, it returns false
.allMatch()
returns true only if ALL elements in the stream match the given predicate.noneMatch()
returns true if NONE of the elements in the stream match the given predicate.allMatch()
and noneMatch()
return true
if the stream is empty.1. Given:
public class Question_15_1 {
public static void main(String[] args) {
Stream<Integer> s = Stream.of(100, 45, 98, 33);
s.anyMatch(i -> i > 50)
.findAny()
.ifPresent(System.out::println);
}
}
What is the result?
A. 100
B. 98
C. Nothing is printed
D. Compilation fails
2. Which of the following methods of the Stream interface returns an Optional
type?
A. filter()
B. findMatch()
C. findAny()
D. anyMatch()
3. Given:
public class Question_15_3 {
public static void main(String[] args) {
IntStream stream = IntStream.of(1, 2, 3, 4, 5, 6, 7);
stream.allMatch(i -> {
System.out.print(i);
return i % 3 == 0;
});
}
}
What is the result?
A. 1234567
B. 36
C. 1
D. Compilation fails
4. Given:
public class Question_15_4 {
public static void main(String[] args) {
IntStream stream = IntStream.of(1, 2, 3, 4, 5, 6, 7);
stream.filter(i -> {
return i > 3;
}).anyMatch(i -> {
System.out.print(i);
return i % 2 == 1;
});
}
}
What is the result?
A. 45
B. 5
C. 4567
D. Compilation fails