Java 8 Predicate with examples

This article provides an introduction to Predicate in Java.

Java 8 Predicate

Here are the concepts it covers :

  1. What is a Predicate in Java ?
  2. Understanding Predicate Interface in java.util.function package
  3. Example of using Predicate Interface
  4. Predicates in Java internal classes
  5. Predicate Default Methods
  6. Predicate chaining using AND(), OR() methods
  7. Predicate advantages

 

What is a Predicate in Java ?

A Predicate is a functional interface that checks whether a condition in true or false.

Here is a simple example of using Predicate.

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

Output :

true
false

 

Predicate Interface

Predicate interface is defined in java.util.function package :

public interface Predicate<T> {
    boolean test(T t);
}

Predicate interface contains abstract method test that takes a generic argument and returns a boolean. It tests whether the T argument satisfies a condition.

Note that a Predicate “test” returns a boolean value.
 

Example of using Predicate Interface

Here is an example of using Predicate to filter employee names starting with “J”.

package com.topjavatutorial;

import java.util.ArrayList;
import java.util.List;
import java.util.function.Predicate;

public class PredicateDemo2 {

  public static void main(String[] args) {
    List<String> employees = new ArrayList<String>();
    employees.add("John");
    employees.add("Bob");
    employees.add("Jane");
    print(employees,emp -> emp.startsWith("J"));
  }
  
  private static void print(List<String> employees, Predicate<String> empPredicate){
    for(String emp : employees){
      if(empPredicate.test(emp))
        System.out.println(emp);
    }
  }

}

Output :

John
Jane
 

Predicates in Java internal classes

Java 8 added Predicate into several existing and new interfaces.

Lets see examples of Stream filter() and ArrayList removeIf() methods that accept a Predicate as an argument.

Stream filter()

package com.topjavatutorial;

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

public class PredicateDemo {

  public static void main(String[] args) {
    
    Predicate<Integer> negative = n -> (n < 0) ;
    
    List<Integer> numbers = Arrays.asList(10,20,30,-10,-20,-30);
    long negativeCount= numbers.stream().filter(negative).count();
    System.out.println("Count of negative numbers in list numbers = " + negativeCount);
    
  }

}

Output :

Count of negative numbers in list numbers = 3

ArrayList removeIf()

ArrayList declares a removeIf() method that accepts a Predicate argument.

package com.topjavatutorial;

import java.util.ArrayList;
import java.util.List;

public class PredicateDemo3 {

  public static void main(String[] args) {
    List<Integer> numbers = new ArrayList<Integer>();
    numbers.add(10);
    numbers.add(15);
    numbers.add(20);
    numbers.add(25);
    
    System.out.println("Original List : " + numbers);
    numbers.removeIf(num -> num%2 == 0);
    System.out.println("Odd numbers : " + numbers);
  }

}

Output :

Original List : [10, 15, 20, 25]
Odd numbers : [15, 25]
 

Predicate Default Methods

Predicate interface also contains following default methods :

and()

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

e.g. predicate.and(nextPredicate)

or()

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

e.g. predicate.or(nextPredicate)

negate()

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

e.g. predicate.negate()

isEqual()

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

 

Predicate chaining using and(), or() methods

We can use and() and or() methods to chain predicates as shown in following examples :

package com.topjavatutorial;

import java.util.ArrayList;
import java.util.List;
import java.util.function.Predicate;

public class PredicateDemo3 {

  public static void main(String[] args) {
    List<Integer> numbers = new ArrayList<Integer>();
    numbers.add(10);
    numbers.add(18);
    numbers.add(21);
    numbers.add(24);
    
    mutipleof2And3(numbers);
  }
  
  private static void mutipleof2And3(List<Integer> numbers){
    Predicate<Integer> multipleOf2 = num -> num%2 == 0;
    Predicate<Integer> multipleOf3 = num -> num%3 == 0;
    System.out.println("Multiples of 2 and 3 in numbers list are : ");
    for(Integer num : numbers){
      if((multipleOf2.and(multipleOf3)).test(num))
        System.out.println(num);
    }
  }

}

Output :

Multiples of 2 and 3 in numbers list are :
18
24

Similarly, we can use the Predicate or() method :

  private static void mutipleof2Or3(List<Integer> numbers){
    Predicate<Integer> multipleOf2 = num -> num%2 == 0;
    Predicate<Integer> multipleOf3 = num -> num%3 == 0;
    System.out.println("Multiples of 2 or 3 in numbers list are : ");
    for(Integer num : numbers){
      if((multipleOf2.or(multipleOf3)).test(num))
        System.out.println(num);
    }
  }

Output :

Multiples of 2 or 3 in numbers list are :
10
18
21
24
 

Predicate advantages

Predicates can help avoid duplicate lambda expression as shown in below code :

package com.topjavatutorial;

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

public class PredicateDemo {

  public static void main(String[] args) {
    
    Predicate<Integer> negative = n -> (n < 0) ;
    
    List<Integer> numbers = Arrays.asList(10,20,30,-10,-20,-30);
    long negativeCount= numbers.stream().filter(negative).count();
    System.out.println("Count of negative numbers in list numbers = " + negativeCount);
    
    List<Integer> moreNumbers = Arrays.asList(-100,-200,-50,0,30,-10,-20,-30);
    long negativeCount2 = moreNumbers.stream().filter(negative).count();
    System.out.println("Count of negative numbers in list moreNumbers = " + negativeCount2);
  }

}

Output :

Count of negative numbers in list numbers = 3
Count of negative numbers in list moreNumbers = 6

Here, we avoided duplicating the lambda expression code to filter negative numbers by adding it as a Predicate variable “negative”. Then we reused the Predicate variable to get negative numbers from two different lists.

 

© 2016 – 2018, https:. All rights reserved. On republishing this post, you must provide link to original post

Leave a Reply.. code can be added in <code> </code> tags