What is Predicate in Java

Mohammad Irfan Oct 12, 2023
  1. What is Predicate in Java
  2. Predicate in Filter() Operation of Java Stream
What is Predicate in Java

This tutorial introduces the predicate interface with examples in Java.

The predicate is an interface in Java used as a target assignment for a lambda expression or method reference. It was added to Java 8 and provided a more functional approach to writing code in Java.

It is present in the java.util.function package. A predicate is most commonly used to filter a stream of objects. In this tutorial, we will discuss what a predicate is and how we can use it.

What is Predicate in Java

As discussed before, a predicate is a functional interface used as the assignment target for a lambda expression or method reference. The Syntax of Predicate interface looks as follows.

@FunctionalInterface public interface Predicate<T>

The T is the type of input to the predicate interface. Let’s take an example of what a predicate is. In the mathematical world, a predicate can take the following form:

x -> x > 90

The above statement represents that x implies that x is greater than 90.

Let’s see an example of how we can create a predicate object.

Predicate<Integer> noGreaterThan5 = x -> x > 5;

In the above code, we create a predicate named noGreaterThan5. This predicate takes Integer input; therefore, T is Integer here. This predicate will check whether the input arguments are greater than five or not.

Predicate in Filter() Operation of Java Stream

The filter() operation of the Java 8 stream API takes a predicate as its argument. In the code below, we will use the filter() operation to see the implementation of the predicate interface. Look at the code below:

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

public class SimpleTesting {
  public static void main(String args[]) {
    // predicate
    Predicate<String> nameGreaterThan4 = x -> x.length() > 4;
    // Create a list
    List<String> name = Arrays.asList("Ram", "Karan", "Aarya", "Rahul", "Om", "Pranav");
    // create a stream
    // apply filter operation
    // pass the predicate
    List<String> name_filtered =
        name.stream().filter(nameGreaterThan4).collect(Collectors.toList());
    // print the resulting list
    System.out.println(name_filtered);
  }
}

Output:

[Karan, Aarya, Rahul, Pranav]

We have written the above code to filter names whose length is greater than 4. We first create a predicate and a List to store the names.

We then create a stream of names using the List.toStream() method and apply the filter() operation. The filter operation takes the nameGreaterThan4 predicate as its argument.

The filter operation using this predicate allowed only the strings whose length was greater than 4. The strings that matched the predicate were finally collected by the collect operation and stored into a List.

Instead of creating predicate objects separately, we can directly pass the predicate into the filter function. Look at the code below:

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

public class SimpleTesting {
  public static void main(String args[]) {
    // Create a list
    List<String> name = Arrays.asList("Ram", "Karan", "Aarya", "Rahul", "Om", "Pranav");
    // create a stream
    // apply filter operation
    // pass the predicate
    List<String> name_filtered =
        name.stream().filter(x -> x.length() > 4).collect(Collectors.toList());
    // print the resulting list
    System.out.println(name_filtered);
  }
}

Output:

[Karan, Aarya, Rahul, Pranav]

Predicate.and() Method in Java

We can use the Predicate.and() method to apply two predicates to the filter operation. It returns a composite predicate that reflects a logical AND of this and short-circuiting another predicate.

If this predicate is false when evaluating the composite predicate, the other predicate is not evaluated. The method signature of this method is:

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

Other in the argument refers to the second predicate, which we may want to apply. Lets us now look at some examples to learn about this method. Look at the code below:

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

public class SimpleTesting {
  public static void main(String args[]) {
    // predicate
    Predicate<String> nameGreaterThan3 = x -> x.length() > 3;
    Predicate<String> nameLesserThan5 = x -> x.length() < 5;
    // Create a list
    List<String> name = Arrays.asList("Ram", "Karan", "Aarya", "Rahul", "Om", "Pranav", "Alok");
    // create a stream
    // apply filter operation
    // pass the predicate
    List<String> name_filtered =
        name.stream().filter(nameGreaterThan3.and(nameLesserThan5)).collect(Collectors.toList());
    // print the resulting list
    System.out.println(name_filtered);
  }
}

Output:

[Alok]

In the above code, the first predicate checks if the string length is greater than 3, and the second one checks if the string length is less than 5. When both these predicates are passed to the filter operation with the AND operation, this filters names whose length equals 4.

The above code can be written more concisely as follows:

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

public class SimpleTesting {
  public static void main(String args[]) {
    // create a list
    List<String> name = Arrays.asList("Ram", "Karan", "Aarya", "Rahul", "Om", "Pranav", "Alok");
    // create a stream
    // apply filter operation
    // pass the predicate
    List<String> name_filtered =
        name.stream().filter(x -> x.length() > 3 && x.length() < 5).collect(Collectors.toList());
    // print the resulting list
    System.out.println(name_filtered);
  }
}

Output:

[Alok]

Predicate.or() Method in Java

Like in the previous discussion, we applied the AND operation using the and() method. We can also apply the OR operation using the or() method.

It returns a composite predicate that reflects a logical OR of this and another predicate that is short-circuiting. If this predicate is true, the other predicate is not considered while assessing the composite predicate.

The method signature of this method is:

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

Other in the argument refers to the second predicate, which we may want to apply. Lets us now look at some examples to learn about this method. Look at the code below:

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

public class SimpleTesting {
  public static void main(String args[]) {
    // predicate
    Predicate<String> nameEqualTo3 = x -> x.length() == 3;
    Predicate<String> nameEqualTo2 = x -> x.length() == 2;
    // Create a list
    List<String> name = Arrays.asList("Ram", "Karan", "Aarya", "Rahul", "Om", "Pranav", "Alok");
    // create a stream
    // apply filter operation
    // pass the predicate
    List<String> name_filtered =
        name.stream().filter(nameEqualTo3.or(nameEqualTo2)).collect(Collectors.toList());
    // print the resulting list
    System.out.println(name_filtered);
  }
}

Output:

[Ram, Om]

In the above code, the first predicate checks if the string length is equal to 3, and the second predicate checks if the string length is equal to 5. When both these predicates are passed to the filter operation with the OR operation, this filters names whose length is equal to 3 or 2.

The above code can be written more concisely as follows:

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

public class SimpleTesting {
  public static void main(String args[]) {
    // Create a list
    List<String> je_name = Arrays.asList("Ram", "Karan", "Aarya", "Rahul", "Om", "Pranav", "Alok");
    // create a stream
    // apply filter operation
    // pass the predicate
    List<String> je_name_filtered = je_name.stream()
                                        .filter(x -> x.length() == 3 || x.length() == 2)
                                        .collect(Collectors.toList());
    // print the resulting list
    System.out.println(je_name_filtered);
  }
}

Output:

[Ram, Om]

Related Article - Java Interface