I have a stream of BiFunctions which I want to reduce to a single BiFunction.
To be more specific I have a stream of BiFunctions
BiFunction<x,y,y>
Where x and y denote the types of the arguments.
Assuming I have two functions
f (x, y) -> y
g (x, y) -> y
I want to compose them to the function
h(x, y) -> f(x, g(x, y))
Is this possible using Java 8 streams, and if not, what would be the most elegant way asides of just looping over all the available functions and composing them in another way?
A composite function is a function that depends on another function. A composite function is created when one function is substituted into another function. For example, f(g(x)) is the composite function that is formed when g(x) is substituted for x in f(x). f(g(x)) is read as “f of g of x”.
If we are given two functions, we can create another function by composing one function into the other. The steps required to perform this operation are similar to when any function is solved for any given value. Such functions are called composite functions.
Using x=Integer
and y=String
, you could define f
and g
as:
BiFunction<Integer, String, String> f = (i, s) -> i + "-f-" + s;
BiFunction<Integer, String, String> g = (i, s) -> i + "-g-" + s;
And the h
function could be built using a reduction:
BiFunction<Integer, String, String> h = Stream.of(f, g)
.reduce((f_, g_) -> (i, s) -> f_.apply(i, g_.apply(i, s)))
.get(); //we know the stream is not empty so we can call get directly
If you apply h
to 1
and "s"
, it will return 1-f-1-g-s
.
As a slight modification to the answer by assylias : Depending on the application pattern, you can also use the Stream#reduce
method that accepts an identity as the first argument, which in this case is the "identity BiFunction
" (actually, a projection on the second argument).
import java.util.function.BiFunction;
import java.util.stream.Stream;
public class BiFunctionsComposition
{
public static void main(String[] args)
{
BiFunction<String, String, String> f = (x,y) -> "f("+x+","+y+")";
BiFunction<String, String, String> g = (x,y) -> "g("+x+","+y+")";
BiFunction<String, String, String> h = Stream.of(f, g)
.reduce((x,y) -> y, (ff,gg) -> (x,y) -> ff.apply(x, gg.apply(x, y)));
String result = h.apply("A", "B");
System.out.println(result); // Prints f(A,g(A,B))
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With