BiFunction Interface in Java

Mohammad Irfan Oct 12, 2023
  1. BiFunction apply() Method Example in Java
  2. BiFunction andThen() Method in Java
  3. Avoid NullPointerException in BiFunction Interface
  4. BiFunction with HashMap in Java
  5. BiFunction and Method Reference
  6. Conclusion
BiFunction Interface in Java

In this tutorial, we will discuss the BiFunction interface in Java.

The BiFunction interface is a built-in functional interface introduced in Java 8 and is located in the java.util.function package. Unlike the Function interface that takes two generics (one argument type and one return type), BiFunction takes two arguments and produces a result.

We can assign a lambda expression or a method reference that takes two arguments and returns a result to an object of type BiFunction.

BiFunction takes three generics - T, U, and R. T and U are the types of the first and second arguments, respectively. R is the type of the result of the Function.

interface BiFunction<T, U, R>

BiFunction interface has two methods:

  • apply(): It performs the defined operation on the arguments and returns a result. The syntax of this method is:
R apply(T t, U u) // R is the return type. T and U are the types of the two arguments
  • andThen(): It returns the result from a composed function. In simpler words, it first runs the BiFunction on the two arguments and produces a result. Next, it passes the result to a Function. The syntax of this method is:
default<V> BiFunction<T, U, V> andThen(Function<? super R, ? extends V> after)

BiFunction apply() Method Example in Java

Let’s create a simple BiFunction that takes Integer and Double type arguments and returns a String. We used the apply() method to pass the argument and get the result.

See the example below.

import java.util.function.*;

public class SimpleTesting {
  public static void main(String args[]) {
    // BiFunction with arguments of type Integer and Double
    // and return type of String
    BiFunction<Integer, Double, String> biFunction = (a, b) -> {
      double result = a * b;
      String s = "The result from the BiFunction is: " + result;
      return s;
    };

    String output = biFunction.apply(10, 15.5);
    System.out.print(output);
  }
}

Output:

The result from the BiFunction is: 155.0

BiFunction andThen() Method in Java

Let’s pass the result of the BiFunction defined above to a Function. We will use the andThen() method. This method first evaluates the result of the BiFunction and then passes that result to the after Function.

import java.util.function.*;

public class SimpleTesting {
  public static void main(String args[]) {
    // BiFunction with arguments of type Integer and Double
    // and return type of String
    BiFunction<Integer, Double, String> biFunction = (a, b) -> {
      double result = a * b;
      String s = "The result from the BiFunction is: " + result;
      return s;
    };

    // Function with argument of type String
    // and return type of Integer
    Function<String, Integer> after = s -> {
      Integer length = s.length();
      return length;
    };

    int output = biFunction.andThen(after).apply(
        10, 15.5); // first evaluates the BiFunction and then the Function
    System.out.print(output);
  }
}

Output:

40

Avoid NullPointerException in BiFunction Interface

If we pass a null reference to the andThen() method, the code returns NullPointerException. See the example below. We should avoid such mistakes and always put the code in try...catch blocks.

import java.util.function.*;

public class SimpleTesting {
  public static void main(String args[]) {
    BiFunction<Integer, Double, String> biFunction = (a, b) -> {
      double result = a * b;
      String s = "The result from the BiFunction is: " + result;
      return s;
    };

    Function<String, Integer> after = null;

    int output = biFunction.andThen(after).apply(10, 15.5);
    System.out.print(output);
  }
}

Output:

Exception in thread "main" java.lang.NullPointerException
	at java.base/java.util.Objects.requireNonNull(Objects.java:222)
	at java.base/java.util.function.BiFunction.andThen(BiFunction.java:69)
	at SimpleTesting.main(SimpleTesting.java:15)

Note that we cannot integrate two BiFunctions using the andThen() method.

BiFunction with HashMap in Java

BiFunctions are used as arguments in a few HashMap methods like compute(), computeIfPresent(), merge(), and replaceAll().

Let’s create an example to use BiFunction in HashMap. Consider a HashMap that stores student roll numbers and their scores. We need to add 5 to the score of every student, except roll number 101.

import java.util.HashMap;
import java.util.function.*;

public class SimpleTesting {
  public static void main(String args[]) {
    HashMap<Integer, Double> scoreMap = new HashMap<>();
    scoreMap.put(101, 95.2);
    scoreMap.put(102, 86.0);
    scoreMap.put(103, 91.9);
    scoreMap.put(104, 72.8);
    scoreMap.put(105, 89.5);

    System.out.println("Intial HashMap: " + scoreMap);

    // BiFunction with arguments of type Integer and Double
    // and return type of Double
    BiFunction<Integer, Double, Double> biFunction = (key, value) -> {
      if (key == 101)
        return value;
      else
        return value + 5;
    };
    scoreMap.replaceAll(biFunction);
    System.out.print("HashMap After The Update: " + scoreMap);
  }
}

Output:

Intial HashMap: {101=95.2, 102=86.0, 103=91.9, 104=72.8, 105=89.5}
HashMap After The Update: {101=95.2, 102=91.0, 103=96.9, 104=77.8, 105=94.5}

BiFunction and Method Reference

So far, we have used the BiFunction interface as a reference for lambda expressions. A method can also be referenced using a BiFunction. The method must take only two arguments and returns a result.

Let’s write a simple static method that checks whether the sum of the two given integers is even or not. We can assign this method reference to a BiFunction. See the example below.

import java.util.function.*;

public class SimpleTesting {
  static boolean isSumEven(int a, int b) {
    int sum = a + b;
    if (sum % 2 == 0)
      return true;
    else
      return false;
  }

  public static void main(String args[]) {
    BiFunction<Integer, Integer, Boolean> biFunction = SimpleTesting::isSumEven;

    System.out.println("Is sum of 10 and 21 even? " + biFunction.apply(10, 21));
    System.out.print("Is sum of 5 and 7 even? " + biFunction.apply(5, 7));
  }
}

Output:

Is sum of 10 and 21 even? false
Is sum of 5 and 7 even? true

Conclusion

Java BiFunction interface is a functional interface. It is used as the assignment target for lambda expressions or method references. BiFunction interface is preferred over the Function interface when we need to pass two arguments.

The BiFunction interface contains two methods: apply(), and andThen(). The apply() method applies the function on the two given arguments. The andThen() method is used to pass the result of BiFunction to a Function interface.

Related Article - Java Stream

Related Article - Java Interface