Java8新特性之二:方法引用

 上一節(jié)介紹了Java8新特性中的Lambda表達(dá)式,本小節(jié)繼續(xù)講解Java8的新特性之二:方法引用。方法引用其實(shí)也離不開Lambda表達(dá)式。

1、方法引用的使用場(chǎng)景

  我們用Lambda表達(dá)式來實(shí)現(xiàn)匿名方法。但有些情況下,我們用Lambda表達(dá)式僅僅是調(diào)用一些已經(jīng)存在的方法,除了調(diào)用動(dòng)作外,沒有其他任何多余的動(dòng)作,在這種情況下,我們傾向于通過方法名來調(diào)用它,而Lambda表達(dá)式可以幫助我們實(shí)現(xiàn)這一要求,它使得Lambda在調(diào)用那些已經(jīng)擁有方法名的方法的代碼更簡(jiǎn)潔、更容易理解。方法引用可以理解為L(zhǎng)ambda表達(dá)式的另外一種表現(xiàn)形式。

2、方法引用的分類


?加java高級(jí)架構(gòu)師群獲取Java工程化、高性能及分布式、高性能、深入淺出。高架構(gòu)。 性能調(diào)優(yōu)、Spring,MyBatis,Netty源碼分析和大數(shù)據(jù)等多個(gè)知識(shí)點(diǎn)高級(jí)進(jìn)階干貨的直播免費(fèi)學(xué)習(xí)權(quán)限? 都是大牛帶飛?讓你少走很多的彎路的?群號(hào)是:?798891710對(duì)了?小白勿進(jìn)?最好是有開發(fā)經(jīng)驗(yàn)?

3、方法引用舉例

3.1?靜態(tài)方法引用

  有一個(gè)Person類,如下所示:

@Data public class Person { private String name; private Integer age; public static int compareByAge(Person a, Person b) { return a.age.compareTo(b.age); } }

 現(xiàn)假設(shè),一個(gè)部門有30人,把他們存放在一個(gè)數(shù)組中,并按年齡排序,通常我們可以自己寫一個(gè)比較器,代碼如下:

Person[] rosterAsArray = new Person[30]; // 添加數(shù)組元素省略 class PersonAgeComparator implements Comparator<Person> { public int compare(Person a, Person b) { return a.getBirthday().compareTo(b.getBirthday()); } } Arrays.sort(rosterAsArray, new PersonAgeComparator());

 Arrays.sort的聲明為:public static <T> void sort(T[] a, Comparator<? super T> c),比較器參數(shù)Comparator為一個(gè)函數(shù)式接口,利用上一節(jié)Lambda表達(dá)式所學(xué)知識(shí),可以改寫為以下代碼:

1 Person[] rosterAsArray = new Person[30]; 2 // 添加數(shù)組元素省略 3 4 Arrays.sort(rosterAsArray, (a,b) -> a.getAge().compareTo(b.getAge()));

 然而,你會(huì)發(fā)現(xiàn),Perdon類中已經(jīng)有了一個(gè)靜態(tài)方法的比較器:compareByAge,因此,我們改用Person類已經(jīng)提供的比較器:

1Person[] rosterAsArray =newPerson[30];2// 添加數(shù)組元素省略34Arrays.sort(rosterAsArray, (a,b) -> Person.compareByAge(a,b));

  以上代碼,因?yàn)長(zhǎng)ambda表達(dá)式調(diào)用了一個(gè)已經(jīng)存在的靜態(tài)方法,根據(jù)我們第2節(jié)表格中的語法,上面的代碼可以最終改寫成靜態(tài)方法引用:

1Person[] rosterAsArray =newPerson[30];2// 添加數(shù)組元素省略34Arrays.sort(rosterAsArray, Person::compareByAge);

  下面這個(gè)例子更簡(jiǎn)單:


public class Test { public static void main(String[] args) { List<Integer> list = Arrays.asList(82,22,34,50,9); list.sort(Integer::compare); System.out.println(list); } }

 對(duì)一個(gè)Integer列表進(jìn)行排序,因?yàn)镮nteger中已經(jīng)存在靜態(tài)的比較方法compare(),因此可以直接用靜態(tài)方法引用的方式來調(diào)用 ,運(yùn)行結(jié)果為:

[9, 22, 34, 50, 82]

3.2?實(shí)例方法引用

  實(shí)例方法引用,顧名思義就是調(diào)用已經(jīng)存在的實(shí)例的方法,與靜態(tài)方法引用不同的是類要先實(shí)例化,靜態(tài)方法引用類無需實(shí)例化,直接用類名去調(diào)用。

@Data class User { private String name; private Integer age; public User(String name, Integer age) { this.name = name; this.age = age; } } public class TestInstanceReference { public static void main(String[] args) { TestInstanceReference test = new TestInstanceReference(); User user = new User("歐陽峰",32); Supplier<String> supplier = () -> user.getName(); System.out.println("Lambda表達(dá)式輸出結(jié)果:" + supplier.get()); Supplier<String> supplier2 = user::getName; System.out.println("實(shí)例方法引用輸出結(jié)果:" + supplier2.get()); } }

 輸出結(jié)果:

Lambda表達(dá)式輸出結(jié)果:歐陽峰

實(shí)例方法引用輸出結(jié)果:歐陽峰

3.3?對(duì)象方法引用

  若Lambda參數(shù)列表中的第一個(gè)參數(shù)是實(shí)例方法的參數(shù)調(diào)用者,而第二個(gè)參數(shù)是實(shí)例方法的參數(shù)時(shí),可以使用對(duì)象方法引用。

String的equals()方法:

public boolean equals(Object anObject) { if (this == anObject) { return true; } if (anObject instanceof String) { String anotherString = (String)anObject; int n = value.length; if (n == anotherString.value.length) { char v1[] = value; char v2[] = anotherString.value; int i = 0; while (n-- != 0) { if (v1[i] != v2[i]) return false; i++; } return true; } } return false; }

public static void main(String[] args) { BiPredicate<String,String> bp = (x, y) -> x.equals(y); BiPredicate<String,String> bp1 = String::equals; boolean test = bp1.test("xy", "xx"); System.out.println(test); }

 BiPredicate的test()方法接受兩個(gè)參數(shù),x和y,具體實(shí)現(xiàn)為x.equals(y),滿足Lambda參數(shù)列表中的第一個(gè)參數(shù)是實(shí)例方法的參數(shù)調(diào)用者,而第二個(gè)參數(shù)是實(shí)例方法的參數(shù),因此可以使用對(duì)象方法引用。

3.4?構(gòu)造方法引用

  注意:需要調(diào)用的構(gòu)造器的參數(shù)列表要與函數(shù)式接口中抽象方法的參數(shù)列表保持一致。

  如:要獲取一個(gè)空的User列表:

1Supplier> userSupplier = () ->newArrayList<>();2List user = userSupplier.get();34Supplier> userSupplier2 = ArrayList::new;// 構(gòu)造方法引用寫法5List user2 = userSupplier.get();

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容