Sitemap

Java Predicates

5 min readDec 29, 2025

--

Press enter or click to view image in full size

A Java Predicate is a functional interface that represents a boolean-valued function introduced in Java 8.

It represents a single argument function that returns a boolean value.

It has exactly one abstract method(SAM — Single Abstract Method) called test(T t).

It is a Lambda ready as it is a Functional Interface provided by Java

Below are the available methods and as shown below table test(T t) is the abstract method of the Interface. It uses a generic type <T>, allowing it to check conditions on any object type (Strings, Integers, Custom Objects, etc.).

@FunctionalInterface
public interface Predicate<T> {

boolean test(T t);

default Predicate<T> and(Predicate<? super T> other) {
Objects.requireNonNull(other);
return (t) -> test(t) && other.test(t);
}

default Predicate<T> negate() {
return (t) -> !test(t);
}

default Predicate<T> or(Predicate<? super T> other) {
Objects.requireNonNull(other);
return (t) -> test(t) || other.test(t);

static <T> Predicate<T> isEqual(Object targetRef) {
return (null == targetRef)
? Objects::isNull
: object -> targetRef.equals(object);
}
}

It is first introduced in Java 8 and Predicate interface includes the primary abstract method and several "default" and "static" methods that allow you to compose multiple predicates together (like logical AND, OR, and NOT).

Press enter or click to view image in full size
Method Summary — Refer Oracle docs for updated information

We can use Predicate<T> to implement some conditional checks. However, from it’s method signature boolean test(T t) it is clear that it takes an input parameter and returns a Boolean result. When you have this type of requirement to write a method, use it confidently.

Lets look at some examples , real world examples

You are building a filtering utility for an inventory management system. You need to create a generic method that can filter any type of object based on dynamic conditions

We have a Products listed with different category , name, Price like

name=’Laptop’, category=’Electronics’, price=1200
name=’Chair’, category=’Furniture’, price=200
name=’Desk’, category=’Furniture’, price=300
name=’Mouse’, category=’Electronics’, price=50

  1. Lets first create a Model/Domain Class
  2. In the Main class lets define some products as shown above as a List of products.
  3. Lets see the Predicate Implementation and how to use the methods.
  4. Lets write a generic method to filter the values and how the test() method works.

Lets create a Domain class/Model class with implementing equals and hashcode methods to support Equality checks. We override them to define Logical Equality

If you don’t override them, the default behavior from Object is:
•equals(): Checks Reference Equality. It only returns true if both variables point to the exact same location in memory (the same instance).
•hashCode(): Returns a number derived from the object’s memory address.

