【问题标题】:Default andThen() method in BiFunction interfaceBiFunction 接口中的默认 andThen() 方法
【发布时间】:2018-04-28 08:45:09
【问题描述】:

BiFunction 接口(@98​​7654323@ 包)中有一个默认方法andThen()

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

文档说:

返回一个组合函数,该函数首先将此函数应用于其输入,然后将 after 函数应用于结果。如果任一函数的求值引发异常,则会将其转发给组合函数的调用者。

理解解释的含义有点令人困惑。据我了解,调用默认的andThen() 方法时会返回一个组合函数。这个组合函数在类型TU 上调用,返回类型V。最后,还有在 RV 类型上调用的 after 函数。

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

【问题讨论】:

    标签: java java-8 function-composition


    【解决方案1】:

    理解解释的含义有点令人困惑。

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

    假设我们有两个函数 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)),这在视觉上更容易理解、阅读和理解。

    这个方法有什么需要?它实际上如何适应 图片?

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

    【讨论】:

    • 或通过柯里化的类型安全构建器
    • 怎么来的?没关注你
    • @Eugene 我的意思是关于 Java-8、java-stream 的问题。
    • 哦,我猜,我现在才开始看... :)
    【解决方案2】:

    我认为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))
    

    但是看看那是多么难以理解!

    函数式编码有时可以使事情更容易阅读和理解。

    【讨论】:

      【解决方案3】:

      考虑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
      

      当你有几个函数要使用时,它会越来越有用,因为Functionmethod是相同的,所以你可以链接它们:

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

      【讨论】:

        【解决方案4】:

        举个例子更容易理解:

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

        而“组合函数”是:

        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产生的结果。

        【讨论】:

          猜你喜欢
          • 2019-01-28
          • 2019-11-14
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2019-04-20
          • 1970-01-01
          • 1970-01-01
          • 2018-06-13
          相关资源
          最近更新 更多