Lambda 从一个接口调用两个函数

Lambda call two functions from one interface

interface MathOperation{
    int operation1(int a, int b);
    int operation2(int c, int d, int e);
}

public static int operate1(int a, int b, MathOperation mathOperation){
    return mathOperation.operation1(a, b);
}

public static int operate2(int a, int b, int c, MathOperation mathOperation){
    return mathOperation.operation2(a, b, c);
}

为什么下面的代码不起作用?

System.out.println("5 - 3 = " + operate1(5, 3, (a,b)->a-b));
System.out.println("5 + 3 + 4 = " + operate2(5, 3, 4, (a,b,c)->a+b+c));

JLS 9.8 是这样说的(释义):

A functional interface is an interface that has just one abstract method. Instances of functional interfaces can be created with lambda expressions.

由于MathOperation有多个方法,不能用lambda表达式创建。

为什么不能呢?好吧,因为如果我们这样做:

operate2( 1, 2, 3, ( (a, b) -> a + b ) );

应该怎么办,因为我们没有提供 operation2 的定义?


使用 @FunctionalInterface annotation will warn you of this, similar to how the @Override 注释有效:

/* causes a compilation error because
   MathOperation is not a functional interface */
@FunctionalInterface
interface MathOperation {
    int operation1(int a, int b);
    int operation2(int c, int d, int e);
}

您的示例代码的更规范的定义是:

@FunctionalInterface
public interface IntTernaryOperator {
    int applyAsInt(int a, int b, int c);
}

public static int operate1(
    int a, int b,
    IntBinaryOperator op
) {
    return op.applyAsInt(a, b);
}

public static int operate2(
    int a, int b, int c,
    IntTernaryOperator op
) {
    return op.applyAsInt(a, b, c);
}

JSE 提供二进制 int 运算,java.util.function.IntBinaryOperator,但不提供三元运算,因此我们需要自己定义。