简介
-
方法引用是Lambda的特殊实现,所以只有函数式接口可以引用方法
-
它只是一个语法糖,对语言本身没有太大意义
-
总之,就是借用已经存在的方法,无需再手动写Lambda表达式了
-
它有四种引用方式
1、静态方法引用
顾名思义就是引用静态的方法
- 格式
类名::静态方法名
样例,根据不同的属性给对象排序
- 创建一个Student类
public class Student {
String name;
int score;
public static int compareByScore(Student stu1,Student stu2){//静态方法1
return stu1.getScore()-stu2.getScore();
}
public static int compareByName(Student stu1,Student stu2){//静态方法
return stu2.getName().compareTo(stu1.getName());//会倒序
}
public Student(String name, int score) {
this.name = name;
this.score = score;
}
//getter和setter方法。。。
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", score=" + score +
'}';
}
}
- 测试
public class Test {
public static void main(String[] args) {
Student student = new Student("张三",78);
Student student2 = new Student("李四",90);
Student student3 = new Student("王五",50);
Student student4 = new Student("赵六",77);
Student student5 = new Student("钱七",100);
List<Student> studentList = Arrays.asList(student,student2,student3,student4,student5);
//studentList.sort((s1,s2) -> s1.getScore() - s2.score); //正常的Lambda,以score排序
//集合自带sort(函数式接口Comparator<T>),需要实现的是int compare(T o1, T o2);方法
studentList.sort(Student::compareByScore);//因为Student类中已经有实现了,直接引用
studentList.forEach(s -> System.out.println(s));//打印
System.out.println("----------------");
studentList.sort(Student::compareByName);
studentList.forEach(s -> System.out.println(s));
}
}
2、实例方法引用
- 格式
引用名(对象名)::实例方法名
样例,前一个样例的变体
- 新创建一个有compare方法的类,方法不再是静态
public class StudentComparetor {
public int compareByScore(Student stu1,Student stu2){//非静态,按分数正序
return stu1.getScore()-stu2.getScore();
}
public int compareByName(Student stu1,Student stu2){//非静态,按名字倒序
return stu2.getName().compareTo(stu1.getName());
}
}
测试
public class Test {
public static void main(String[] args) {
StudentComparetor comparetor = new StudentComparetor();//实例化刚创建的类StudentComparetor
Student student = new Student("张三",78);
Student student2 = new Student("李四",90);
Student student3 = new Student("王五",50);
Student student4 = new Student("赵六",77);
Student student5 = new Student("钱七",100);
List<Student> studentList = Arrays.asList(student,student2,student3,student4,student5);
//studentList.sort((s1,s2) -> s1.getScore() - s2.score);//正常的lambda表达式
studentList.sort(comparetor::compareByScore);//引用了对象comparetor的方法
studentList.forEach(s -> System.out.println(s));
System.out.println("----------------");
studentList.sort(comparetor::compareByName);
studentList.forEach(s -> System.out.println(s));
}
}
结果同上
3、实例方法引用2.0
- 格式
类名::方法名
样例,在前面的Student类中compareByScore
方法改了
public int compareByScore(Student stu){ //参数只有一个
return this.getScore()-stu.getScore();//当前对象调用,使用一个参数
}
测试,依旧是排序
studentList.sort((s , s1) ->s.compareByScore(s1));
studentList.sort(Student::compareByScore);//和上面lambda表达式是等价的
4、构造方法引用
构造方法的返回值是对象
测试
public class Test {
public String getString(Supplier<String> supplier){
return supplier.get()+"getString from No-parameter construction";
}
public String getString2(String str,Function<String, String> function){
return function.apply(str);
}
public static void main(String[] args) {
Test test = new Test();
//使用String的无参构造实现supplier.get(),因为get的返回值是String
System.out.println(test.getString(String::new));
//使用String的有参构造,返回String,因为function.apply(str);参数和返回值与String的有参构造一致
System.out.println(test.getString2("hello world",String::new));
}