Disclosure: This article may contain affiliate links. When you purchase, we may earn a commission.

Java 8 Predicate and Lambda Expression Example

Hello guys, if you want to learn about Predicates in Java 8 and looking for examples then you have come to the right place. In the past, I have explained key Java 8 concepts and classes like Stream, Optional, Collectors etc and we have seen how to use those functional methods like map, filter, and flatmap and in this article, I will show you how to use Predicates in Java 8 with Lambda expression. If you don't know Predicate is a functional interface in Java. A functional interface is nothing but a function with one abstract method or annotated by @FunctionalInterface annotation. Predicate is a functional interface with a function which accepts an object and return Boolean. 

Here is how Predicate interface looks like:

@FunctionalInterface
Predicate<T> { 
  boolean test(T t); 
}

It's a pre-defined functional interface from java.util.function package and its very useful, you can use Predicate for testing conditions, unit testing and simple conditional code. In other words, you pass a object and then you test something about that object and return true or false. This will be more clear when you will see examples so let's jump into it.

Java 8 Predicate and Lambda Expression Example






10 Examples of Predicate Interface in Java 8

Here are examples of how to use Predicate in Java 8. Since Predicate is a functional interface, any method which is accepting Predicate, you can also pass a Lambda expression to them. 
package test;

import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.function.Predicate;
import java.util.stream.Collectors;


public class Test {

    public static void main(String args[]){

        List names = Arrays.asList("John", "Jacky", "Jason", "Barry", "Frank");
        System.out.print("\nDisplay All names : "); 
        process(names, c -> true);   
        
        System.out.print("\nDisplay No names : ");  
        process(names, c -> false);
        
        System.out.print("\nDisplay names which startswith 'J' : ");
        process(names, c -> c.startsWith("J"));
        
        System.out.print("\nDisplay names which ends with 'n' : ");  
        process(names, c -> c.endsWith("n"));
        
        System.out.print("\nDisplay names which are longer than 4 character : "); 
        process(names, c -> c.length() > 4);
    
        // Another way to apply Predicate on each element of collection
        // Stream's filter() method also accepts a Prediicate object
        // You can use filter() to creat another Collection or List with
        // elements, which satisfy Predicate conditions

        List hasR = names.stream()
                         .filter(c-&gt; c.contains("r"))
                         .collect(Collectors.toList());
        System.out.print("\nList with words contains 'r' : " + hasR);
    
        List startsWithB = names.stream()
                                .filter(c -&gt; c.startsWith("B"))
                                .collect(Collectors.toList());
        System.out.print("\nList with words starts with 'B' : " + startsWithB);
    
        // We can even combine Predicate using and(), or() And xor() logical functions
        // for example to find names, which starts with J and four letters long, you
        // can pass combination of two Predicate

        Predicate startsWithJ = (n) -> n.startsWith("J");
        Predicate fourLetterLong = (n) -> n.length() == 4;

        names.stream()
                .filter(startsWithJ.and(fourLetterLong))
                .forEach((n) -&gt; System.out.print("\nName, 
                 which starts with 'J' and four letter long is : " + n));
    
        // You can even negate a Predicate before passing to method
        names.stream()
             .filter(startsWithJ.negate())
             .forEach(n -&gt; System.out.print("\nNames which doesn't starts with 'J' : "
                           + n));
    
        // Combining two Predicates using OR condition in Java 8
        names.stream()
                .filter(startsWithJ.or(fourLetterLong.negate()))
                .forEach(n -&gt; System.out.print("\nNames which either
                  starts with 'J' or their length !=4 : " + n));
    }

    public static void process(Collection names, Predicate condition){
        for(String name : names){
            if(condition.test(name)){
                System.out.printf("%s, ", name);
            }
        }
    }

}

Output:

Display All names: John, Jacky, Jason, Barry, Frank,
Display No names :
Display names which start with 'J': John, Jacky, Jason,
Display names which end with 'n': John, Jason,
Display names which are longer than 4 characters: Jacky, Jason, Barry, Frank,
List with words contains 'r' : [Barry, Frank]
List with words starts with 'B' : [Barry]
Name, which starts with 'J' and four-letter long is: John
Names which doesn't start with 'J': Barry
Names which doesn't start with 'J': Frank
Names which either starts with 'J' or their length !=4: John
Names which either starts with 'J' or their length !=4: Jacky
Names which either starts with 'J' or their length !=4: Jason
Names which either starts with 'J' or their length !=4: Barry
Names which either starts with 'J' or their length !=4: Frank

If you look at those examples then you will realize that we are using Predicate at many places. For example in the first code, we have a method process which accept a Collection class and a Predicate.

       List names = Arrays.asList("John", "Jacky", "Jason", "Barry", "Frank");
        System.out.print("\nDisplay All names : "); 
        process(names, c -> true);   

Here when I a calling this method, I am just passing a Lambda expression which always return true. This is nothing but the code for your test() method which is defined in Predicate interface. Since we always return true that's why it print all the names as shown in the first line of output:

Display All names: John, Jacky, Jason, Barry, Frank,

Now, in the second example, I passed a lambda  which always return false and that's why no display name is printed.  In the third example, we passed another predicate which uses startswith() method. 

That's all about how to use the Predicate class on Java 8 in Lambda expression. In this article, you have learned that Predicate is nothing but a functional interface with only one method called boolean test(Object obj) which takes and object and returns a Boolean value.  You can pass lambda expression where a Predicate is expected because its a functional interface and its heavily used for filtering elements from Collections like List, Set, Queue, and Map. 


Other Java 8 tutorials you may like
If you are interested in learning more about new features of Java 8, here are my earlier articles covering some of the important concepts of Java 8:
  • How to sort the may by values in Java 8? (example)
  • Difference between map() and flatMap in Java 8 (answer)
  • How to use Stream class in Java 8 (tutorial)
  • 10 Courses to learn Java in-depth (courses)
  • How to format/parse the date with LocalDateTime in Java 8? (tutorial)
  • 5 Books to Learn Java 8 from Scratch (books)
  • Difference between abstract class and interface in Java 8? (answer)
  • 20 Examples of Date and Time in Java 8 (tutorial)
  • What is the default method in Java 8? (example)
  • How to join String in Java 8 (example)
  • How to sort the map by keys in Java 8? (example)
  • 15 Java Stream and Functional Programming interview questions (list)
  • How to convert List to Map in Java 8 (solution)
  • 10 examples of Optionals in Java 8? (example)

Thanks for reading this article so far. If you like this article then please share it with your friends and colleagues. If you have any questions or feedback then please drop a note.

No comments:

Post a Comment

Feel free to comment, ask questions if you have any doubt.