Java 8 - Stream.filter() method Example

In the last couple of Java 8 tutorials, you have learned how to use map(), flatMap(), and other stream examples to get an understanding of how Java 8 makes it easy to perform the bulk data operation on Collection classes. In this example, I am going to share how to use the filter() method in Java 8, another key method of Stream class. The filter() method as it name suggests is used to perform filtering e.g. if you have a stream of numbers you can create another stream of even numbers by using the filter() method. Though, filter() method is little bit of counter intuitive i.e. in order to create a stream of even number you call filter( i -> i%2 == 0) which means you do filter(isEven()) but, you are actually filtering odd numbers to create a new stream of even numbers, but that's how it works. The key benefit of using filter() method is lazy evaluation i.e. no data comparison is performed unless you call a terminal operation on stream e.g. findFirst() or forEach(). The filter() method just set up some pointers when you first call them on stream and only performs real filtering when you call the terminal method.

How filter method works in Java 8

In order to learn how to use the filter() method in Java 8, it's important that you also know how it works, at least at a high level. Let's see an example of filter() method to understand the lazy evaluation it does.

Suppose we have a list of integer numbers and we want to find the first number which is divisible by both 2 and 3, let' see how to solve this problem in Java 8.

List<Integer> listOfNumbers = Arrays.asList(1, 2, 3, 4, 5, 6, 12, 18);
Integer lcm =
                           .filter(i -> i % 2 == 0)
                           .filter(i -> i % 3 == 0)

This code is returning the first the first number which is divisible by both 2 and 3. Now, let's see how this code will execute. When you call the filter() method nothing happens until you call the findFirst(). At this time, Java knows that it just need to find the first element which satisfies the criterion imposed by the two chained filter() methods.

The findFirst() ask the filter() method prior to it in the chain of any number, the filter doesn't have any record so it asks the first filter() method, which in turn then scan the list and return a number which is divisible by 2. At this time, second filter method checks if this number is divisible by 3, if yes then it return that number to findFirst() otherwise it ask another number from first filter() method.

This process continues until a number is found which satisfy both filter() methods. Once that number is found it presented to findFirst() method. The job of findFirst() is to return that number. This is an example of lazy evaluation because nothing happens until the call to findFirst() is a method, this also present an opportunity to stop as soon as you find the first number which satisfies your criterion.

There is no need to process the entire list again and again, as it happens in the case of iterative eager evaluation. You can also see Java SE 8 for Really Impatient to learn more about other new enhancements made in Java 8.

Java 8 filter method example

Java 8 filter Example

Here are a couple of more examples of Stream.filter() method in Java 8. I have created a list of String containing Android versions e.g. LolliPop, KitKat etc. The first example just uses one filter() method to print Strings whose length is greater than 10. The second example prints String which contains the letter "e" e.g. Gingerbread. The Third examples combine these two filter methods to create a chain of filter methods to print String whose length is greater than 5 and starts with a letter "G".

By the way, for testing purpose, you can also create a stream of integers number by using Stream.of() static factory methods as shown in the following example:

How to use filter method in Java 8 with example

You can see that input stream contains numbers from 1 to 5 but output stream just contains odd numbers.

How to use filter() method in Java 8
package test;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

 * Java 8 filter example. You can use filter() method to perform lazy filtering
 * in Java.
public class Java8FilterExample {

    public static void main(String[] args) {

        List<String> versions = new ArrayList<>();
        versions.add("Jelly Bean");
        versions.add("Ice Cream Sandwidth");

        // Using one filter() 
        // print all versions whose length is greater than 10 character
        System.out.println("All versions whose length greater than 10");
                .filter(s -> s.length() > 10)

        System.out.println("first element which has letter 'e' ");
        String first =
                .filter(s -> s.contains("e"))

        // Using multiple filter
        System.out.println("Element whose length is > 5 and startswith G");
                .filter(s -> s.length() > 8)
                .filter(s -> s.startsWith("G"))

        // another example of filter() method in Java 8
        List<Integer> listOfNumbers = Arrays.asList(1, 2, 3, 4, 5, 6, 12, 18);
        Integer lcm =
                .filter(i -> i % 2 == 0)
                .filter(i -> i % 3 == 0)
        System.out.println("first number divisible by 2 and 3 in the list is : " + lcm);



All versions whose length greater than 10
Ice Cream Sandwidth
first element which has letter 'e' 
Jelly Bean
Element whose length is > 5 and starts with G
a first number divisible by 2 and 3 in the list is : 6

That's all in this Java 8 filter() example. It's one of the most useful methods of Stream class and you will find yourself using this method time and again. The best part of this method is that it improves performance by doing lazy evaluation. The filter() method just setup couple of pointers and no data comparison is performed untile a terminal method e.g. forEach() or findFirst() is called. You can see the Java documentation of filter() method to learn more about it, you can also read Java 8 in Action by Manning publication to learn more about streams in Java 8.

Further Learning
The Ultimate Java 8 Tutorial
Java SE 8 New Features
From Collections to Streams in Java 8 Using Lambda Expressions

Related Java 8 tutorials you may like
  • 20 Example of Date and Time API in Java 8 (click here)
  • 10 Examples of Lambda Expression in Java 8 (click here)
  • 5 Books to Learn Java 8 Better? (read here)
  • 10 Examples of converting a List to Map in Java 8 (see here)
  • Difference between and Stream.flatMap() in Java 8? (answer)
  • Java 8 Comparator Example (check here)
  • Collection of best Java 8 tutorials (click here)

No comments:

Post a Comment