Pages

Java 8 provides excellent features to support filtering of elements in Java Collections. Prior to Java 8, only better way to filter elements is by using foreach loop or iterating over Collection using Iterator and selecting required object, leaving out rest. Though that approach work, it was very difficult to run them in parallel and take advantage of multiple CPU available in modern day servers. Java 8 provides Streams, which not only makes it easy to run any operation parallel but also support lazy loading and lazy evaluation, which means as soon as filtering condition is satisfied, it stooped doing work, doesn't matter how many object collection contains. You can filter Java Collections like List, Set or Map in Java 8 by using filter() method of Stream class. You first need to obtain stream from Collection by calling stream() method and than you can use filter() method, which takes a Predicate as only argument. Predicate is a functional interface with couple of boolean valued method e.g. test(), which returns boolean true or false. Java 8 uses this method to filter Collection. Just remember that filter doesn't remove elements which matches the condition given in predicate, instead it selects them in output stream. I agree, little bit counter intuitive, select would have been better name for this method, but once you used it couple of times, you will be Ok. For example, if you have list of String and you want another list which contains only long string say whose length is greater than 20 character, you can use filter method to do that and you don't need a loop. Java 8 Stream is very efficient replacement of looping both design and performance wise, because it separates What to do from how to do, just like SQL. Leaving the implementation part to platform.

Java 8 Filter Method

As I said filter() method is defined in Stream class, it takes a Predicate object and returns a stream consisting of the elements from original stream which matches the given Predicate. It is an intermediate operation, which means you can call any other method of Stream e.g. count() as stream will not be closed due to filtering. Predicate is applied to each element of Collection to check whether a particular element should be included in filtered stream or not. Predicate should be stateless and non interfering so that if needed filter operation can run in parallel using parallel stream. In Java8, Predicate is a functional interface with couple of boolean valued method used to test input against the condition. In our case test(T t) method is used, which evaluate this predicate in given argument. Since filter() method accept a functional interface, you can also pass lambda expression to it, which is what we will do. You can pass any condition to filter elements e.g. either by using relational operator e.g. less than, greater than or equal to or by using methods like equals() and equalsIgnoreCase() as shown in our sample program.

Java 8 Example of Filtering List using Stream

This is our sample program to demonstrate power of Java 8 Stream and Filter method. By using these Java 8 enhancements you can perform SQL like operation in Java e.g.

In this example, we are passing a lambda expression to filter method, which returns a boolean. It's actually anonymous function test(), we have omitted type information for deal variable because it will be inferred by JVM easily, making our code concise. In short, you can pass a lambda expression to filter method until result is boolean. The forEach() method is a terminal operation and used here to print all deals present in filtered collection.

Now let's see second example of filtering List in Java. Now we need all deals which are expiring in March. In SQL we can write query like this :

That's all about how to filter collection in Java 8. This is just an example of super power of new stream API. You can write more expressive code, which is easy to understand, easy to optimize and super easy to run in parallel without you worrying about multi-threading nightmare. Together with lambda expression, method references and new Stream API, Java has become super expressive language without added boiler plate.

Thanks for reading this article so far. If you like this article then please share with your friends and colleagues. If you have any question, doubt, or feedback then please drop a comment and I'll try to answer your question.

P.S. : If you want to learn more about new features in Java 8 then please see the tutorial What's New in Java 8. It explains about all important features of Java 8 e.g. lambda expressions, streams, functional inteface, Optionals, new date and time API and other miscelleneous changes.