具有多个参数的Java 8的功能

时间:2018-08-09 19:46:01

标签: java lambda java-8

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

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

当然,您可以像f2那样延伸主体:

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

但是我无法找到一种方法来定义具有可变数量的f3等参数的lambda:

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

或不带参数的f4

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

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

3 个答案:

答案 0 :(得分:12)

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

实际上是BiFunction<Integer,Integer,Integer>

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

Supplier<Double>

如果您需要 more 创建自己的文件,例如TriFunction<Integer,Integer,Integer,Integer>

答案 1 :(得分:5)

  

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

除了Eugene答案,我还要补充一点:

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

可以被视为BiFunction<Integer,Integer,Integer>或简称为BinaryOperator<Integer>。 请注意,您对lambda主体中的Integer执行了算术运算。这些操作产生拆箱和装箱操作:Integer->int->Integer。因此,在本使用案例中,鼓励您使用专门的功能接口,以防止以下情况:功能签名为IntBinaryOperator的{​​{1}}本身是(int, int)-> int的专业化,而{{1 }}

以与保留自动装箱操作相同的逻辑:  BinaryOperator<T>应该是BiFunction<T,T,T> 并且Function<Integer,Integer> f2应该是IntFunction f2

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

例如,您可以声明此接口:

Supplier<Double> f4

但是在不委托给接受var-args的方法的情况下更难使用:

DoubleSupplier f4

答案 2 :(得分:2)

带有两个参数的函数是BiFunction

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

不带参数的函数是Supplier

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

或等效地:

Supplier<Double> f4 = Math::random;