lambda表达式用于创建匿名方法。它什么也不做,只是调用一个现有的方法,但是直接引用方法的名称会更清楚。方法引用允许我们使用方法引用操作符::来实现。
考虑下面的简单类,其中每个员工都有姓名和级别。
public class Employee {
private String name;
private String grade;
public Employee(String name, String grade) {
this.name = name;
this.grade = grade;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getGrade() {
return grade;
}
public void setGrade(String grade) {
this.grade = grade;
}
}
假设我们有一个由某个方法返回的员工列表,并且我们希望根据员工的等级对其进行排序。我们知道我们可以使用匿名类作为:
List<Employee> employeeList = getDummyEmployees();
// Using anonymous class
employeeList.sort(new Comparator<Employee>() {
@Override
public int compare(Employee e1, Employee e2) {
return e1.getGrade().compareTo(e2.getGrade());
}
});
其中getDummyEmployee()是一个方法,如下:
private static List<Employee> getDummyEmployees() {
return Arrays.asList(new Employee("Carrie", "C"),
new Employee("Fanishwar", "F"),
new Employee("Brian", "B"),
new Employee("Donald", "D"),
new Employee("Adam", "A"),
new Employee("Evan", "E")
);
}
现在我们知道Comparator是一个功能接口。函数式接口是只有一个抽象方法的接口(尽管它可能包含一个或多个默认方法或静态方法)。Lambda表达式提供了@FunctionalInterface的实现,因此函数接口只能有一个抽象方法。我们可以这样使用lambda表达式:
employeeList.sort((e1,e2) -> e1.getGrade().compareTo(e2.getGrade())); // Lambda expression
看起来一切都很好,但是如果Employee类也提供类似的方法呢?
public class Employee {
private String name;
private String grade;
// getter and setter
public static int compareByGrade(Employee e1, Employee e2) {
return e1.grade.compareTo(e2.grade);
}
}
在这种情况下,使用方法名本身会更清楚。因此,我们可以通过使用方法引用直接引用该方法:
employeeList.sort(员工::compareByGrade);//方法引用
根据文档,有四种方法引用:
+----+-------------------------------------------------------+--------------------------------------+
| | Kind | Example |
+----+-------------------------------------------------------+--------------------------------------+
| 1 | Reference to a static method | ContainingClass::staticMethodName |
+----+-------------------------------------------------------+--------------------------------------+
| 2 |Reference to an instance method of a particular object | containingObject::instanceMethodName |
+----+-------------------------------------------------------+--------------------------------------+
| 3 | Reference to an instance method of an arbitrary object| ContainingType::methodName |
| | of a particular type | |
+----+-------------------------------------------------------+--------------------------------------+
| 4 |Reference to a constructor | ClassName::new |
+------------------------------------------------------------+--------------------------------------+