We can pass lambda expressions to methods as arguments.
The following code creates a functional interface called Calculator
.
Inside the Calculator
there is a method called calculate
which
accepts two int
parameters and return an int
value.
In the Main
class there is an engine
method which accepts the
functional interface Calculator
as the parameter. And it calls the
calculate
method from the Calculator
and outputs the result.
In the main method we call the engine methods four times with different lambda expressions.
public class Main { public static void main(String[] argv) { engine((x,y)-> x + y);// w w w .j av a 2s. c om engine((x,y)-> x * y); engine((x,y)-> x / y); engine((x,y)-> x % y); } private static void engine(Calculator calculator){ int x = 2, y = 4; int result = calculator.calculate(x,y); System.out.println(result); } } @FunctionalInterface interface Calculator{ int calculate(int x, int y); }
The code above generates the following result.
The result of engine
method is depending on
lambda expressions passed into it.
The behaviour of engine method is parameterized.
Changing the behavior of a method through its parameters is called behavior parameterization.
In behavior parameterization we pass logic encapsulated in lambda expressions to methods as if was data.
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.
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); }/* w ww . java 2 s . com*/ 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.
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); }/* w w w . java 2 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.
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 www .java2s . c om*/ 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.