The functional interface Predicate was defined in Java 8. Predicate receives an argument and based on a specific condition it returns a Boolean value. It makes the code more readable, manageable and clean. It’s located in the java.util.function package.

Predicate benefits mainly unit-testing; it has several built-in methods that lead to better tests results.

Let’s look at the following example:

public static void main(String[] args) {

    Predicate<Integer> predicate = n -> (n < 20);
    System.out.println(predicate.test(10));
    
}

Here, we send to the Predicate an integer value of 10. Then, we provide the logic that the argument number which is represented by n should be less than 20 for the predicate to be true, otherwise it returns false. In the above example, the predicate is obviously true and the output is as follows:

true

A few more examples:

public static void main(String[] args) {

    Predicate<Integer> predicate1 = n -> (n > 20);
    System.out.println(predicate1.test(10));

    Predicate<Integer> predicate2 = n -> (n == 10);
    System.out.println(predicate2.test(5));

    Predicate<Integer> predicate3 = n -> (n < 10);
    System.out.println(predicate3.test(2));

}

With outputs:

 false
 false
 true

In the above examples, we are using the Predicate through the method test(). In addition to that, Predicate has four more methods: isEqual() , and() , or() , negate() :

  • test(): returns true if the argument matches the condition, otherwise false.
  • isEqual: returns true if two arguments are equal according to object’s equals() method, otherwise false.
  • and(): it is used when there are multiple logical conditions that are checked by the Predicate, it returns true only if all conditions are true, otherwise false
  • or(): it is used when there are multiple logical conditions that are checked by the Predicate, it returns true if one of the conditions is true. If all the conditions are false then it returns false.
  • negate(): it is the opposite of the test() method. It returns false if the argument matches the condition and returns true if the argument doesn’t match the condition

We saw an example for test(), let’s show a few examples for the other methods:

  • isEqual():
public static void main(String[] args) {

    Predicate<String> predic = Predicate.isEqual("Hello World");

    System.out.println(predic.test("Hello World"));
    System.out.println(predic.test("Hello"));


}

Output:

true
false
  • and():
public static void main(String[] args) {

    Predicate<Integer> predicate1 = n -> (n > 20);


    Predicate<Integer> predicate2 = n -> (n == 25);

    Predicate<Integer> andPredicate = predicate1.and(predicate2);
    System.out.println(andPredicate.test(30));
    System.out.println(andPredicate.test(25));

}

Output:

 false
 true
  • or():
public static void main(String[] args) {

    Predicate<Integer> predicate1 = n -> (n > 20);


    Predicate<Integer> predicate2 = n -> (n == 25);

    Predicate<Integer> andPredicate = predicate1.or(predicate2);
    System.out.println(andPredicate.test(30));
    System.out.println(andPredicate.test(25));
    System.out.println(andPredicate.test(15));

}

Output:

true
true
false
  • negate():
public static void main(String[] args) {

    Predicate<Integer> predicate1 = i -> i > 15;

    Predicate<Integer> negate = predicate1.negate();

    System.out.println(negate.test(30));
    System.out.println(negate.test(10));

}

Output:

false
true

One of the main uses of Predicate is to apply a Filter to a collection containing objects.
What does Filter in Java Stream do?

Filter is an interface used to filter out some of the collection’s objects based on a predefined condition. Let’s see an example of Filter:

public static void main(String[] args) {

    List<Integer> ages = Arrays.asList(23, 16, 26, 31, 44, 12, 8, 20, 41, 33, 17);

    List<Integer> collect = ages.stream().filter(x -> x > 18).collect(Collectors.toList());

    System.out.println("The ages above 18 : " + collect);

}

Above we have a list with different ages and we want to pick only the ages above 18.

The output:

The ages above 18 : [23, 26, 31, 44, 20, 41, 33]

Now let’s see how Filter works in combination with Predicate:

public static void main(String[] args) {

    Predicate<Integer> above18 = x -> x > 18;

    List<Integer> ages = Arrays.asList(23, 16, 26, 31, 44, 12, 8, 20, 41, 33, 17);

    List<Integer> collect = ages.stream().filter(above18).collect(Collectors.toList());

    System.out.println("The ages above 18 : " + collect);

}

In this example, we give to the filter() method an argument of Predicate type. The output is as following:

The ages above 18 : [23, 26, 31, 44, 20, 41, 33]

In this article we saw what is Predicate, its benefits and its usages. Then we saw how to use it in combination with other stream interfaces to produce an easier and cleaner Java code.

Leave a Reply