方法引用:
在某些场景之下,Lambda表达式要做的事情,其实在另一个地方已经写过了。
那么此时如果通过Lambda表达式重发编写相同代码,就是浪费。
那么如何才能复用已经存在的方法逻辑呢?
如果Lamda表达式需要做的事情,在另外一个类当中已经做过了,那么可以直接拿过来替换Lambda
一.通过 类名称 引用 静态方法 :
类名称::静态方法名
事先存在一个Cook类:
public class Cook {
//这是一个静态方法,可以通过类名称进行调用
public static void makeFood(String food) {
System.out.println("将" + food + "做成可口饭菜");
}
}
现在要用保姆接口来打印输出跟Cook方法一样的工作:
//保姆接口
@FunctionalInterface
public interface Sitter {
//工作,将食材做为熟饭
public abstract void work(String food);
}
这里可以使用方法引用,通过类名称引用静态方法:
public class Lambda {
public static void main(String[] args) {
//使用Lambda
hireSitter(food -> System.out.println("将" + food + "做成可口饭菜"));
//方法引用,简化Lambda
hireSitter( Cook::makeFood );
}
// 雇佣一个保姆去做饭
public static void hireSitter(Sitter sitter) {
sitter.work("白菜");
}
}
1.1通过 类名称 引用 静态方法 举例:
做一个计算器函数式接口,求出数字的绝对值:
方法引用格式:
类名称::静态方法名
//计算器函数式接口
@FunctionalInterface
public interface Calculator {
//抽象方法作用:求绝对值
int getAbs(int num);
}
JDK当中已经给我们提供好了一个java.lang.Math类,其中有一个静态方法abs就可以实现求绝对值的功能。
既然Math.abs方法已经存在,那么就没有必要再用Lambda再写一遍。
就可以通过方法引用,直接拿过来用。
public class Abs {
public static void main(String[] args) {
// 使用Lambda表达式
method((int num) -> {
int result;
if (num>=0) {
result = num;
}else {
result = -num;
}
return result;
});
// 方法引用的意义:Math类当中有一个abs静态方法,已经有了现成的功能,直接拿过来用
method(Math::abs);
}
public static void method(Calculator cal) {
int result = cal.getAbs(-25);
System.out.println("结果是"+result);
}
}
二.通过 对象名 引用 成员方法
通过对象引用成员方法,格式:
对象名::成员方法名
存在的方法Cook:
public class Cook {
//成员方法,必须要有对象才能调用
public void makeFood(String food) {
System.out.println("将" + food + "做成可口的饭菜");
}
}
新建的接口Sitter:
public interface Sitter {
public abstract void work(String food);
}
新的主类:
public class MethodRef {
public static void main(String[] args) {
//Lambda
method(food -> System.out.println("将" + food + "做成可口的饭菜"));
//方法引用
Cook cook = new Cook(); //创建了一个对象
//引用了cook对象当中的成员方法makeFood
method( cook::makeFood );
}
public static void method(Sitter sitter) {
sitter.work("土豆");
}
}
2.1对象引用成员方法举例:
功能为打印参数:
@FunctionalInterface
public interface Monitor {
//将参数打印显示出来
void show(String str);
}
public class Moniter {
public static void main(String[] args) {
//首先使用Lambda,间接调用println方法
Prt( str -> System.out.println(str) );
//对象引用,直接交给了println方法引用去处理
Prt( System.out::println );
}
public static void Prt(Monitor mon) {
mon.show("HelloWorld");
}
}
既然Lambda就是拿到参数,原封不动的交给println去使用。
那么为什么不能直接交给println,而中间不用Lambda?
Lambda在这种场景中要做的事情,就是打印,而打印功能在println当中已经有了。
这时候,可以使用方法引用。
System.out其实就是JDK当中一个已经创建好的对象,而println就是System.out对象当中的成员方法
对象名::成员方法名
System.out::println
小结:
1.一定要有函数式接口,才能使用Lambda。
2.对应重复的Lambda场景,可以使用方法引用来进行简化。