BiFunction Interface in Java
-
BiFunction
apply()
Method Example in Java -
BiFunction
andThen()
Method in Java -
Avoid
NullPointerException
in BiFunction Interface - BiFunction with HashMap in Java
- BiFunction and Method Reference
- Conclusion
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
- How to Convert Iterable to Stream in Java
- How to Distinct by Property in Java 8 Stream
- How to Convert Stream Element to Map in Java
- The Stream Reduce Operation in Java
- How to Convert Stream to Array in Java