  • Without overriding: Two different Products objects with the exact same data (name=”A”, type=”B”, price=10) would be considered not equal because they are different instances in memory.
    •With overriding: You tell Java, “If the name, type, and price are the same, treat these objects as equal.”

STEP 1 : Model Class

import java.util.Objects;

public class Product {


private String name;
private String type;
private int price;
public Products(){
}

public Products(String name, String type, int price) {
this.name = name;
this.type = type;
this.price = price;
}

public String getType() {
return type;
}

@Override
public boolean equals(Object o) {
if (!(o instanceof Products)) return false;
Products products = (Products) o;
return price == products.price && Objects.equals(name, products.name) && Objects.equals(type, products.type);
}

@Override
public int hashCode() {
return Objects.hash(name, type, price);
}

@Override
public String toString() {
return "Products{" +
"name='" + name + '\'' +
", type='" + type + '\'' +
", price=" + price +
'}';
}

public void setType(String type) {
this.type = type;
}

public int getPrice() {
return price;
}

public void setPrice(int price) {
this.price = price;
}



public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

}

Please have a notice how we overwritten the equals , hashcode and toString methods.

Now lets do some Predicate Implementation,

In your main method, define the following Predicate<T> instances T => product so Predicate<product>
◦ isElectronics: Returns true if the category is “Electronics”.
◦ isExpensive: Returns true if the price is greater than $100.00.

Get Vamsi balaga’s stories in your inbox

Join Medium for free to get updates from this writer.

◦ and(): Filter for products that are both Electronics AND Expensive.
◦ or(): Filter for products that are either Electronics OR Expensive.
◦ negate(): Filter for products that are not Expensive (Cheap).
◦ isEqual(): Create a specific “target” product object (e.g., a specific Mouse). Use Predicate.isEqual(target) to find this exact item in the list.
◦ not(): Use the static method Predicate.not() to filter for products that are not Electronic.

STEP 2 : Main method

public class PredictionPractice {
public static void main(String[] args) {


List<Products> products = Arrays.asList(
new Products("Laptop","Electronics",1200),
new Products("Chair","Furniture",200),
new Products("Desk","Furniture",300),
new Products("Mouse","Electronics",50)
);
//Predicate of Electronics

//Predicate >100

//negate

//AND

//OR
}
}


STEP 3 : Predicate Methods

//Predicate of Electronics
Predicate<Products> isElectronics = product -> "Electronics".equals(product.getType());
System.out.println("IsElectronics>>>"+isElectronics);
filterEntities(products,isElectronics);

//Predicate >100
Predicate<Products> isExpensive = product -> product.getPrice() > 100;
System.out.println("isExpensive>>>"+isExpensive);
filterEntities(products,isExpensive);

//negate
Predicate<Products> isNotExpensive = isExpensive.negate();
System.out.println("isNotExpensive>>>"+isNotExpensive);
filterEntities(products,isNotExpensive);
//AND
Predicate<Products> isExpensiveandOver100 = isElectronics.and(isExpensive);
System.out.println("isExpensiveandOver100>>>"+isExpensiveandOver100);
filterEntities(products,isExpensiveandOver100);
//OR
Predicate<Products> isExpensiveOrOver100 = isElectronics.or(isExpensive);
System.out.println("isExpensiveOrOver100>>>"+isExpensiveOrOver100);
filterEntities(products,isExpensiveOrOver100);

STEP 4 : Generic method implementation

As a generic Implementation lets write a filter method which has

◦ List<T> of items.
◦ Predicate<T> condition.
◦ Inside this method, use the test() method to filter the list and return a new list of matching items.

public static <T> List<T> filterEntities(List<T> listItems, Predicate<T> condition){
List<T> result = new ArrayList<>();
for (T item : listItems) {
if (condition.test(item)) {
result.add(item);
}
}
// look at the product model as we overide the toString() method so that product of toString
// gives us the details rather hashcode
result.stream().forEach(product-> System.out.println(product.toString()));
System.out.println("*****************************************************");
return result;
}
Press enter or click to view image in full size
console output

Lets see how we can enhance this using streams instead of predicate<T> test(T ,t) method. It also gives the same output as above

List<T> resultStreamlst;
resultStreamlst = listItems.stream()
.filter(condition)
.collect(Collectors.toList());
System.out.println("Filtered Entries of the Predicate"+resultStreamlst);
System.out.println("*****************************************************");

Thank you for taking the time to read our blog post!If you found the information helpful or interesting, don’t forget to show your appreciation by giving it a round of applause 👏

Bonus explore

Practice Example Scenario : E-Commerce Order Validator

Goal: Filter orders to identify which ones need manual review or special handling.

1.Domain Class: Create an Order class with:

◦orderId (String)

◦status (String) — e.g., “NEW”, “SHIPPED”, “DELIVERED”, “CANCELLED”

◦totalAmount (double)

◦isPrimeUser (boolean)

2.Generic Method: Create a method validateOrders that takes a List<T> and a Predicate<T> and returns a filtered list.

3.Predicates:

◦isHighValue: Returns true if totalAmount > 500.

◦isCancelled: Returns true if status is “CANCELLED”.

◦isShipped: Returns true if status is “SHIPPED”.

4.Demonstration:

◦Fraud Check: Find orders that are isHighValue AND isCancelled (suspicious).

◦Priority Handling: Find orders that are isHighValue AND belong to a Prime user (isPrimeUser is true).

◦Pending Actions: Use Predicate.not() to find orders that are NOT isShipped.

Happy reading and exploring! 🚀✨ Thank you !!

--

--