BiFunction 接口中的默认 andThen() 方法

Default andThen() method in BiFunction interface

BiFunction 接口(java.util.function 包)中有一个默认方法 andThen()

default <V> BiFunction<T,U,V> andThen(Function<? super R,? extends V> after)

文档说:

Returns a composed function that first applies this function to its input, and then applies the after function to the result. If evaluation of either function throws an exception, it is relayed to the caller of the composed function.

不难理解解释的意思。根据我的理解,调用默认 andThen() 方法时会返回一个组合函数。此组合函数在 TU 类型上调用,returns 类型 V。最后,after 函数在 RV.

类型上调用

这个方法有什么用?它实际上如何适合图片?

考虑 f1.andThen(f2) :

  1. 首先,f1 将取 2 个元素,结果只有 1 个
  2. 之后,f2 将取 f1 的结果并将其转换为另一个结果
BiFunction<Integer, Integer, Integer> plus10 = (i1, i2) -> i1 + i2 + 10;

Function<Integer, Integer> mult = i -> i * 5;

System.out.println(plus10.andThen(mult).apply(5, 6)); // (5+6+10) *5 = 105

这是一种减少计算量的方法

int val1 = plus10.apply(5, 6);
int res1 = mult.apply(val1);

int res2 = plus10.andThen(mult).apply(5, 6);
System.out.println(res1 == res2);            //true

当你有多个函数要使用时,它会越来越有用,因为 Function 有相同的 method,所以你可以将它们链接起来:

System.out.println(plus10.andThen(mult).andThen(mult).andThen(mult).apply(5, 6)); 
// (5+6+10)*5*5*5 = 2625

举个例子更容易理解:

BiFunction<Integer, Integer, String> f = 
        (n1, n2) -> String.format("result is %s", n1+n2);

而 "composed function" 是:

BiFunction<Integer, Integer, String> f1 = 
        f.andThen(string -> string.toUpperCase());

请注意,第二个函数仍然采用与第一个函数相同的参数类型,尽管它在内部只需要一个字符串来执行其逻辑。

考虑调用:

System.out.println(f1.apply(2, 3));

输出RESULT IS 5,即:它调用第一个函数,然后用第一个函数的结果调用第二个函数。所以简单理解为f1(f(x, y)),最终的输入就是f需要的输入,最终的结果就是f1.

产生的结果

我认为 andThen 函数的主要目的是使您的代码更具可读性和功能性。

让我们来看一个例子:

BiFunction<Integer, Integer, Integer> add = (x, y) -> x + y;
Function<Integer, Integer> negate = x -> -x;
BiFunction<Integer, Integer, Integer> newFunction = add.andThen(negate);

猜猜 newFunction 是做什么的?它然后求反两个数!看看这行和英文有多相似:

BiFunction<Integer, Integer, Integer> newFunction = add.andThen(negate);

如果你调用 .apply(1, 2),你知道你会得到 -3。

当然,您可以不使用 andThen:

BiFunction<Integer, Integer, Integer> newFunction = (x, y) -> negate.apply(add.apply(x, y))

但看看那是多么难读!

功能性编码有时可以使事情更容易阅读和理解。

It's little confusing to understand what the explanation means.

为了尽可能简单地解释,方法 andThen returns 函数首先将给定函数应用于输入,然后将另一个函数应用于该应用程序的结果。

假设我们有两个函数 fg ,函数 f 做一些逻辑和函数 g 做一些其他类型的逻辑所以当你写 f.andThen(g) 本质上意味着 g(f(x)) 即我们首先应用作为参数给出的函数 f(x) 然后将函数 g 应用到结果。

示例:

BiFunction<Integer, Integer, Integer> f = Math::addExact; 
Function<Integer, Integer> g = e -> e * 2; 
System.out.println(f.andThen(g).apply(10,10)); // 40

我们首先调用函数f(10, 10),然后取出20的结果,将其传递给函数g(20),然后将20乘以2 因此产生 40.

老实说,在 Java 中调用函数的语法并不是最好的,所以我可以理解,当有人第一次看这个时,它可能很难掌握并且更难理解你编写的函数越多,例如在 C# 中,你可以简单地做 g(f(10, 10)) ,这样看起来更容易理解、阅读和理解。

What's the need of this method? How does it actually fit in the picture?

根据我的经验,我编写如上所示的函数并不常见,但我可以想象的一个典型场景是,如果你有各种实用方法来执行一些逻辑,其中一个函数的结果进一步传递给另一个用于处理的函数,在这种情况下,您可以使用函数组合通过组合实用方法来创建各种转换管道。