Method References
目录
方法引用种类:Kinds of Method References
引用类的静态方法:Reference to a Static Method
引用对象的成员方法:Reference to an Instance Method of a Particular Object
引用对象的特定类型成员方法:Reference to an Instance Method of an Arbitrary Object of a Particular Type
引用构造函数:Reference to a Constructor
You use lambda expressions to create anonymous methods. Sometimes, however, a lambda expression does nothing but call an existing method. In those cases, it's often clearer to refer to the existing method by name. Method references enable you to do this; they are compact, easy-to-read lambda expressions for methods that already have a name.
您可以使用lambda表达式来创建匿名方法。然而,有时候,lambda表达式除了调用现有的方法之外什么也不做。
在这些情况下,使用名称引用现有的方法通常更清楚。
方法引用使您能够做到这一点;它们是紧凑的、易于阅读的lambda表达式,用于引用有名称的方法。
Consider again the Person
class discussed in the section Lambda Expressions:
再考虑一下在Lambda表达式中讨论的Person类:
public class Person {
public enum Sex {
MALE, FEMALE
}
String name;
LocalDate birthday;
Sex gender;
String emailAddress;
public int getAge() {
// ...
}
public Calendar getBirthday() {
return birthday;
}
public static int compareByAge(Person a, Person b) {
return a.birthday.compareTo(b.birthday);
}
}
假设用数组来保存会员,您希望按年龄对数组进行排序。您可以使用下面的代码:Suppose that the members of your social networking application are contained in an array, and you want to sort the array by age. You could use the following code (find the code excerpts described in this section in the example MethodReferencesTest
):
// you want to sort the array by age. // 你想按年龄对数组进行排序 Person[] rosterAsArray = roster.toArray(new Person[roster.size()]);
class PersonAgeComparator implements Comparator<Person> { public int compare(Person a, Person b) { return a.getBirthday().compareTo(b.getBirthday()); } }
Arrays.sort(rosterAsArray, new PersonAgeComparator());
// The method signature of this invocation of sort is the following: // 调用的排序 sort 接口如下: static <T> void sort(T[] a, Comparator<? super T> c)
// Notice that the interface Comparator is a functional interface. // Therefore, you could use a lambda expression instead of defining // and then creating a new instance of a class that implements Comparator: // 注意,上栗中 sort接口是一个功能接口。因此,您可以使用lambda表达式,简化代码 Arrays.sort(rosterAsArray, (Person a, Person b) -> { return a.getBirthday().compareTo(b.getBirthday()); } );
// However, this method to compare the birth dates of two Person instances already exists as Person. // compareByAge. You can invoke this method instead in the body of the lambda expression: // 然而,这种比较两个Person实例的出生日期的方法已经存在compareByAge()。你可以在lambda表达式的主体中调用这个方法 Arrays.sort(rosterAsArray, (a, b) -> Person.compareByAge(a, b) );
// Because this lambda expression invokes an existing method, you can use a method reference instead of a lambda expression: // 因为这个lambda表达式调用了一个现有的方法,所以您可以使用一个方法引用而不是lambda表达式: Arrays.sort(rosterAsArray, Person::compareByAge); The method reference Person::compareByAge is semantically the same as the lambda expression (a, b) -> Person.compareByAge(a, b). Each has the following characteristics:
方法引用Person::compareByAge 和lambda表达式(a, b) -> Person.compareByAge(a, b).代表了相同的语义。他们有如下特征:
|
Kinds of Method References
There are four kinds of method references:
Kind |
Example |
Reference to a static method |
ContainingClass::staticMethodName |
Reference to an instance method of a particular object |
containingObject::instanceMethodName |
Reference to an instance method of an arbitrary object of a particular type |
ContainingType::methodName |
Reference to a constructor |
ClassName::new |
有四种方法引用:
Kind |
Example |
引用类的静态方法 |
ContainingClass::staticMethodName |
引用对象的成员方法 |
containingObject::instanceMethodName |
引用类的任意对象成员方法 |
ContainingType::methodName |
引用构造方法 |
ClassName::new |
Reference to a Static Method
The method reference Person::compareByAge
is a reference to a static method.
Person::compareByAge就是一个引用类的静态方法的栗子。
Reference to an Instance Method of a Particular Object
The following is an example of a reference to an instance method of a particular object:
下面是栗子:
// 比较 供应器封装了Person类所有属性的比较方法, // 本例中使用比较供应器ComparisonProvider的成员方法compareByName实现比较 class ComparisonProvider { public int compareByName(Person a, Person b) { return a.getName().compareTo(b.getName()); }
public int compareByAge(Person a, Person b) { return a.getBirthday().compareTo(b.getBirthday()); } } ComparisonProvider myComparisonProvider = new ComparisonProvider(); Arrays.sort(rosterAsArray, myComparisonProvider::compareByName);
|
The method reference myComparisonProvider::compareByName
invokes the method compareByName
that is part of the object myComparisonProvider
. The JRE infers the method type arguments, which in this case are (Person, Person)
.
JRE会推断出方法类型参数,在本例中是(Person,Person)。
Reference to an Instance Method of an Arbitrary Object of a Particular Type
The following is an example of a reference to an instance method of an arbitrary object of a particular type:
下面是任意对象的方法引用的栗子:
// The equivalent lambda expression for the method reference String::compareToIgnoreCase would have the formal parameter list (String a, String b), // where a and b are arbitrary names used to better describe this example. The method reference would invoke the method a.compareToIgnoreCase(b). String[] stringArray = { "Barbara", "James", "Mary", "John", "Patricia", "Robert", "Michael", "Linda" }; // 一数组的任意对象 Arrays.sort(stringArray, String::compareToIgnoreCase); // 等价于:a.compareToIgnoreCase(b)
|
Reference to a Constructor
// You can reference a constructor in the same way as a static method by using the name new. The following method copies elements from one collection to another: // 您可以通过使用new来引用构造函数,和引用静态方法一样。下面的方法将元素从一个集合复制到另一个集合: public static <T, SOURCE extends Collection<T>, DEST extends Collection<T>> DEST transferElements( SOURCE sourceCollection, Supplier<DEST> collectionFactory) {
DEST result = collectionFactory.get(); for (T t : sourceCollection) { result.add(t); } return result; }
// The functional interface Supplier contains one method get that takes no arguments and returns an object. // Consequently, you can invoke the method transferElements with a lambda expression as follows: // 功能接口Supplier包含一个方法,它不接受任何参数,并返回一个对象。 // 因此,您可以用lambda表达式调用transferelement方法: Set<Person> rosterSetLambda = transferElements(roster, () -> { return new HashSet<>(); });
// You can use a constructor reference in place of the lambda expression as follows: // 您可以也使用引用构造方法来代替lambda表达式,如下所示 Set<Person> rosterSet = transferElements(roster, HashSet::new);
// The Java compiler infers that you want to create a HashSet collection that contains elements of type Person. // Alternatively, you can specify this as follows: // java编译器推断你想要创建一个HashSet集合,用来存储Person对象。等同于如下表达式: Set<Person> rosterSet = transferElements(roster, HashSet<Person>::new);
|