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.





















Home »
  Java Lambda »
    Java Lambda Tutorial »




Java Lambda Tutorial