【问题标题】:Function.Function of Java 8 with multiple parameters [duplicate]具有多个参数的Java 8的Function.Function [重复]
【发布时间】:2018-08-09 19:46:01
【问题描述】:

我阅读了许多关于如何在 Java 8 中轻松定义 lambda 的示例。这个 lambda 始终采用一个参数,例如 f1

Function<Integer,Integer> f1 = (x) -> Math.pow(x,2);

当然,你可以像f2一样扩展body:

Function<Integer,Integer> f2 = (x) -> {if (x < 0)  return 0;
                                       else return Math.pow(x,2);};

但我找不到一种方法来定义具有可变数量参数的 lambda,例如 f3

Function<Integer,Integer,Integer> f3 = (x,y) -> {return x + y};

或不带参数如f4:

Function<Double> f4 = () -> {return Math.random()};

我几乎可以肯定你可以定义自己的功能接口(即通常创建一个新文件)来开发f3f4,但是有什么方法可以轻松定义它们吗?

【问题讨论】:

    标签: java lambda java-8


    【解决方案1】:
    Function<Integer,Integer,Integer> f3 = (x,y) -> {return x + y};
    

    其实是BiFunction&lt;Integer,Integer,Integer&gt;

    Function<Double> f4 = () -> {return Math.random()};
    

    Supplier&lt;Double&gt;

    如果您需要更多创建自己的,例如TriFunction&lt;Integer,Integer,Integer,Integer&gt;

    【讨论】:

    • 或者,如果所有参数都是同一类型,则创建一个可变参数版本:interface NAryFunction&lt;T, R&gt; { R apply(T... t); }
    • @Andreas 我没有故意暗示,我从来没有发现自己需要一个,所以不确定。不过谢谢你
    【解决方案2】:

    我几乎可以肯定您可以定义自己的功能接口(即, 通常创建一个新文件)来开发f3和f4,但是有没有 如何轻松定义它们?

    除了尤金的回答,我还要补充一点:

    Function<Integer,Integer,Integer> f3 = (x,y) -> {return x + y};
    

    可被视为BiFunction&lt;Integer,Integer,Integer&gt; 或简称为BinaryOperator&lt;Integer&gt;。 请注意,您使用 lambda 主体中的 Integers 执行算术计算。这些产生拆箱和装箱操作:Integer-&gt;int-&gt;Integer。因此,在这个用例中,鼓励您使用专门的功能接口来防止:IntBinaryOperator,其功能签名是 (int, int)-&gt; int,它本身就是 BinaryOperator&lt;T&gt; 的特化BiFunction&lt;T,T,T&gt; 的子类

    在保留自动装箱操作的相同逻辑中: Function&lt;Integer,Integer&gt; f2 应该是 IntFunction f2 Supplier&lt;Double&gt; f4 应该是 DoubleSupplier f4

    还要注意,指定特定数量的参数是有意义的,因为它可以直接在 lambda 主体中使用,但指定类似 var-args 的东西是可能的,但通常更难利用。

    例如你可以声明这个接口:

    @FunctionalInterface
    public interface VargsFunction<T,R> {
        @SuppressWarnings("unchecked")
        R apply(T...  t);
    }
    

    但如果不委托给接受 var-args 的方法,则更难使用:

    VargsFunction<Integer, Integer> f = varg-> call(varg);
    
    Integer call(Integer... varg) {
        ...
    }
    

    【讨论】:

      【解决方案3】:

      接受两个参数的函数是BiFunction

      BiFunction<Integer, Integer, Integer> f3 = (x, y) -> x + y;
      

      不带参数的函数是Supplier

      Supplier<Double> f4 = () -> Math.random();
      

      或等效:

      Supplier<Double> f4 = Math::random;
      

      【讨论】:

        猜你喜欢
        • 2014-09-06
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-02-01
        • 2016-03-21
        • 2011-07-30
        相关资源
        最近更新 更多