Free tools Windows power users keep installed

One-click scans. No signup required.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

iTechGuides is reader-supported. When you buy through links on our site, we may earn an affiliate commission. As an Amazon Associate I earn from qualifying purchases. Learn more

BiFunction<T, U, R> represents a calculation that takes two inputs—one of type T and one of type U—and returns a result of type R. Use its apply method to run the calculation, and andThen to transform its result. Unlike Function, BiFunction has no compose method.

What is a BiFunction in Java?

Oracle’s Java SE 26 BiFunction API documentation describes it as a function that “accepts two arguments and produces a result.” Its type parameters identify the first input, second input, and result: BiFunction<T, U, R>.

Its functional method is R apply(T t, U u). Because it has one abstract method, a lambda or compatible method reference can supply its behavior:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
BiFunction<Integer, Integer, Integer> add = (left, right) -> left + right;

int total = add.apply(3, 4); // 7

Here, both inputs and the returned value are integers. The interface has existed since Java 1.8; the Java SE 26 API page documents its current contract. Confirm your project’s supported Java version before using it.

How does BiFunction compare with Function and BinaryOperator?

Choose an interface based on the callback’s input count and the relationship between its types.

Interface Inputs Result Composition method
Function<T, R> One value of type T Type R compose and andThen
BiFunction<T, U, R> One value of type T and one of type U Type R andThen
BinaryOperator<T> Two values of type T Type T andThen, inherited from BiFunction

BinaryOperator<T> is a specialized BiFunction<T, T, T>: both inputs and the result share the same type. It is a natural choice for operations such as combining two values of the same type.

How do I use BiFunction’s andThen method?

andThen runs the original two-input function first, then passes its result to another function. The original inputs are not changed; the second function receives only the first function’s output.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
BiFunction<Integer, Integer, Integer> add = (left, right) -> left + right;
Function<Integer, String> label = total -> "Total: " + total;
BiFunction<Integer, Integer, String> addAndLabel = add.andThen(label);

String result = addAndLabel.apply(3, 4); // "Total: 7"

The type flow is T and U into the BiFunction, then its R result into the following Function, which produces V. The resulting type is BiFunction<T, U, V>. Its API signature accepts Function<? super R, ? extends V>, allowing a function that accepts a supertype of R and returns a subtype of V.

If the original operation throws an exception, it propagates to the caller; an exception from the following function does too. Passing a null function to andThen causes a NullPointerException.

Does BiFunction have a compose method?

No. BiFunction provides andThen, but not compose. A single-input Function can define a compose method because it has one input to preprocess. For two inputs, decide how each value should be transformed and apply those transformations explicitly before calling the BiFunction:

Function<String, Integer> parse = Integer::parseInt;
BiFunction<Integer, Integer, Integer> add = Integer::sum;

String first = "3";
String second = "4";
int total = add.apply(parse.apply(first), parse.apply(second)); // 7

This keeps each input’s conversion visible and lets the resulting types be checked by the compiler.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Where is BiFunction used in Java?

Several JDK APIs accept a two-input callback. The callback’s purpose depends on the API, so do not assume that they share the same evaluation or concurrency behavior.

Map.compute and Map.merge

Map.compute uses a remapping function with the key and current mapped value to calculate a replacement mapping:

map.compute(key, (existingKey, currentValue) ->
    recompute(existingKey, currentValue));

The current value may be null in cases specified by the map contract, such as when there is no existing mapping. Map.merge also accepts a remapping callback, using it to combine the existing value with the supplied value when a mapping is already present. Consult the contract for the particular map and Java version when null handling or mutation behavior matters.

Stream.reduce

One Stream.reduce overload accepts a BiFunction accumulator. It combines a prior accumulated result with the next stream element; those two arguments need not have the same type. This is useful when the accumulator’s result type differs from the stream element type. Reduction overloads have specific identity, compatibility, and parallel-use requirements, so follow the overload’s contract rather than treating the callback as an unrestricted loop.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

CompletionStage.thenCombine

CompletionStage.thenCombine accepts a function that receives the results of two normally completed stages and combines them into a new result. The callback runs as part of composing the stages; it is not a substitute for choosing the appropriate asynchronous error-handling or scheduling method.

Concurrent map operations

Concurrent map APIs also use BiFunction callbacks for remapping or combining key-and-value results. Their concurrency guarantees and callback rules are specific to each operation; check the relevant API documentation before relying on invocation timing or side effects.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.