o7planning

Java BiPredicate Tutorial with Examples

View more Tutorials:

Follow us on our fanpages to receive notifications every time there are new articles. Facebook Twitter

1- BiPredicate

In Java 8, BiPredicate is a functional interface, representing an operator that accepts two input parameters and returns a boolean value.
BiPredicate interface

@FunctionalInterface
public interface BiPredicate<T, U> {
    boolean test(T t, U u);
    
    default BiPredicate<T, U> and(BiPredicate<? super T, ? super U> other) {
        Objects.requireNonNull(other);
        return (T t, U u) -> test(t, u) && other.test(t, u);
    }  
    default BiPredicate<T, U> negate() {
        return (T t, U u) -> !test(t, u);
    }
    default BiPredicate<T, U> or(BiPredicate<? super T, ? super U> other) {
        Objects.requireNonNull(other);
        return (T t, U u) -> test(t, u) || other.test(t, u);
    }
}
See also: Predicate is a functional interface similar to BiPredicate, which only accepts one parameter:
Example: Create a BiPredicate object to check if the length of a String matches a given number.
BiPredicateEx1.java

package org.o7planning.bipredicate.ex;

import java.util.function.BiPredicate;

public class BiPredicateEx1 {

    public static void main(String[] args) {  
        // Create a BiPredicate.
        BiPredicate<String,Integer> tester = (aString, aNumber) -> {
            return aString.length() == aNumber;
        };
        // Test:
        boolean testResult = tester.test("o7planning.org", 14);
        
        System.out.println("Test Result: " + testResult);
    }
}
Output:

Test Result: true
Continue with the above example. A Map<String,Integer> object contains mappings between a String and its length. However there are some incorrect mappings. Print out the correct mappings.
BiPredicateEx2.java

package org.o7planning.bipredicate.ex;

import java.util.HashMap;
import java.util.Map;
import java.util.function.BiPredicate;

public class BiPredicateEx2 {

    public static void main(String[] args) {  
        // Create a BiPredicate.
        BiPredicate<String,Integer> tester = (aString, aNumber) -> {
            return aString.length() == aNumber;
        };

        // String aString --> Integer length.
        Map<String,Integer> map = new HashMap<String,Integer>();
        
        map.put("Apple", 5);
        map.put("Google", 10); // Wrong
        map.put("Microsoft", 9);
        map.put("Amazon", 100); // Wrong
        map.put("Louis Vuitton", 13);  
        map.put("Disney", 6);  
        map.put("Intel", 5);  
        
        map.entrySet()  // Set<Map.Entry<String,Integer>>
             .stream()  // Stream<Map.Entry<String,Integer>>
             // filter(Predicate<Map.Entry<String,Integer>>)
             .filter(entry ->  tester.test(entry.getKey(), entry.getValue())) // Stream<Map.Entry<String,Integer>>
             .forEach(entry -> System.out.println(entry.getKey() +" --> " + entry.getValue()));
    }
}
Output:

Apple --> 5
Disney --> 6
Louis Vuitton --> 13
Microsoft --> 9
Intel --> 5

2- test(T t, U u)


public boolean test(T t, U u);
Evaluates this BiPredicate on the given arguments.

3- BiPredicate + Method reference

If a static method takes 2 parameters and returns a boolean then its reference is considered as a BiPredicate:
Example:
BiPredicate_mRef_ex1.java

package org.o7planning.bipredicate.ex;

import java.util.function.BiPredicate;

public class BiPredicate_mRef_ex1 {

    public static void main(String[] args) {
        // Create a BiPredicate from a Method reference.
        BiPredicate<Staff,Integer> tester = StaffUtils::higher;
        
        Staff tom = new Staff("Tom", 3000);
        
        boolean testResult = tester.test(tom, 2000);
        
        System.out.println("Test Result: " + testResult);
    }
}

class StaffUtils {

    // A static method take 2 input parameters and return boolean type.
    public static boolean higher(Staff staff, int salary) {
         return staff.getSalary() > salary;
    }
}

class Staff {
    private String fullName;
    private int salary;
    
    public Staff(String fullName, int salary) {
        this.fullName = fullName;
        this.salary = salary;
    }
    public String getFullName() {
        return fullName;
    }
    public int getSalary() {
        return salary;
    }
}
Output:

Test Result: true

4- negate()

negate() method returns a new BiPredicate object whose evaluation is negative of the current BiPredicate.

default BiPredicate<T, U> negate() {
    return (T t, U u) -> !test(t, u);
}
Example: A BiPredicate<Integer,Integer> that checks 2 numbers to see if the first number is greater than the second number.
BiPredicate_negate_ex1.java

package org.o7planning.bipredicate.ex;

import java.util.function.BiPredicate;

public class BiPredicate_negate_ex1 {

