Java 8 - Predicate with Examples

The Predicate is a functional interface, which is used to improve manageability of code, helps in unit-testing them separately,

It is part of the java.util.function package which has been introduced since Java 8, to implement functional programming in Java.

Syntax: -

public interface Predicate<T>

The methods in Predicate interface: -

The Predicate interface consists of the following 6 methods as listed which are later discussed as follows:

  1. test()
  2. and()
  3. negate()
  4. or()
  5. isEqual()
  6. not()

1. test(T t) : Evaluates this predicate on the given argument.

Syntax: 

boolean test(T t);

Parameters: t - the input argument

Returns: true if the input argument matches the predicate, otherwise false

Example

// Java program to illustrate Simple Predicate 
  
import java.util.function.Predicate; 
public class PredicateInterfaceExample1 { 
    public static void main(String[] args) 
    { 
        // Creating predicate 
        Predicate<Integer> lesserthan = i -> (i < 18);  
  
        // Calling Predicate method 
        System.out.println(lesserthan.test(10));  
    } 

Output:

True

2. and(Predicate other) : Returns a composed predicate that represents a short-circuiting logical AND of this predicate and another.

default Predicate<T> and(Predicate<? super T> other)

Returns a composed predicate that represents a short-circuiting logical AND of this predicate and another.

Parameters:

other: a predicate that will be logically-ANDed with this predicate

Returns : a composed predicate that represents the short-circuiting logical AND of this predicate and the other predicate.

Throws: NullPointerException - if other is null.

Example

// Java program to illustrate AND Predicate 
  
import java.util.function.Predicate; 
import java.util.Objects; 
  
class PredicateInterfaceExample5 { 
    public static Predicate<String> hasLengthOf10 = new Predicate<String>() { 
        @Override
        public boolean test(String t) 
        { 
            return t.length() > 10; 
        } 
    }; 
  
    public static void predicate_and() 
    { 
        Predicate<String> nonNullPredicate = Objects::nonNull; 
  
        String nullString = null; 
  
        boolean outcome = nonNullPredicate.and(hasLengthOf10).test(nullString); 
        System.out.println(outcome); 
  
        String lengthGTThan10 = "Welcome to the machine"; 
        boolean outcome2 = nonNullPredicate.and(hasLengthOf10). 
        test(lengthGTThan10); 
        System.out.println(outcome2); 
    } 
    public static void main(String[] args) 
    { 
        predicate_and(); 
    } 
}
 
Output:
False
True

3. negate() : Returns a predicate that represents the logical negation of this predicate.

default Predicate<T> negate()

Returns: a predicate that represents the logical negation of this predicate

Example:

// Java program to illustrate negate Predicate 
  
import java.util.function.Predicate; 
class PredicateInterfaceExample6 { 
    public static Predicate<String> hasLengthOf10 = new Predicate<String>() { 
        @Override
        public boolean test(String t) 
        { 
            return t.length() > 10; 
        } 
    }; 
  
    public static void predicate_negate() 
    { 
  
        String lengthGTThan10 = "Thunderstruck is a 2012 children's "
                                + "film starring Kevin Durant"; 
  
        boolean outcome = hasLengthOf10.negate().test(lengthGTThan10); 
        System.out.println(outcome); 
    } 
    public static void main(String[] args) 
    { 
        predicate_negate(); 
    } 
}

Output:
False

4. or(Predicate other) : Returns a composed predicate that represents a short-circuiting logical OR of this predicate and another.

default Predicate<T> or(Predicate<? super T> other)

Parameters:

other : a predicate that will be logically-ORed with this predicate

Returns:

a composed predicate that represents the short-circuiting logical OR of this predicate and the other predicate.

Throws : NullPointerException - if other is null

Example

// Java program to illustrate OR Predicate 
  
import java.util.function.Predicate; 
class PredicateInterfaceExample4 { 
    public static Predicate<String> hasLengthOf10 = new Predicate<String>() { 
        @Override
        public boolean test(String t) 
        { 
            return t.length() > 10; 
        } 
    }; 
  
