Java 8 中的方法引用,輕松減少代碼量,提升可讀性!
點擊上方藍色“程序猿DD”,選擇“設(shè)為星標(biāo)”
回復(fù)“資源”獲取獨家整理的學(xué)習(xí)資料!

1. 引言
Java8中最受廣大開發(fā)中喜歡的變化之一是因為引入了 lambda 表達式,因為這些表達式允許我們放棄匿名類,從而大大減少了樣板代碼,并提高了可讀性。?方法引用是lambda表達式的一種特殊類型。它們通常通過引用現(xiàn)有方法來創(chuàng)建簡單的lambda表達式。
方法引用包括以下四種類型:
靜態(tài)方法 特定對象的實例方法 特定類型的任意對象的實例方法 構(gòu)造方法
在本篇文章中,我們將探討Java中的方法引用。
2. 引用靜態(tài)方法
We'll begin with a very simple example, capitalizing and printing a list of?Strings:
我們從一個非常簡單的示例開始,字符串轉(zhuǎn)成大寫并打?。?/p>
List?messages?=?Arrays.asList("hello",?"baeldung",?"readers!");
我們可以通過簡單的lambda表達式直接調(diào)用?StringUtils.capitalize()?方法:
messages.forEach(word?->?StringUtils.capitalize(word));
或者,我們可以使用方法引用來簡單地引用?capitalize?靜態(tài)方法:
messages.forEach(StringUtils::capitalize);
注意,方法引用應(yīng)使用::運算符。
3. 引用特定對象的實例方法
為了演示這種類型的方法引用,我們新建以下這兩個類:
public?class?Bicycle?{
?
????private?String?brand;
????private?Integer?frameSize;
????//?standard?constructor,?getters?and?setters
}
?
public?class?BicycleComparator?implements?Comparator?{
?
????@Override
????public?int?compare(Bicycle?a,?Bicycle?b)?{
????????return?a.getFrameSize().compareTo(b.getFrameSize());
????}
?
}
創(chuàng)建一個 BicycleComparator 對象來比較自行車尺寸:
BicycleComparator?bikeFrameSizeComparator?=?new?BicycleComparator();
我們可以使用lambda表達式按尺寸大小對自行車進行排序,但需要指定兩個自行車實例進行比較:
createBicyclesList().stream()
??.sorted((a,?b)?->?bikeFrameSizeComparator.compare(a,?b));
我們可以使用方法引用讓編譯器把句柄參數(shù)傳遞給我們:
createBicyclesList().stream()
??.sorted(bikeFrameSizeComparator::compare);
4. 引用特定類型任意對象的實例方法
這種類型的方法引用與前面的示例類似,但不必創(chuàng)建自定義對象來執(zhí)行比較。
讓我們創(chuàng)建一個要排序的Integer?整數(shù)列表:
List?numbers?=?Arrays.asList(5,?3,?50,?24,?40,?2,?9,?18);
如果我們使用經(jīng)典的 lambda 表達式,這兩個參數(shù)都需要顯式傳遞,而使用方法引用則要簡單得多:
numbers.stream()
??.sorted((a,?b)?->?a.compareTo(b));
numbers.stream()
??.sorted(Integer::compareTo);
盡管它仍然是一行代碼,但是方法引用更容易閱讀和理解。
5. 引用構(gòu)造函數(shù)
我們可以像在第一個例子中引用靜態(tài)方法一樣引用構(gòu)造函數(shù)。唯一區(qū)別是需要使用new關(guān)鍵字?,F(xiàn)在我們用不同品牌的String列表創(chuàng)建一個Bicycle數(shù)組:
List?bikeBrands?=?Arrays.asList("Giant",?"Scott",?"Trek",?"GT");
首先,我們將向Bicycle類添加一個新的構(gòu)造函數(shù):
public?Bicycle(String?brand)?{
????this.brand?=?brand;
????this.frameSize?=?0;
}
接下來,我們將使用方法引用中的新構(gòu)造函數(shù),并從原始的String列表中生成一個Bicycle數(shù)組:
bikeBrands.stream()
??.map(Bicycle::new)
??.toArray(Bicycle[]::new);
注意如何使用方法引用調(diào)用Bicycle和Array構(gòu)造函數(shù),從而使代碼看起來更加簡潔明了。
6. 其他示例和限制
目前為止,方法引用是一個使代碼非常清晰和易讀的好方法。但是,我們不能用它們來代替各種lambda表達式,因為它們有一些局限性。
它們的主要局限性是由于它們最大的優(yōu)點:前一個表達式的輸出需要與引用的方法聲明的輸入?yún)?shù)匹配。
看看這個限制的例子:
createBicyclesList().forEach(b?->?System.out.printf(
??"Bike?brand?is?'%s'?and?frame?size?is?'%d'%n",
??b.getBrand(),
??b.getFrameSize()));
這個簡單的例子不能用方法引用來表示,因為在我們的例子中,printf?方法需要3個參數(shù),而使用*createBicyclesList().forEach()*只允許方法引用一個參數(shù)(Bicycle對象)。
最后,我們研究下,如何創(chuàng)建一個可以從lambda表達式引用的no-operation函數(shù)。
在本例中,我們希望使用lambda表達式而不使用其參數(shù)。
首先,創(chuàng)建?doNothingAtAll?方法:
private?static??void?doNothingAtAll(Object...?o)?{
}
因為這是一個varargs方法,它可執(zhí)行在任意 lambda 表達式中,而不管引用的對象或參數(shù)的數(shù)量。我們看看它的作用:
createBicyclesList()
??.forEach((o)?->?MethodReferenceExamples.doNothingAtAll(o));
7. Conclusion
在這篇文章中,我們學(xué)習(xí)了Java中的方法引用,以及如何使用它們來替換lambda表達式,從而提高了可讀性并闡明編程的意圖。
推薦關(guān)注本文作者
【往期推薦】
2020-12-14
2020-12-14
2020-12-13
2020-12-13
2020-12-12
2020-12-12
掃一掃,關(guān)注我
一起學(xué)習(xí),一起進步
每周贈書,福利不斷
﹀
﹀
﹀
深度內(nèi)容
推薦加入

素質(zhì)二連,走一個
