我阅读了许多有关如何在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()};
我几乎可以肯定,您可以定义自己的功能接口(即,共同创建一个新文件)来开发f3
和f4
,但是有什么方法可以轻松地定义它们?
答案 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;