Table of contents
Predicate Interface is a functional interface introduced in Java 8 . It is a part of java.util.function package . It is having one abstract method ( test ) , one static method ( isEqual ) and three default methods ( and , or , negate ) . We will explore all this methods in detail below :
Methods in predicate interface
test method
test is a abstract method in predicate interface which accepts a argument , test a condition and returns true or false ( boolean ) .
Syntax : boolean test(T t)
We will try to replicate Predicate Interface from java source code in our below example :
interface Predicate<T> { boolean test(T t); } class PredicateImpl implements Predicate < Integer > { @Override public boolean test(Integer number) { return number % 2 == 0; } } public class PredicateInterfaceDemo { public static void main(String[] args) { Predicate<Integer> predicate = new PredicateImpl(); System.out.println(predicate.test(10)); } } Output : true
We can clean up the above code base further . As a Predicate interface is a functional interface hence Instead of writing a Implementer class we can use the lambda expression directly ( In Short we can depict the method of a functional interface as a lambda expression )
interface Predicate < T > { boolean test(T t); } public class PredicateInterfaceDemo { public static void main(String[] args) { Predicate<Integer> predicate = (Integer number) -> { return number % 2 == 0; }; System.out.println(predicate.test(15)); } } Output : false
We can pass the above lambda expression as an argument to some other method as well . You might have heard about filter method of Stream Api . Lets check below a very common example which we see often :
import java.util.Arrays; import java.util.List; public class PredicateInStreamsApi { public static void main(String[] args) { List<Integer> list = Arrays.asList(1, 2, 3, 4, 5); list.stream() .filter(number -> number % 2 == 0) .forEach(number -> System.out.println(number)); } } Output : 2 4
filter method accepts the java.util.function.Predicate as an argument . Check the snap and code below :
import java.util.Arrays; import java.util.List; import java.util.function.Predicate; public class PredicateInStreamsApi { public static void main(String[] args) { List<Integer> list = Arrays.asList(1, 2, 3, 4, 5); Predicate<Integer> predicate = (Integer number) -> number % 2 == 0; list.stream() .filter(predicate) .forEach(number -> System.out.println(number)); } } Output : 2 4
filter method calls the Predicate interface test method internally .
and method
and is a default method in predicate interface which accepts a predicate as an argument and returns back a predicate . This method acts as a logical “and operator” hence if both the condition passes then only the result is true .
Syntax : default Predicate and(Predicate other)
- We will create a predicate1 which checks if the number is divisible by 2
- We will create another predicate2 which checks if the number is divisible by 5
- When “and operator” is applied on both the predicates , then the result number should be divisible by both 2 as well 5 .
predicate1.and(predicate2)
import java.util.function.Predicate; public class PredicateInStreamsApi { public static void main(String[] args) { Predicate<Integer> divisibleByTwo = (Integer number) -> number % 2 == 0; Predicate<Integer> divisibleByFive = (Integer number) -> number % 5 == 0; Predicate<Integer> andResultPredicate = divisibleByTwo.and(divisibleByFive); System.out.println(andResultPredicate.test(10)); } } Output : true
We can pass the andResultPredicate to filter method of stream as well . Check the example below :
import java.util.Arrays; import java.util.List; import java.util.function.Predicate; public class PredicateInStreamsApi { public static void main(String[] args) { List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 10, 15, 20); Predicate<Integer> divisibleByTwo = (Integer number) -> number % 2 == 0; Predicate<Integer> divisibleByFive = (Integer number) -> number % 5 == 0; list.stream() .filter(divisibleByTwo.and(divisibleByFive)) .forEach(number -> System.out.println(number)); } } Output: 10
or method
or is a default method in predicate interface which accepts a predicate as an argument and returns back a predicate . This method acts as a logical “or operator” hence if either of the condition passes then the result is true .
Syntax : default Predicate or(Predicate other)
- We will create a predicate1 which checks if the number is divisible by 2
- We will create another predicate2 which checks if the number is divisible by 5
- When “or operator” is applied on both the predicates , then the result number should be divisible by either 2 or either 5 .
predicate1.or(predicate2)
import java.util.function.Predicate; public class PredicateInStreamsApi { public static void main(String[] args) { Predicate<Integer> divisibleByTwo = (Integer number) -> number % 2 == 0; Predicate<Integer> divisibleByFive = (Integer number) -> number % 5 == 0; Predicate<Integer> OrResultPredicate = divisibleByTwo.or(divisibleByFive); System.out.println(OrResultPredicate.test(5)); } } Output : true
We can pass the OrResultPredicate to filter method of stream as well . Check the example below :
import java.util.Arrays; import java.util.List; import java.util.function.Predicate; public class PredicateInStreamsApi { public static void main(String[] args) { List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 10, 15); Predicate<Integer> divisibleByTwo = (Integer number) -> number % 2 == 0; Predicate<Integer> divisibleByFive = (Integer number) -> number % 5 == 0; list.stream() .filter(divisibleByTwo.or(divisibleByFive)) .forEach(number -> System.out.println(number)); } } Output: 2 4 5 10 15
negate method
negate is a default method in functional interface which accepts no argument and returns back a predicate . It acts as a logical not operation .
Syntax : default Predicate negate()
For Ex : Negation of true is false .
Negation of false is true .
import java.util.function.Predicate; public class PredicateInStreamsApi { public static void main(String[] args) { Predicate<Integer> predicate = (Integer number) -> number % 2 == 0; System.out.println(predicate.test(10)); System.out.println(predicate.negate().test(10)); } } Output: true false
We will use negate with in the filter method . Check the example below :
import java.util.Arrays; import java.util.List; import java.util.function.Predicate; public class PredicateInStreamsApi { public static void main(String[] args) { List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 10, 15, 20); Predicate<Integer> predicate = (Integer number) -> number % 2 == 0; Predicate<Integer> negatePredicate = predicate.negate(); // negate returns back a Predicate list.stream() .filter(negatePredicate) .forEach(number -> System.out.println(number)); } } Output : 1 3 5 15
isEqual method
isEqual is a static method in predicate interface which accepts an Object as a argument and returns back a predicate . It is used to compare the equality of two objects .
Syntax : static Predicate isEqual(Object targetRef)
import java.util.function.Predicate; class Student { int rollNo; String name; Student(int rollNo, String name) { this.rollNo = rollNo; this.name = name; } } public class PredicateInStreamsApi { public static void main(String[] args) { Student student1 = new Student(101, "Suraj"); Student student2 = new Student(101, "Suraj"); Predicate<Student> predicate = Predicate.isEqual(student1); System.out.println(predicate.test(student2)); // student1 is not equal to student2 Student student3 = student1; System.out.println(predicate.test(student3)); // student1 is equal to student3 } } Output : false true
Hope you liked this article on predicate functional interface injava 8 . If you want to add anything extra please comment below and write to me if i have gone wrong anywhere . Learn more java 8 concepts here Java-8 .