Composing Two-Arity Functions
The interface BiFunction<T, U, R> provides the andThen() method for creating compound two-arity functions. Given a two-arity function f and a one-arity function g, the method evaluates the functions as follows:
f.andThen(g).apply(x, y) emulates g.apply(f.apply(x, y))—that is, the two-arity function f is executed first and the one-arity function g last.
In the example below, the functions chained by the andThen() method calls are applied from left to right, first the caller function and then the parameter function.
BiFunction<String, String, String> concatStr = (s1, s2) -> s1 + s2;
Function<String, String> postfix1 = s -> s + “nana”;
Function<String, String> postfix2 = s -> s + “s!”;
System.out.println(concatStr.andThen(postfix1).andThen(postfix2)
.apply(“I am going”, ” ba”)); // I am going bananas!
In the code below, the concatStr two-arity function is both the caller and the parameter function in the call to the andThen() method. However, the code does not compile. The reason is easy to understand: The two-arity parameter function requires two arguments, but the two-arity caller function can only return a single value. A one-arity function as the parameter function avoids this problem, as it can accept the single-value result of the caller function. Chaining instances of BiFunction<T, U, R> is not as straightforward as chaining instances of Function<T, R>.
BiFunction<String, String, String> concatTwice
= concatStr.andThen(concatStr); // Compile-time error!
default <V> BiFunction<T,U,V> andThen(Function<? super R,? extends V> after)
This generic method returns a composed two-arity function that first applies this function to its input, and then applies the specified after one-arity function to the result.
Note the type of the parameter: It is Function and not BiFunction. Given that the type of this two-arity function is (T, U) -> R and the type of the one-arity parameter function after is R -> V, the andThen() method creates a compound two-arity function of type (T, U) -> V, as this function is executed first and the one-arity function after last.
Any exception thrown during the evaluation of either function aborts the evaluation of the composed function and the exception is conveyed to the caller.