前言:
方法引用是Lambda表达式的快捷语法,返回的函数式接口的实例,而Lambda表达式可理解为匿名函数的简洁写法。
当Java8中没有与我们所写的Lambda表达式签名一致的函数式接口时,可以通过自定义函数式接口来解决。
一、概念
1.方法引用是通过目标引用和方法名称来指向一个方法,是Lambda表达式的一种快捷写法
目标引用:要使用的类
方法名称:要引用的方法的名称
注意: 方法引用只是Lamdba表达式的一种快捷写法,没有实际调用方法;
方法引用关注的是“用名称直接调用方法” 而不是 “如何实际调用方法”
所以,我们只需要知道方法名称,而不需要关注入参,写法上也只需要方法名称,()及参数都不需要
二、语法
2.1语法及分类
目标引用 :: 方法名称
构造方法引用: Class :: new 或 Class<T> :: new
静态方法引用: Class :: static-method-name
类的任意对象方法引用: Class :: method-name
指定对象方法引用: instance :: method-name
Lamdda及等效方法引用例子
(Apple a) -> a.getWeight() Apple :: getWeight
() -> Thread.currentThread().dumpStack() Thread.currentThread() :: dumpStack
(str,i) -> str.substring(i) String :: substring
(String s) -> System.outprintln(s) System.out :: println
#注意:此处验证了概念中,我们只关注用方法名称做引用,而不是实际调用,因此不关注入参
2.2构造方法引用
2.2.1 空参构造函数 () -> T 对应Supplier函数式接口 get抽象方法
Suppliter<Apple> sup = Apple :: new;
Apple apple = sup.get();
2.2.2 单参数构造函数 T -> R 对应Function函数式接口 apply抽象方法
Function<String,Apple> function = Apple :: new;
Apple apple = function.apply("red");
2.2.3 多参构造函数 (T,F,V...) -> R 如果没有已有的函数式接口相对应,就自定义
public interface AppleFunction<T,F,V,R> {
R apply(T t,F f,V v);
}
AppleFunction<String,int,String> function = Apple :: new;
function.apply("red",20,"Lambda");
三、Lambda和方法引用实战
在这里,我们实现以下 用不同的属性,给苹果进行排序
1、行为参数化 传递代码
使用List的sort方法,需要传入一个Comparator接口
void sort(Comparator<? super E> c)
public class AppleComparator implements Comparator<Apple> {
public int compare(Apple a1,Apple a2) {
return a1.getWeight().compareTo(a2.getWeight());
}
}
list.sort(new AppleComparator());
2、使用匿名类
list.sort(new AppleComparator<Apple>(){
public int compare(Apple a1,Apple a2) {
return a1.getWeight().compareTo(a2.getWeight());
}
});
3、使用Lambda表达式
list.sort((Apple a1,Apple a2) -> a1.getWeight().compareTo(a2.getWeight()) );
Java通过编译器进行类型推导
list.sort((a1, a2) -> a1.getWeight().compareTo(a2.getWeight()) );
Comparator的静态方法comparing 通过接收一个Function函数式接口来提取排序键,返回Comparator
list.sort(Comparator.comparing(a -> a.getWeight));
4、使用方法引用
Function的函数接口可以通过方法引用来获取
list.sort(Comparator.comparing(Apple :: getWeight));