Reputation: 249
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?
Upvotes: 14
Views: 920
Reputation: 54709
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))
}
}
Upvotes: 8
Reputation: 328893
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
.
Upvotes: 14