4.2.  Search for data by using methods such as findFirst(), findAny(), anyMatch(), allMatch(), and noneMatch()

[Note]

Finding the first element - findFirst

Some streams have an encounter order that specifies the order in which items logically appear in the stream (for example, a stream generated from a List or from a sorted sequence of data).

For such streams you may wish to find the first element. There is the findFirst method for this:


Optional<T> findFirst();

					

For example, the code that follows, given a list of numbers, finds the first square that is divisible by 7:


List<Integer> ints = Arrays.asList(1, 6, 22, 21, 35, 36);
Optional<Integer> result = ints.stream().filter(i ->i % 7 == 0).findFirst();
System.out.println(result.get());

					

Finding an element - findAny

The findAny method returns an arbitrary element of the current stream.


Optional<T> findAny();

					

It can be used in conjunction with other stream operations. For example, you may wish to find any manager from employee list. You can combine the filter(...) method and findAny to express this query:

public class Employee {
    public static final int MANAGER=100;
    public int type;
    public String name;

    public Employee(int t, String n) {
        type = t;
        name = n;
    }
}
					


Stream<Employee> emps = Stream.of(new Employee(100, "John"), new Employee(100, "Jane"), new Employee(99, "Deb"));
Optional<Employee> mgr = emps.filter(a -> a.type == Employee.MANAGER).findAny();
System.out.println(mgr.get().name);

					

The stream pipeline will be optimized behind the scenes to perform a single pass and finish as soon as a result is found by using short-circuiting.

You may wonder why Java 8 has both findFirst() and findAny. The reason behind findAny() is to give a more flexible alternative to findFirst(). If you are not interested in getting a specific element, this gives the implementing stream more flexibility in case it is a parallel stream.

No effort will be made to randomize the element returned, it just does not give the same guarantees as findFirst(), and might therefore be faster.

The behavior of findAny() operation is explicitly nondeterministic; it is free to select any element in the stream. This is to allow for maximal performance in parallel operations; the cost is that multiple invocations on the same source may not return the same result. If a stable result is desired, use findFirst() instead.

Checking to see if a predicate matches at least one element - anyMatch

The anyMatch(...) method can be used to answer the question "Is there an element in the stream matching the given predicate?" It accepts Predicate as parameter:


boolean anyMatch(Predicate<? super T> predicate);

					

For example, you can use it to find out whether company has an employee with name "Mikalai":


Stream<Employee> emps = Stream.of(new Employee(100, "Minerva"), new Employee(100, "Mikalai"), new Employee(99, "Michael"));
boolean b = emps.anyMatch(e -> "Mikalai".equalsIgnoreCase(e.name));
if (b) {
    System.out.println("There is an employee with name 'Mikalai'");
}

					

The anyMatch(...) method returns a boolean and is therefore a terminal operation.

Checking to see if a predicate matches all elements - allMatch

The allMatch(...) method works similarly to anyMatch(...) but will check to see if all the elements of the stream match the given predicate:


boolean allMatch(Predicate<? super T> predicate);

					

For example, you can use it to find out whether all employee names start with "Mi":


Stream<Employee> emps = Stream.of(new Employee(100, "Minerva"), new Employee(100, "Mikalai"), new Employee(99, "Michael"));
boolean b = emps.allMatch(e -> e.name.startsWith("Mi"));
if (b) {
    System.out.println("All employee names start with 'Mi'");
}

					

Checking to see if a predicate does not matche any element - noneMatch

The opposite of allMatch(...) is noneMatch(...). It ensures that no elements in the stream match the given predicate:


boolean noneMatch(Predicate<? super T> predicate);

					

For example, you can use it to find out whether company has an employee with name "Gandalf":


Stream<Employee> emps = Stream.of(new Employee(100, "Minerva"), new Employee(100, "Mikalai"), new Employee(99, "Michael"));
boolean b = emps.noneMatch(e -> e.name.equals("Gandalf"));
if (b) {
    System.out.println("Gandalf is employed by some other company !");
}

					

[Important]

Remember method signatures:

  • All findXxx() methods have no arguments and return Optional.

  • All xxxMatch(...) methods accept a Predicate and return a boolean primitive.

[Important]

Some operations do not need to process the whole stream to produce a result. For example, you need to evaluate a large boolean expression chained with "and" operators. You need only find out that one expression is false to deduce that the whole expression will return false, no matter how long the expression is; there is no need to evaluate the entire expression. This is what short-circuiting refers to.

In relation to streams, operations anyMatch(...), allMatch(...), noneMatch(...), findFirst(), and findAny() do not need to process the whole stream to produce a result. As soon as an element is found, a result can be produced.

Professional hosting         Free 'Oracle Certified Expert Web Services Developer 6' Guide     Exam 1Z0-810: Upgrade to Java SE 8 Programmer Quiz