    public static void main(String[] args) {  
        // Create a BiPredicate.
        // Check if anInteger1 > anInteger2
        BiPredicate<Integer, Integer> tester = (anInteger1, anInteger2) -> {
            return anInteger1 > anInteger2;
        };
      
        boolean test1 = tester.test(100, 10);
        
        boolean test2 = tester.negate().test(100, 10);
   
        System.out.println("Test1: " + test1);
        System.out.println("Test2: " + test2);
    }
}
Output:

Test1: true
Test2: false
Example: A Map<String,Integer> object contains mappings between a String and its length. However there are some incorrect mappings. Print out those incorrect mappings.
BiPredicate_negate_ex2.java

package org.o7planning.bipredicate.ex;

import java.util.HashMap;
import java.util.Map;
import java.util.function.BiPredicate;

public class BiPredicate_negate_ex2 {

    public static void main(String[] args) {  
        // Create a BiPredicate.
        // Check if length of a String equals to aNumber.
        BiPredicate<String,Integer> tester = (aString, aNumber) -> {
            return aString.length() == aNumber;
        };

        // String aString --> Integer length.
        Map<String,Integer> map = new HashMap<String,Integer>();
        
        map.put("Apple", 5);
        map.put("Google", 10); // Wrong
        map.put("Microsoft", 9);
        map.put("Amazon", 100); // Wrong
        map.put("Louis Vuitton", 13);  
        map.put("Disney", 6);  
        map.put("Intel", 5);  
        
        map.entrySet()  // Set<Map.Entry<String,Integer>>
             .stream()  // Stream<Map.Entry<String,Integer>>
             // filter(Predicate<Map.Entry<String,Integer>>)
             .filter(entry ->  tester.negate().test(entry.getKey(), entry.getValue())) // Stream<Map.Entry<String,Integer>>
             .forEach(entry -> System.out.println(entry.getKey() +" --> " + entry.getValue()));
    }
}
Output:

Google --> 10
Amazon --> 100

5- and(BiPredicate other)

and(other) method creates a new BiPredicate object by combining the current BiPredicate and other. It evaluates to true if both the current BiPredicate and other are evaluated to be true.

default BiPredicate<T, U> and(BiPredicate<? super T, ? super U> other) {
    Objects.requireNonNull(other);
    return (T t, U u) -> test(t, u) && other.test(t, u);
}
Example:
BiPredicate_and_ex1.java

package org.o7planning.bipredicate.ex;

import java.util.function.BiPredicate;

public class BiPredicate_and_ex1 {

    public static void main(String[] args) {
        // Test if anInteger1 > anInteger2
        BiPredicate<Integer, Integer> tester1 = (anInteger1, anInteger2) -> {
            return anInteger1 > anInteger2;
        };

        // Test if anInteger1 + anInteger2 > 100
        BiPredicate<Integer, Integer> tester2 = (anInteger1, anInteger2) -> {
            return anInteger1 + anInteger2 > 100;
        };

        // Test if number1 > number2 and number1 + number2 > 100.
        boolean testResult1 = tester1.and(tester2).test(70, 45);
        boolean testResult2 = tester1.and(tester2).test(45, 70);
        
        System.out.println("Test Result 1: " + testResult1);
        System.out.println("Test Result 2: " + testResult2);
    }
}
Output:

Test Result 1: true
Test Result 2: false

6- or(BiPredicate other)

or(other) method returns a new BiPredicate object by combining the current BiPredicate and other. It evaluates to true if either, the current BiPredicate or other is evaluated to be true.

default BiPredicate<T, U> or(BiPredicate<? super T, ? super U> other) {
    Objects.requireNonNull(other);
    return (T t, U u) -> test(t, u) || other.test(t, u);
}
Example:
BiPredicate_or_ex1.java

package org.o7planning.bipredicate.ex;

import java.util.function.BiPredicate;

public class BiPredicate_or_ex1 {

    public static void main(String[] args) {
        // Test if anInteger1 > anInteger2
        BiPredicate<Integer, Integer> tester1 = (anInteger1, anInteger2) -> {
            return anInteger1 > anInteger2;
        };

        // Test if anInteger1 + anInteger2 > 100
        BiPredicate<Integer, Integer> tester2 = (anInteger1, anInteger2) -> {
            return anInteger1 + anInteger2 > 100;
        };

        // Test if number1 > number2 or number1 + number2 > 100.
        boolean testResult1 = tester1.or(tester2).test(70, 45);
        boolean testResult2 = tester1.or(tester2).test(45, 70);  
        
        System.out.println("Test Result 1: " + testResult1);
        System.out.println("Test Result 2: " + testResult2);
    }
}
Output:

Test Result 1: true
Test Result 2: true

View more Tutorials: