一 定义
方法引用就是通过方法的名字来指向某一个方法,类似于函数指针,其好处在于代码的简洁和去冗余。其基本结构如下:
类名::方法名
::是Java8的新操作符
前面介绍过函数式接口的实例可以通过Lambda表达式和方法引用创建,下面通过案例介绍。
二 分类
方法引用的类型有静态方法引用、类名实例方法引用、实例名实例方法引用和构造方法引用。
类型 | 形式 |
---|---|
静态方法方法引用 | ClassName :: staticMethod |
类名实例方法引用 | ClassName :: instanceMethod |
实例名实例方法引用 | InstanceName :: instanceMethod |
构造方法引用 | ClassName :: constructorMethod |
三 实例介绍
静态方法引用
注意点:方法的实参就是所对应的Lambda表达式的参数
以泛型为Student类型的List排序为例
//实体类
public class Student {
private String name;
private int score;
public Student(String name, int score) {
this.name = name;
this.score = score;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getScore() {
return score;
}
public void setScore(int score) {
this.score = score;
}
}
//排序类
public class StudentComparator {
//静态方法
public static int sortByScore(Student student, Student student1) {
return student.getScore()-(student1.getScore());
}
//静态方法
public static int sortByName(Student student, Student student1) {
return student.getName().compareTo(student1.getName());
}
}
public class MethodReferenceTest {
public static void main(String[] args) {
Student student = new Student("zhangsan", 20);
Student student1 = new Student("lisi", 30);
Student student2 = new Student("wangwu", 10);
Student student3 = new Student("maliu", 50);
List<Student> studentList = Arrays.asList(student, student1, student2, student3);
//匿名类的形式
//sort是List接口的新增的默认方法,用于排序,排序的规则就是Comparator接口
studentList.sort(new Comparator<Student>() {
@Override
public int compare(Student o1, Student o2) {
return o1.getScore()-o2.getScore();
}
});
//Lambda表达式的形式
//Comparator是函数式接口,其compare就是唯一的抽象方法,代表了比较的规则
//因此Lambda表达式就是比较的规则-->该案例就是比较规则是score
//Lambda表达式的类型是 (Student,Student)->{int}
studentList.sort((item,item1)->item.getScore()-item1.getScore());
//静态方法引用的形式 类名::静态方法
//sortByScore方法与上述的Lambda表达式的类型一致:接受两个Student参数,返回一个int值
//问题点在于:并未给sortByScore方法传入参数,因为编译器帮我们做了
//参数就是Lambda表达式的参数列表
studentList.sort(StudentComparator::sortByScore);
}
}
类名实例方法引用
注意点:Lambda表达式的第一参数是方法引用的调用者,之后的参数就是方法引用中的参数。
以泛型为Student类型的List排序为例
public class Student {
private String name;
private int score;
public Student(String name, int score) {
this.name = name;
this.score = score;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getScore() {
return score;
}
public void setScore(int score) {
this.score = score;
}
public int compareByScore(Student other) {
return getScore() - other.getScore();
}
}
public class MethodReferenceTest {
public static void main(String[] args) {
Student student = new Student("zhangsan", 20);
Student student1 = new Student("lisi", 30);
Student student2 = new Student("wangwu", 10);
Student student3 = new Student("maliu", 50);
List<Student> studentList = Arrays.asList(student, student1, student2, student3);
//匿名类的形式
//sort是List接口的新增的默认方法,用于排序,排序的规则就是Comparator接口
studentList.sort(new Comparator<Student>() {
@Override
public int compare(Student o1, Student o2) {
return o1.getScore()-o2.getScore();
}
});
//Lambda表达式的形式
//Lambda表达式的类型是(Student,Student)-{int}
studentList.sort((item,item1)->item.compareByScore(item1));
//类名实例方法引用的形式
//问题在于:并未出现调用者和参数---->编译器帮我们做了
//调用者就是上述Lambda表达式的第一个参数,
//方法参数就是Lambda表达式中第一个参数之后的参数
studentList.sort(Student::compareByScore);
}
}
实例名实例方法引用
注意点:方法引用的参数就是Lambda表达式的参数
以泛型为Student类型的List遍历为例
public class MethodReferenceTest {
public static void main(String[] args) {
Student student = new Student("zhangsan", 20);
Student student1 = new Student("lisi", 30);
Student student2 = new Student("wangwu", 10);
Student student3 = new Student("maliu", 50);
List<Student> studentList = Arrays.asList(student, student1, student2, student3);
//匿名类的形式
//Consumer:接受一个参数,执行一个无结果的操作
studentList.forEach(new Consumer<Student>() {
@Override
public void accept(Student student) {
//控制台打印就是 接受一个student参数,执行一个无结果的操作
System.out.println(student);
}
});
//Lambda表达式的形式
studentList.forEach(item -> System.out.println(item));
//方法引用的形式
//方法调用者就是System.out
//问题在于:并未指出参数
//参数是Lambda表达式的参数
studentList.forEach(System.out::println);
}
}
构造方法引用
注意点:方法引用的参数就是Lambda表达式的参数
//Supplier:不接受参数,返回一个值
Supplier<String> supplier = String::new;//实际调用的是new String()方法
//Function:接受一个参数,返回一个结果
Function<String, String> function = item -> item;
Function<String, String> function1 = String::new;//实际调用的是String(String original)
Function<char[], String> function2 = String::new;//实际调用的是String(char value[])
四 小结
①方法引用本质是Lambda表达式的特殊化实现,其使用场景是Lambda表达式的的体只有一行代码,并且其实现已经有方法实现。
②一定要注意方法引用中调用者是谁,参数是谁。比如类名的实例方法引用,调用者是Lambda表达式的第一个参数,参数是Lambda表达式的第一个参数之后的参数
网友评论