Состав BiFunctions
У меня есть поток BiFunctions, который я хочу свести к одному BiFunction.
Чтобы быть более конкретным, у меня есть поток BiFunctions
BiFunction<x,y,y>
Где x и y обозначают типы аргументов.
Предполагая, что у меня есть две функции
f (x, y) -> y
g (x, y) -> y
Я хочу скомпоновать их функции
h(x, y) -> f(x, g(x, y))
Возможно ли это, используя потоки Java 8, а если нет, то что было бы самым элегантным способом просто перебрать все доступные функции и составить их по-другому?
Ответы
Ответ 1
Используя x=Integer
и y=String
, вы можете определить f
и g
как:
BiFunction<Integer, String, String> f = (i, s) -> i + "-f-" + s;
BiFunction<Integer, String, String> g = (i, s) -> i + "-g-" + s;
И функция h
может быть построена с использованием сокращения:
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
Если вы примените h
к 1
и "s"
, он вернет 1-f-1-g-s
.
Ответ 2
Как небольшая модификация ответа assylias: в зависимости от шаблона приложения вы также можете использовать Stream#reduce
, который принимает идентификатор в качестве первого аргумента, который в этом случае является "идентификатором BiFunction
" (фактически, проекцией на второй аргумент).
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))
}
}