双函数的组合

14

我有一串BiFunction流,我想将其缩减为单个的BiFunction。

更具体地说,我有一串BiFunction流。

BiFunction<x,y,y>

其中 x 和 y 表示参数的类型。

假设我有两个函数

f (x, y) -> y
g (x, y) -> y

我希望将它们组合成函数。

h(x, y) -> f(x, g(x, y))

在Java 8中是否可能使用流(Stream)实现此功能?如果不行,除了遍历所有可用的函数并以另一种方式组合它们之外,有什么更优雅的方法吗?


1
你需要寻找Stream.reduce,然后给它一个lambda函数,该函数接受f和g并返回h。 - Louis Wasserman
2个回答

14

使用 x=Integery=String,你可以定义 fg 如下:

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
请注意,Stream.of(f, g).reduce((f_, g_) -> ... 是多余的,但在这种情况下,它允许您将其推广到两个以上的输入函数。 - user253751
3
没问题,那就这样吧——只需这两个函数,就不需要使用流。 - assylias

8
作为 assylias的答案 的轻微修改:根据应用程序模式,您还可以使用接受 identity 作为第一个参数的 Stream#reduce 方法,在这种情况下,它是 "identity 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))
    }
}

除了我们可以省略 get() 调用之外,是否还有其他优点超过已接受的答案? - lup3x
3
视情况而定:如果您想提供类似于 BiFunction<X,Y,Z> compose(Stream<BiFunction<X,Y,Z>> stream) 的函数,则可能不知道流是否为空。因此,您需要首先检查Optional以查看它是否为空。我认为在这种情况下使用“恒等”函数是合理且方便的。 - Marco13

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接