Java Predicate – Java 8 Predicate

Filed Under: Java

In this article, we’ll talk about Java Predicate, which is a Functional Interface. A Functional Interface is one that contains exactly one abstract method.

Java Predicate

java predicate, java 8 predicate
Remember predicate from Math class in school? Yeah, something like a function that takes in a value and returns true or false.

In Java 8, java.util.function.Predicate was introduced that behaves the same way and can be used as an assignment target in lambda expressions and functional interfaces. The functional method of Predicate is test(Object).

java predicate functional interface

Java Predicate Example

Let’s consider that we have a class Apple:


package com.journaldev.predicates;

public class Apple {
	private String color;
	private Double weight;

	public Apple(String c, Double w) {
		this.color = c;
		this.weight = w;
	}

	@Override
	public String toString() {
		return "Apple{color:" + this.getColor() + ",weight:" + this.getWeight() + "}";
	}

	public String getColor() {
		return color;
	}

	public void setColor(String color) {
		this.color = color;
	}

	public Double getWeight() {
		return weight;
	}

	public void setWeight(Double weight) {
		this.weight = weight;
	}
}

Now if we have a condition to get the apples whose weight is above 150 grams, we can write a Predicate for it as below:


package com.journaldev.predicates;

import java.util.function.Predicate;

public class ApplePredicates {

	public static Predicate<Apple> isWeightAbove150() {
		return apple -> apple.getWeight() >= 150;
	}
}

Now, we can use this predicate in filter(), to filter a list of apples by the condition in this predicate.

Let’s add a method filterApples() to the ApplePredicates class:


public static List<Apple> filterApples(List<Apple> apples, Predicate<Apple> predicate) {
	return apples.stream().filter(predicate).collect(Collectors.toList());
}

We can call this and get the results as below in a main method:


public static void main(String[] args) {
	List<Apple> apples = Arrays.asList(new Apple("green", 120.0), new Apple("red", 110.0),
			new Apple("brown", 150.0), new Apple("green", 160.0), new Apple("red", 122.0));
	ApplePredicates.filterApples(apples, ApplePredicates.isWeightAbove150()).forEach(System.out::println);
}

Output:


Apple{color:brown,weight:150.0}
Apple{color:green,weight:160.0}

With java 8 lambda expressions, we can do it simply as below:


ApplePredicates.filterApples(apples, apple -> {
	return apple.getWeight() >= 150;
}).forEach(System.out::println);

Or, if we don’t want to define our own method, we can also use the default filter method and write it as:


apples.stream().filter(apple -> {
	return apple.getWeight() >= 150;
}).collect(Collectors.toList()).forEach(System.out::println);

Java 8 Predicate Methods

Let’s now go through the methods available for Predicate:

  1. default Predicate and(Predicate other)

    Returns a composed predicate that represents a logical AND of two predicates. When evaluating the composed predicate, if this predicate is false, then the other predicate is not evaluated.

    To understand this, let’s add another predicate in the ApplePredicates class:

    
    public static Predicate<Apple> isColorGreen() {
        return apple -> apple.getColor().equals("green");
    }
    

    Now we can apply the and() function if we want to get a predicate for apple to be green and weight above or equal to 150 grams.

    
    Predicate<Apple> andPredicate = ApplePredicates.isColorGreen().and(ApplePredicates.isWeightAbove150());
    apples.stream().filter(andPredicate).forEach(System.out::println);
    

    This will give the following output:

    
    Apple{color:green,weight:160.0}
    

    Similarly, we have or() method to do the short-circuiting, logical ORing of two predicates.

  2. default Predicate negate()

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

    Let’s say we want the Predicate to get apples that are not green. We already have one predicate that checks for Apple to be green, so we can negate it.

    
    Predicate<Apple> negateExample = ApplePredicates.isColorGreen().negate();
    apples.stream().filter(negateExample).forEach(System.out::println);
    

    The output will be:

    
    Apple{color:red,weight:110.0}
    Apple{color:brown,weight:150.0}
    Apple{color:red,weight:122.0}
    
  3. boolean test(T t)

    Evaluates this predicate for the given argument. In our case, we can pass in an Apple object to check if this predicate returns true or false for that apple.

    
    Apple testApple = new Apple("green", 120.0);
    System.out.println(ApplePredicates.isColorGreen().test(testApple));
    System.out.println(ApplePredicates.isWeightAbove150().test(testApple));
    

    Output:

    
    true
    false
    
  4. static Predicate isEqual(Object targetRef)

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

    Consider we have overridden the equals() method for Apple class:

    
    @Override
    public boolean equals(Object obj) {
    	Apple apple = (Apple) obj;
    	if (this.getColor().equals(apple.getColor()) && this.getWeight().equals(apple.getWeight())) {
    		return true;
    	}
    	return false;
    }
    

    Now, let’s say we have an Apple, which has standard color and weight. Then we can get a Predicate, that will test if the given apple is standard or not.

    
    Predicate<Apple> standardApplePredicate = Predicate.isEqual(new Apple("red", 150.0));
    
    Apple testApple = new Apple("green", 120.0);
    System.out.println(standardApplePredicate.test(testApple));
    System.out.println(standardApplePredicate.test(new Apple("red", 150.0)));
    

    This will output:

    
    false
    true
    

That’s it for Java Predicate functional interface.

Reference: API Doc

Leave a Reply

Your email address will not be published. Required fields are marked *

close
Generic selectors
Exact matches only
Search in title
Search in content
Search in posts
Search in pages