How do I use the BiPredicate functional interface in Java?

The BiPredicate interface is a functional interface introduced in Java 8 that represents a predicate (boolean-valued function) with two arguments. It is located in the java.util.function package and can be used to evaluate a condition or logical test involving two input arguments.

Key Details about BiPredicate:

Functional Method:

The BiPredicate interface defines a single abstract method:

boolean test(T t, U u);
  • t and u are the two input arguments of generic types.
  • The method returns a boolean result based on the condition.

Default Methods:

  • default BiPredicate<T, U> and(BiPredicate<? super T, ? super U> other)
    Returns a composed predicate that represents a short-circuiting logical AND of this predicate and another.
  • default BiPredicate<T, U> or(BiPredicate<? super T, ? super U> other)
    Returns a composed predicate that represents a short-circuiting logical OR of this predicate and another.
  • default BiPredicate<T, U> negate()
    Returns a predicate that represents the logical negation of this predicate.

Example Usage of BiPredicate:

Example 1: Testing Two Numbers

package org.kodejava.util.function;

import java.util.function.BiPredicate;

public class BiPredicateExample {
    public static void main(String[] args) {
        // BiPredicate to check if the sum of two integers is greater than 50
        BiPredicate<Integer, Integer> sumGreaterThanFifty =
                (a, b) -> (a + b) > 50;

        // Output: true
        System.out.println(sumGreaterThanFifty.test(30, 25));
        // Output: false
        System.out.println(sumGreaterThanFifty.test(10, 20));
    }
}

Example 2: Comparison of Strings

package org.kodejava.util.function;

import java.util.function.BiPredicate;

public class StringComparison {
    public static void main(String[] args) {
        // BiPredicate to check if two strings are equal ignoring case
        BiPredicate<String, String> equalsIgnoreCase =
                (str1, str2) -> str1.equalsIgnoreCase(str2);

        // Output: true
        System.out.println(equalsIgnoreCase.test("Hello", "hello"));
        // Output: false
        System.out.println(equalsIgnoreCase.test("Java", "Kotlin"));
    }
}

Example 3: Combining Predicates

We can use the and, or, and negate methods to combine BiPredicate conditions.

package org.kodejava.util.function;

import java.util.function.BiPredicate;

public class CombinedPredicates {
    public static void main(String[] args) {
        // BiPredicate to check if a is greater than b
        BiPredicate<Integer, Integer> isGreater = (a, b) -> a > b;

        // BiPredicate to check if a is even
        BiPredicate<Integer, Integer> isAEven = (a, b) -> a % 2 == 0;

        // Combining predicates: is a greater than b AND a is even
        BiPredicate<Integer, Integer> combined = isGreater.and(isAEven);

        // Output: true (10 > 5 and 10 is even)
        System.out.println(combined.test(10, 5));
        // Output: false (7 > 5 but 7 is not even)
        System.out.println(combined.test(7, 5));
        // Output: false (3 is not greater than 5)
        System.out.println(combined.test(3, 5));
    }
}

Example 4: Filtering Collections Using BiPredicate

A common use case is using BiPredicate to filter data in collections.

package org.kodejava.util.function;

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

public class FilterCollection {
    public static void main(String[] args) {
        List<String> data = new ArrayList<>();
        data.add("Java");
        data.add("Kotlin");
        data.add("JavaScript");
        data.add("Python");

        // BiPredicate to filter strings where length is 
        // greater than given threshold
        BiPredicate<String, Integer> isLongerThan =
                (str, limit) -> str.length() > limit;

        // Filter strings based on the predicate
        for (String str : data) {
            if (isLongerThan.test(str, 5)) {
                // Output: Kotlin, JavaScript, Python
                System.out.println(str);
            }
        }
    }
}

Common Use Cases:

  1. Comparison Operations: Used to compare two objects or primitive values.
  2. Collection Filtering: Applying conditions with two parameters in stream operations or loops.
  3. Logical Compositions: Creating complex conditions by composing multiple predicates.

Summary:

  • The BiPredicate interface is useful for conditions involving two inputs.
  • We can combine and enhance predicates using default methods like and, or, and negate.
  • It is versatile for working with collections, streams, and logical operations in a structured functional way.
Wayan

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.