This article covers all aspects of predicates in Java (java.util.function.Predicate, java.util.function.BiPredicate), Google API Guava (com.google.common.base.Predicate) & Apache API commons-collection (org.apache.commons.collections4.Predicate) through several examples.
java.util.function.Predicate
java.util.function.Predicate is a functional interface which provides ability to test certain criteria based on single argument. Here are code examples of java.util.function.Predicate in simple use, lambda, streams. Example also shows how multiple predicates can be combined using AND & OR operations & how existing predicate can be negated.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 |
package com.itsallbinary.java; import java.util.Arrays; import java.util.List; import java.util.function.Predicate; import java.util.stream.Collectors; public class PredicateExamples { public static void main(String[] args) { /* * Simple predicate & its use. */ Predicate<String> hasSpaces = s -> s.contains(" "); System.out.println( "Predicate result = " + hasSpaces.test("This has spaces")); /* * Use predicate in functional programming style with streams. */ List<String> texts = Arrays.asList("JAMES", "SPACE - HYPHEN", "NOSPACE", "S P A C E", "H-Y-P-H-E-N"); System.out.println("These have space = " + texts.stream() .filter(hasSpaces).collect(Collectors.joining(","))); /* * Combine predicates with AND or OR operations. */ System.out.println("These have space AND hyphen = " + texts.stream().filter(hasSpaces.and(s -> s.contains("-"))) .collect(Collectors.joining(","))); System.out.println("These have space OR hyphen = " + texts.stream().filter(hasSpaces.or(s -> s.contains("-"))) .collect(Collectors.joining(","))); /* * Negate predicate */ System.out.println("These don't have space = " + texts.stream() .filter(hasSpaces.negate()).collect(Collectors.joining(","))); } } |
1 2 3 4 5 |
Predicate result = true These have space = SPACE - HYPHEN,S P A C E These have space AND hyphen = SPACE - HYPHEN These have space OR hyphen = SPACE - HYPHEN,S P A C E,H-Y-P-H-E-N These don't have space = JAMES,NOSPACE,H-Y-P-H-E-N |
java.util.function.BiPredicate
java.util.function.BiPredicate is a functional interface which provides ability to test any criteria based on two arguments. Multiple bipredicates can be combined using NAD or OR operations.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
/* * -------------- java.util.function.BiPredicate --------------- */ /* * Check if String number is same as Integer number. */ BiPredicate<String, Integer> isTextEqualsIntegerPredicate = (s, i) -> Integer.valueOf(s).equals(i); boolean isTextEqualsInteger = isTextEqualsIntegerPredicate.test("100", 100); System.out.println("Text number equals Integer Number = " + isTextEqualsInteger); /* * Check if text number & Integer number are different by just negating earlier * BiPredicate */ BiPredicate<String, Integer> isTextDifferentThanIntegerPredicate = isTextEqualsIntegerPredicate.negate(); boolean isTextDifferentThanInteger = isTextDifferentThanIntegerPredicate.test("999", 100); System.out.println("Text number & Integer Number are different = " + isTextDifferentThanInteger); /* * Use BiPredicate.or() to compose new predicate which is OR of two different * predicate. */ BiPredicate<String, Integer> isTextGreaterThanIntegerPredicate = (s, i) -> Integer.valueOf(s).compareTo(i) > 0; BiPredicate<String, Integer> isTextGreaterThanAndEqualsIntegerPredicate = isTextGreaterThanIntegerPredicate .or(isTextEqualsIntegerPredicate); System.out.println( "Is greater than or equals to = " + isTextGreaterThanAndEqualsIntegerPredicate.test("150", 100)); System.out.println( "Is greater than or equals to = " + isTextGreaterThanAndEqualsIntegerPredicate.test("100", 100)); |
Multi argument predicate like Tri Predicate or Tetra Predicate or so ..
If more than 2 arguments are required for predicate, then its better to wrap those arguments in single object & pass to single argument predicate.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
package com.itsallbinary.java; import java.util.function.Predicate; public class TriPredicateExample { public static void main(String[] args) { Predicate<Container> triPredicate = c -> c.employeeName.startsWith("J") && c.departmentId.equals("Electrical") && c.otherData.contains("SomeData"); System.out.println("triPredicate result = " + triPredicate.test(new Container("James", "Electrical", "Here is SomeData for this employee"))); } } class Container { String employeeName; String departmentId; String otherData; public Container(String employeeName, String departmentId, String otherData) { super(); this.employeeName = employeeName; this.departmentId = departmentId; this.otherData = otherData; } } |
1 |
triPredicate result = true |
com.google.common.base.Predicate
com.google.common.base.Predicate is sub-interface of Java’s java.util.function.Predicate since 2.0 version of Guava. So google predicate can be used same as java.util.function.Predicate.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 |
package com.itsallbinary.guava; import java.util.Arrays; import java.util.List; import java.util.stream.Collectors; import com.google.common.base.Predicate; public class PredicateExamples { public static void main(String[] args) { /* * Simple predicate & its use. */ Predicate<String> hasSpaces = s -> s.contains(" "); System.out.println( "Predicate result = " + hasSpaces.test("This has spaces")); /* * Use predicate in functional programming style with streams. */ List<String> texts = Arrays.asList("JAMES", "SPACE - HYPHEN", "NOSPACE", "S P A C E", "H-Y-P-H-E-N"); System.out.println("These have space = " + texts.stream() .filter(hasSpaces).collect(Collectors.joining(","))); /* * Combine predicates with AND or OR operations. */ System.out.println("These have space AND hyphen = " + texts.stream().filter(hasSpaces.and(s -> s.contains("-"))) .collect(Collectors.joining(","))); System.out.println("These have space OR hyphen = " + texts.stream().filter(hasSpaces.or(s -> s.contains("-"))) .collect(Collectors.joining(","))); /* * Negate predicate */ System.out.println("These don't have space = " + texts.stream() .filter(hasSpaces.negate()).collect(Collectors.joining(","))); } } |
1 2 3 4 5 |
Predicate result = true These have space = SPACE - HYPHEN,S P A C E These have space AND hyphen = SPACE - HYPHEN These have space OR hyphen = SPACE - HYPHEN,S P A C E,H-Y-P-H-E-N These don't have space = JAMES,NOSPACE,H-Y-P-H-E-N |
But here is the real advantage that guava can still offer if use guava predicate. Guava offers utility class com.google.common.base.Predicates which provides lot of good-to-use utility methods for predicates. Here are examples.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 |
package com.itsallbinary.guava; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.stream.Collectors; import com.google.common.base.Predicate; import com.google.common.base.Predicates; public class PredicatesUtilityExamples { public static void main(String[] args) { Predicate<String> hasSpaces = s -> s.contains(" "); Predicate<String> hasHyphens = s -> s.contains("-"); Predicate<String> startWithS = s -> s.startsWith("S"); List<String> texts = Arrays.asList("JAMES", "SPACE - HYPHEN", "NOSPACE", "S P A C E", "H-Y-P-H-E-N"); /* * Combine all above three predicates with AND var args */ System.out .println("These have space AND hyphen AND start with S = " + texts.stream() .filter(Predicates.and(hasSpaces, hasHyphens, startWithS)) .collect(Collectors.joining(","))); /* * Special predicates to check object present in collection */ System.out.println("JAMES present in texts collection = " + Predicates.in(texts).test("JAMES")); /* * Special predicates to do subtype check, null check instanceof check * etc.. */ System.out.println("subtype check = " + Predicates.subtypeOf(List.class).test(ArrayList.class)); System.out.println("null check = " + Predicates.notNull().test(null)); System.out.println("instanceOf check = " + Predicates.instanceOf(List.class).test(new ArrayList<>())); } } |
1 2 3 4 5 |
These have space AND hyphen AND start with S = SPACE - HYPHEN JAMES present in texts collection = true subtype check = true null check = false instanceOf check = true |
org.apache.commons.collections4.Predicate
org.apache.commons.collections4.Predicate does not extend java’s java.util.function.Predicate so might not work directly in lambda. But Apache’s predicate does provides many in-built predicates.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 |
package com.itsallbinary.apache; import java.util.Arrays; import java.util.List; import org.apache.commons.collections4.Predicate; import org.apache.commons.collections4.PredicateUtils; import org.apache.commons.collections4.functors.NotNullPredicate; import org.apache.commons.collections4.functors.NullIsFalsePredicate; public class PrediatesExamples { public static void main(String[] args) { /* * Simple predicate example */ Predicate<String> hasSpaces = s -> s.contains(" "); System.out.println( "Predicate result = " + hasSpaces.evaluate("This has spaces")); /* * Special predicates */ System.out.println("notNullPredicate = " + PredicateUtils.notNullPredicate().evaluate(null) + ", another way = " + NotNullPredicate.INSTANCE.evaluate(null)); System.out .println("neitherPredicate = " + PredicateUtils .neitherPredicate(s -> ((String) s).contains(" "), s -> ((String) s).contains("-")) .evaluate("JAMES")); /* * Make existing non-null safe predicate null safe. */ System.out.println("Prediate made null sage = " + PredicateUtils.nullIsFalsePredicate(hasSpaces).evaluate(null) + ", another way = " + NullIsFalsePredicate .nullIsFalsePredicate(hasSpaces).evaluate(null)); /* * Use predicate in functional programming style with streams. */ List<String> texts = Arrays.asList("JAMES", "SPACE - HYPHEN", "NOSPACE", "S P A C E", "H-Y-P-H-E-N"); } } |
1 2 3 4 |
Predicate result = true notNullPredicate = false, another way = false neitherPredicate = true Prediate made null sage = false, another way = false |