什么是method reference
- 通常我們可以用lambda表達(dá)式去創(chuàng)建一個(gè)匿名方法厦章,然而有的時(shí)候灭衷,一個(gè)lambda表達(dá)式什么都不做只是調(diào)用一個(gè)已經(jīng)存在的方法,這種情況下显拳,我們可以使用一個(gè)更緊湊易讀的方式去表達(dá)就是method reference ::
- 我們調(diào)用的這個(gè)方法可以是靜態(tài)方法也可以是實(shí)例方法
- 我們調(diào)用的這個(gè)方法要求跟Function Interface里面的方法有同樣的參數(shù)變量窿克,但是其他的比如返回類(lèi)型,方法名稱(chēng)髓涯,方法修飾符是不要求一樣的
Method Reference的類(lèi)型
類(lèi)型 | 例子 |
---|---|
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 |
類(lèi)型1: 引用static method
語(yǔ)法: Classname::methodName
舉例:
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);
}}
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());
這里Comparator是個(gè)Functional Interface所以我們可以寫(xiě)成Lambda表達(dá)式:
Arrays.sort(rosterAsArray, (Person a, Person b) -> {return a.getBirthday().compareTo(b.getBirthday());});
然而比較生日的方法已經(jīng)在Person類(lèi)里面定義了袒啼,所以我們可以簡(jiǎn)單的寫(xiě)成:
Arrays.sort(rosterAsArray, ( a, b) -> Person.compareByAge(a,b););
因?yàn)長(zhǎng)ambda表達(dá)式調(diào)用了一個(gè)已經(jīng)存在的方法,所以我們可以用method reference來(lái)代替Lambda表達(dá)式
Arrays.sort(rosterAsArray, Person::compareByAge);
method reference Person::compareByAge
跟 lambda 表達(dá)式(a, b) -> Person.compareByAge(a, b)
是一樣的. method reference的參數(shù)來(lái)自 Comparator<Person>.compare
, 就是 (Person, Person).方法內(nèi)容本身來(lái)自 Person.compareByAge
.
類(lèi)型:引用實(shí)例方法
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);
我們?cè)倏磦€(gè)例子:
//首先定義個(gè)Functional Interface
interface interf{
void m1(int i);
}
Class Test{
public void m2(int i) {
System.out.println("From Method Reference:"+i);
}
public static void main(String[] args){
interf inter1 = i -> System.out.println("From Lambda expression:"+i);
inter1.m1(10);
Test test = new Test();
Interf inter2 =test:m2;
inter2.m1(20);
}
}
在上面這個(gè)例子中纬纪,我們實(shí)現(xiàn)的是接口里的方法m1()直接引用Test類(lèi)里面的實(shí)例方法m2().
這里的主要的優(yōu)勢(shì)是我們可以重用已經(jīng)存在的方法去實(shí)現(xiàn)interface蚓再,輕易的達(dá)到代碼重用
任意對(duì)象的實(shí)例方法引用
String[] stringArray = { "Barbara", "James", "Mary", "John",
"Patricia", "Robert", "Michael", "Linda" };
Arrays.sort(stringArray, String::compareToIgnoreCase);
這里的compareToIgnoreCase是個(gè)實(shí)例方法,不是靜態(tài)方法包各,所以String::compareToIgnoreCase
相當(dāng)于任意定義了兩個(gè)變量 (String a, String b), 然后調(diào)用了a.compareToIgnoreCase(b)
.
調(diào)用構(gòu)造函數(shù)
我們可以調(diào)用構(gòu)造函數(shù)摘仅, 用new這個(gè)關(guān)鍵字類(lèi)似調(diào)用靜態(tài)方法一樣:
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;
}
Set<Person> rosterSetLambda =
transferElements(roster, () -> { return new HashSet<>(); });
這里我們可以用method reference:
Set<Person> rosterSet = transferElements(roster, HashSet::new);
Java編譯器推斷出,你想創(chuàng)建一個(gè)包含Person類(lèi)型的HashSet集合髓棋,或者你也可以寫(xiě)成如下:
Set<Person> rosterSet = transferElements(roster, HashSet<Person>::new);
Referece:
https://docs.oracle.com/javase/tutorial/java/javaOO/methodreferences.html