Java Lambda行为参数化
我们可以将lambda表达式作为参数传递给方法。
例子
以下代码创建了一个名为Calculator的函数接口。
在Calculator中有一个称为calculate的方法,它接受两个int参数并返回一个int值。
在Main类中有一个引擎方法,它接受函数接口Calculator作为参数。它从计算器调用计算方法并输出结果。
在主方法中,我们用不同的lambda表达式调用引擎方法四次。public class Main {
public static void main(String[] argv) {
engine((x,y)-> x + y);
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);
}
上面的代码生成以下结果。
注意
engine方法的结果取决于传递给它的lambda表达式。
引擎方法的行为被参数化。
通过其参数更改方法的行为称为行为参数化。
在行为参数化中,我们将在lambda表达式中封装的逻辑传递给数据的方法。
行为参数化模糊性
编译器并不总是可以推断lambda表达式的类型。
一种情况是将lambda表达式传递给重载的方法。
在以下代码中有两个函数接口。 一个是int值计算,另一个用于long值。
在Main类中有称为engine的重载方法。 一个是期望IntCalculator,另一个是LongCalculator。
在main方法中,我们必须指定lambda表达式的参数,以指示我们要使用的重载函数的编译器。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);
}
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);
}
上面的代码生成以下结果。
注意1
要解决歧义,我们可以通过指定参数的类型将隐式lambda表达式更改为explicit。这是为上面的代码做的。
或者我们可以使用cast如下。当第一次调用引擎时,我们将lambda表达式转换为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);
}
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);
}
上面的代码生成以下结果。
注意2
或者我们可以避免直接使用lambda表达式作为参数。我们可以将lambda表达式分配给一个函数接口,然后将该变量传递给该方法。下面的代码显示了这种技术。public class Main {
public static void main(String[] argv) {
IntCalculator iCal = (x,y)-> x + y;
engine(iCal);
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);
}
上面的代码生成以下结果。