Java 8 Predicate with examples
This article provides an introduction to Predicate in Java.
Here are the concepts it covers :
- What is a Predicate in Java ?
- Understanding Predicate Interface in java.util.function package
- Example of using Predicate Interface
- Predicates in Java internal classes
- Predicate Default Methods
- Predicate chaining using AND(), OR() methods
- 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