Finding & MatchingJ8 Home « Finding & Matching

In previous lessons we have seen terminal operations producing a count, returning a boolean or optional or simply printing results to a console. In this lesson we look at the terminal operators for finding and matching elements of a stream.

The find methods within the Stream<E> interface return an Optional<T> object type whilst the matching methods return a boolean.

We will start by looking at the find methods of the Stream<E> interface.

Terminal Operations For Finding Top

There are two terminal operations for finding elements within a stream, findAny() which returns an Optional describing some element of the stream and findFirst() which returns an Optional describing the first element of this stream. Both of these methods return an empty Optional if the stream is empty.

Lets try these methods out! We will be using the Employee class we created in the Introducing Streams lesson to test against for this purpose.

Following is a TestFindInStream class to demonstrate finding elements within a stream using the findAny() and findFirst() methods of the Stream<E> interface.


package info.java8;

import java.util.Optional;

/* Find elements within a stream */
public class TestFindInStream {

    public static void main(String[] args) {

        // Find any element 
        Employee.listOfStaff().stream()
                .filter(e -> e.getAge() < 30)
                .findAny()
                .ifPresent(e -> System.out.println(e.getName()));
        
        // Find first element 
        Employee.listOfStaff().stream()
                .filter(e -> e.getAge() > 21)
                .findFirst()
                .ifPresent(e -> System.out.println(e.getName()));
        
        // Return an Optional
        Optional<Employee.Sex> sex = Employee.listOfStaff().stream()
                .map(Employee::getGender)
                .findFirst();
        System.out.println(sex);
        
        // Return an empty Optional
        Optional<Employee> age = Employee.listOfStaff().stream()
                .filter(e -> e.getAge() > 71)
                .findFirst();
        System.out.println(age);
    }
}

Building and running the TestFindInStream class produces the following output:

Run TestFindInStream class
Screenshot 1. Running the TestFindInStream class.

The first find selects any element within the stream that matches the predicate, in this case any employee under 30, which in this case is Jill.

The second find selects the first element within the stream that matches the predicate, in this case the first employee over 21, which is Jack. The stream has been created from a list so has kept the ordering and when you want to know the first of something in an ordered stream the findFirst() method is useful.

The third find selects the first Employee.Sex within the stream if present and passes it back as an Optional.

The last find selects any element within the stream that matches the predicate, any employee over 71, which in this case is none, so an empty Optional is returned.

Terminal Operations For Matching Top

There are three terminal operations for matching elements within a stream, allMatch() which returns whether all elements of this stream match the provided predicate, anyMatch() which returns whether any elements of this stream match the provided predicate and noneMatch() which returns whether no elements of this stream match the provided predicate.

Ok, lets do some matching! We will be using the Employee class we created in the Introducing Streams lesson to test against for this purpose.

Following is a TestMatchInStream class to demonstrate matching elements within a stream using the allMatch(), anyMatch() and noneMatch() methods of the Stream<E> interface.


package info.java8;

/* Match elements within a stream */
public class TestMatchInStream {

    public static void main(String[] args) {

        // Match any element
        System.out.println("Are there any employees over 70? " +
                Employee.listOfStaff().stream()
                        .anyMatch(e -> e.getAge() > 70));
        
        // Match no elements
        System.out.println("Are there no employees over 70? " +
                Employee.listOfStaff().stream()
                        .noneMatch(e -> e.getAge() > 70));
        
        // Match all elements
        System.out.println("Are all employees over 26? " +
                Employee.listOfStaff().stream()
                        .allMatch(e -> e.getAge() > 26));
        
        // Match all elements
        System.out.println("Are all employees over 16? " +
                Employee.listOfStaff().stream()
                        .allMatch(e -> e.getAge() > 16));
    }
}

Building and running the TestMatchInStream class produces the following output:

Run TestMatchInStream class
Screenshot 2. Running the TestMatchInStream class.

The first match selects any element within the stream that match the predicate of age 70+, in this case no employee is over 70 and so false is returned.

The second match selects no element within the stream that match the predicate of age 70+, in this case no employee is over 70 and so true is returned.

The third match selects all element within the stream that match the predicate of age 26+, in this case not all employees are over 26 and so false is returned.

The last match selects all element within the stream that match the predicatee of age 16+, in this case all employees are over 16 and so false is returned.

Related Quiz

Streams Quiz 7 - Finding & Matching

Lesson 7 Complete

In this lesson we looked at the finding and matching terminal operators.

What's Next?

In the next lesson we look at stream collectors.