Jason Ni
Jason Ni

Reputation: 159

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);
}

Why does the following code not work?

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));

Upvotes: 2

Views: 1783

Answers (1)

Radiodef
Radiodef

Reputation: 37845

JLS 9.8 says this (paraphrased):

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

Since MathOperation has more than one method, it cannot be created with a lambda expression.

Why can't that be? Well, because if we did this:

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

What should happen, since we did not supply a definition of operation2?


Use of the @FunctionalInterface annotation will warn you of this, similar to how the @Override annotation works:

/* 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);
}

A more canonical definition of your sample code would be:

@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 supplies a binary int operation, java.util.function.IntBinaryOperator, but not a ternary operation, so we need to define our own.

Upvotes: 3

Related Questions