方法引用是Lambda表达式的一种简化写法,用于直接引用已有方法。当Lambda表达式仅仅是调用一个已有方法,可以使用更加简洁的方法引用语法。
1、静态方法引用
类名::静态方法
// Lambda表达式
(args) -> 类名.静态方法名(args)
// 静态方法引用
类名::静态方法名
使用场景:如果Lambda表达式中只是调用1个静态方法,并且"------>"前后参数形式一致,就可以使用静态方法引用。
什么时候用?当程序中有且仅能出现这样的形式:x------>f(x), (x,y)------>f(x,y)。f是类名.静态方法,此时可以把参数省略,f的形式修改为类名::静态方法名,或者说整体简化为类名::静态方法名。
// Lambda表达式
Function<Double, Double> lambda2 = x -> Math.sqrt(x);
UnaryOperator<Double> lambda3 = x -> Math.abs(x);
// 静态方法引用
Function<Double, Double> reference2 = Math::sqrt;
UnaryOperator<Double> reference3 = Math::abs;
// 使用
System.out.println(reference2.apply(25.0)); // 5.0
System.out.println(reference3.apply(-10.5)); // 10.5
2、实例方法引用
对象名::实例方法
如果某个Lamda表达式只是通过对象名称调用一个实例方法,并且"------>"前后的参数形式一致,就可以使用实例方法引用。
什么时候用?当程序中有且仅能出现这样的形式:x------>f(x), (x,y)------>f(x,y)。f是对象名.实例方法,此时可以把参数省略,f的形式修改为对象名::实例方法名,或者说整体简化为对象名::实例方法名。
package com.ljh.methodreference1;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Student {
private String name;
private int age;
private double height;
private char sex;
//Student类的实例方法,属于Student对象
public int compareByHeight(Student o1, Student o2){
//return Double.compare(o1.getHeight(), o2.getHeight());
if(o1.getHeight()- o2.getHeight()<0){
return -1;
} else if (o1.getHeight()-o2.getHeight()>0) {
return 1;
}
else {
return 0;
}
}
}
package com.ljh.methodreference1;
import java.util.Arrays;
public class Demo2 {
public static void main(String[] args) {
//实例方法引用
//目标:完成给数组排序,理解其中匿名内部类的用法
//准备一个学生类型的数组,存放4个学生对象
Student[] students = new Student[6];
students[0] = new Student("张三",34,165,'男');
students[1] = new Student("李四",33,155,'男');
students[2] = new Student("王五",48,175,'男');
students[3] = new Student("赵六",29,165,'女');
students[4] = new Student("赵敏",18,170,'女');
students[5] = new Student("张蓝",42,158,'男');
Student t = new Student();
//Arrays.sort(students, ((o1, o2) -> t.compareByHeight(o1,o2)));
Arrays.sort(students,t::compareByHeight);
//遍历数组中的学生对象并输出
for (int i = 0; i < students.length; i++) {
System.out.println(students[i]);
//默认重写toString方法,在学生类中重写了toString方法
}
}
}
3、特定类的方法引用
特定类的名称::方法
如果某个Lambda表达式只是调用一个特定类型(如字符串类型)的实例方法,并且前面参数列表中的第一个参数是作为方法的主调,后面的所有参数是作为该实例方法入参的,则此时可以使用特定类型的方法引用。
package com.ljh.methodreference1;
import java.util.Arrays;
import java.util.Comparator;
public class Demo3 {
public static void main(String[] args) {
//目标:特定类型的方法引用
//需求:有一个字符串数组,里面有有些人的名字,请按照名字的首字母排序
String[] names ={"Tom", "Jerry", "Mike", "Jack","Rose","angela","Anna", "Bob","曹操"};
//Arrays.sort(names);
//要求:忽略首字母的大小进行排序,(JAVA官方是不能的,需要我们自己指定比较规则)
//Arrays.sort(names, (o1,o2) -> o1.compareToIgnoreCase(o2));//java为我们提供了字符串按照首字母忽略大小写比较的方法:compareToIgnoreCase(02);
Arrays.sort(names, String::compareToIgnoreCase);
System.out.println(Arrays.toString(names));
}
}
4、构造器引用
类名::new
如果某个Lambda表达式只是在创建对象,并且------>前后参数情况一致,就可以使用构造器引用。