    public static void predicate_or() 
    { 
  
        Predicate<String> containsLetterA = p -> p.contains("A"); 
        String containsA = "And"; 
        boolean outcome = hasLengthOf10.or(containsLetterA).test(containsA); 
        System.out.println(outcome); 
    } 
    public static void main(String[] args) 
    { 
        predicate_or(); 
    } 
}

Output:
True

5. isEqual(Object targetRef) : 

Returns a predicate that tests if two arguments are equal according to Objects.equals(Object, Object).

Syntax: - 

static <T> Predicate<T> isEqual(Object targetRef)

Returns a predicate that tests if two arguments are equal according to Objects.equals(Object, Object).

T : the type of arguments to the predicate.

Parameters:

targetRef : the object reference with which to compare for equality, which may be null.

Returns: a predicate that tests if two arguments are equal according to Objects.equals(Object, Object).

Examples: -

Example 1: Predicate Chaining: -

// Java program to illustrate Predicate Chaining 
  
import java.util.function.Predicate; 
public class PredicateInterfaceExample2 { 
    public static void main(String[] args) 
    { 
        Predicate<Integer> greaterThanTen = (i) -> i > 10; 
  
        // Creating predicate 
        Predicate<Integer> lowerThanTwenty = (i) -> i < 20;  
        boolean result = greaterThanTen.and(lowerThanTwenty).test(15); 
        System.out.println(result); 
  
        // Calling Predicate method 
        boolean result2 = greaterThanTen.and(lowerThanTwenty).negate().test(15); 
        System.out.println(result2); 
    } 
}

Output:
True
False

Example 2: Predicate into Function

// Java program to illustrate passing Predicate into function 
  
import java.util.function.Predicate; 
class PredicateInterfaceExample3 { 
    static void pred(int number, Predicate<Integer> predicate) 
    { 
        if (predicate.test(number)) { 
            System.out.println("Number " + number); 
        } 
    } 
    public static void main(String[] args) 
    { 
        pred(10, (i) -> i > 7); 
    } 

Output:
Number 10

Example 3: Predicate in Collection

Java
// Java program to demonstrate working of predicates on collection. 
// The program finds all admins in an arrayList of users. 

import java.util.function.Predicate; 
import java.util.*; 
class User 

    String name, role; 
    User(String a, String b) { 
        name = a; 
        role = b; 
    } 
    String getRole() { return role; } 
    String getName() { return name; }     
    public String toString() { 
       return "User Name : " + name + ", Role :" + role; 
    } 
  
    public static void main(String args[]) 
    {       
        List<User> users = new ArrayList<User>(); 
        users.add(new User("John", "admin")); 
        users.add(new User("Peter", "member")); 
        List admins = process(users, (User u) -> u.getRole().equals("admin")); 
        System.out.println(admins); 
    } 
  
    public static List<User> process(List<User> users,  
                            Predicate<User> predicate) 
    { 
        List<User> result = new ArrayList<User>(); 
        for (User user: users)         
            if (predicate.test(user))             
                result.add(user); 
        return result; 
    } 
}
 
Output:
[User Name : John, Role :admin]

The same functionality can also be achieved by using Stream API and lambda functions offered since JDK 1.8 on top of the Collections API.


The Stream API allows "streaming" of collections for dynamic processing. Streams allow concurrent and parallel computation on data (using internal iterations), to support database-like operations such as grouping and filtering the data (similar to GROUP BY and WHERE clause in SQL). This allows the developers to focus on "what data is needed" instead of "how data is needed" since streaming hides the details of the implementation and provides the result. This is done by providing predicates as inputs to functions operating at runtime upon the streams of collections. In the following example, we illustrate how Stream API can be used along with predicates to filter the collections of data as achieved in Example above.

Java
// Java program to demonstrate working of predicates on collection.
// The program finds all admins in an arrayList of users. 
import java.util.function.Predicate; 
import java.util.*; 
import java.util.stream.Collectors; 
import java.util.stream.Stream; 
  
class User 

    String name, role; 
    User(String a, String b) { 
        name = a; 
        role = b; 
    } 
    String getRole() { return role; } 
    String getName() { return name; }  
    public String toString() { 
    return "User Name : " + name + ", 
    Role :" + role; 
    } 
  
    public static void main(String args[]) 
    {  
        List<User> users =  
            new ArrayList<User>(); 
        users.add(new User("John", "admin")); 
        users.add(new User("Peter", "member")); 
          
    // This line uses Predicates to filter out the list of users with the role "admin". 
    // List admins = process(users, (User u) ->  
    // u.getRole().equals("admin")); 
  
    // Replacing it with the following line using Stream API and lambda functions 
    // produces the same output 
      
    // the input to the filter() is a lambda  expression that returns a predicate: a boolean value for each user encountered
  // (true if admin, false otherwise) 
    List admins = users.stream() 
    .filter((user) -> user.getRole().equals("admin")) 
    .collect(Collectors.toList()); 
          
    System.out.println(admins); 
    } 
}

Output:
[User Name : John, Role :admin]