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

2022-09-01 20:27:20

我阅读了许多关于如何在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);};

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

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

或没有参数,如:f4

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

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


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

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

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

是一个Supplier<Double>

如果你需要更多的创建自己的,比如TriFunction<Integer,Integer,Integer,Integer>


答案 2

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

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

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

可视为 或 简称 为 。请注意,您使用 lambda 主体中的 s 执行算术计算。这些产生拆箱和装箱操作:。因此,在此用例中,我们鼓励您使用专用的功能接口来防止这种情况:功能签名本身就是BiFunction<Integer,Integer,Integer>BinaryOperator<Integer>IntegerInteger->int->IntegerIntBinaryOperator(int, int)-> intBinaryOperator<T>BiFunction<T,T,T>

在保留自动装箱操作的相同逻辑中:应该是并且应该是 。Function<Integer,Integer> f2IntFunction f2Supplier<Double> f4DoubleSupplier 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) {
    ...
}

推荐