Behavior parameterization Ambiguity
Description
It is not always possible for the compiler to infer the type of a lambda expression.
One such situation is passing lambda expressions to overloaded methods.
Example
There are two functional interfaces in the following code. One is for int
value
calculation and the other is for long
value.
In the Main class there are overloaded methods called engine
. One is expecting
IntCalculator
and another is for LongCalculator
.
In the main method we have to indicate the parameters for lambda expression to indicate compiler which overloaded function we want to use.
public class Main {
public static void main(String[] argv) {
engine((int x,int y)-> x + y);
engine((long x, long y)-> x * y);
engine((int x,int y)-> x / y);
engine((long x,long y)-> x % y);
}/*from ww w. j a va2 s .c o m*/
private static void engine(IntCalculator calculator){
int x = 2, y = 4;
int result = calculator.calculate(x,y);
System.out.println(result);
}
private static void engine(LongCalculator calculator){
long x = 2, y = 4;
long result = calculator.calculate(x,y);
System.out.println(result);
}
}
@FunctionalInterface
interface IntCalculator{
int calculate(int x, int y);
}
@FunctionalInterface
interface LongCalculator{
long calculate(long x, long y);
}
The code above generates the following result.
Note 1
To resolve the ambiguity we can change the implicit lambda expression to explicit by specifying the type of the parameters. This is what has been done for the code above.
Or we can use a cast as follows. When calling the engine the first time we cast the lambda
expression to IntCalculator
.
public class Main {
public static void main(String[] argv) {
engine((IntCalculator) ((x,y)-> x + y));
engine((long x, long y)-> x * y);
engine((int x,int y)-> x / y);
engine((long x,long y)-> x % y);
}/*from w w w . j av a 2 s. co m*/
private static void engine(IntCalculator calculator){
int x = 2, y = 4;
int result = calculator.calculate(x,y);
System.out.println(result);
}
private static void engine(LongCalculator calculator){
long x = 2, y = 4;
long result = calculator.calculate(x,y);
System.out.println(result);
}
}
@FunctionalInterface
interface IntCalculator{
int calculate(int x, int y);
}
@FunctionalInterface
interface LongCalculator{
long calculate(long x, long y);
}
The code above generates the following result.
Note 2
Or we can avoid using the lambda expression directly as the parameter. We can assign the lambda expression to a functional interface, and then pass the variable to the method. The following code shows this technique.
public class Main {
public static void main(String[] argv) {
IntCalculator iCal = (x,y)-> x + y;
engine(iCal);/*from w w w . ja va 2 s. co m*/
engine((long x, long y)-> x * y);
engine((int x,int y)-> x / y);
engine((long x,long y)-> x % y);
}
private static void engine(IntCalculator calculator){
int x = 2, y = 4;
int result = calculator.calculate(x,y);
System.out.println(result);
}
private static void engine(LongCalculator calculator){
long x = 2, y = 4;
long result = calculator.calculate(x,y);
System.out.println(result);
}
}
@FunctionalInterface
interface IntCalculator{
int calculate(int x, int y);
}
@FunctionalInterface
interface LongCalculator{
long calculate(long x, long y);
}
The code above generates the following result.