Java8中方法引用的使用詳解
1. 引言
Java8中最受廣大開發(fā)中喜歡的變化之一是因?yàn)橐肓?lambda 表達(dá)式,因?yàn)檫@些表達(dá)式允許我們放棄匿名類,從而大大減少了樣板代碼,并提高了可讀性。
方法引用是lambda表達(dá)式的一種特殊類型。它們通常通過引用現(xiàn)有方法來(lái)創(chuàng)建簡(jiǎn)單的lambda表達(dá)式。
方法引用包括以下四種類型:
- 靜態(tài)方法
- 特定對(duì)象的實(shí)例方法
- 特定類型的任意對(duì)象的實(shí)例方法
- 構(gòu)造方法
- 在本篇文章中,我們將探討Java中的方法引用。
2. 引用靜態(tài)方法
We'll begin with a very simple example, capitalizing and printing a list of Strings:
我們從一個(gè)非常簡(jiǎn)單的示例開始,字符串轉(zhuǎn)成大寫并打?。?/p>
List<String> messages = Arrays.asList("hello", "baeldung", "readers!");
我們可以通過簡(jiǎn)單的lambda表達(dá)式直接調(diào)用 StringUtils.capitalize() 方法:
messages.forEach(word -> StringUtils.capitalize(word));
或者,我們可以使用方法引用來(lái)簡(jiǎn)單地引用 capitalize 靜態(tài)方法:
messages.forEach(StringUtils::capitalize);
注意,方法引用應(yīng)使用::運(yùn)算符。
3. 引用特定對(duì)象的實(shí)例方法
為了演示這種類型的方法引用,我們新建以下這兩個(gè)類:
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)建一個(gè) BicycleComparator 對(duì)象來(lái)比較自行車尺寸:
BicycleComparator bikeFrameSizeComparator = new BicycleComparator();
我們可以使用lambda表達(dá)式按尺寸大小對(duì)自行車進(jìn)行排序,但需要指定兩個(gè)自行車實(shí)例進(jìn)行比較:
createBicyclesList().stream() .sorted((a, b) -> bikeFrameSizeComparator.compare(a, b));
我們可以使用方法引用讓編譯器把句柄參數(shù)傳遞給我們:
createBicyclesList().stream() .sorted(bikeFrameSizeComparator::compare);
4. 引用特定類型任意對(duì)象的實(shí)例方法
這種類型的方法引用與前面的示例類似,但不必創(chuàng)建自定義對(duì)象來(lái)執(zhí)行比較。
讓我們創(chuàng)建一個(gè)要排序的Integer 整數(shù)列表:
List<Integer> numbers = Arrays.asList(5, 3, 50, 24, 40, 2, 9, 18);
如果我們使用經(jīng)典的 lambda 表達(dá)式,這兩個(gè)參數(shù)都需要顯式傳遞,而使用方法引用則要簡(jiǎn)單得多:
numbers.stream() .sorted((a, b) -> a.compareTo(b)); numbers.stream() .sorted(Integer::compareTo);
盡管它仍然是一行代碼,但是方法引用更容易閱讀和理解。
5. 引用構(gòu)造函數(shù)
我們可以像在第一個(gè)例子中引用靜態(tài)方法一樣引用構(gòu)造函數(shù)。唯一區(qū)別是需要使用new關(guān)鍵字。
現(xiàn)在我們用不同品牌的String列表創(chuàng)建一個(gè)Bicycle數(shù)組:
List<String> bikeBrands = Arrays.asList("Giant", "Scott", "Trek", "GT");
首先,我們將向Bicycle類添加一個(gè)新的構(gòu)造函數(shù):
public Bicycle(String brand) { this.brand = brand; this.frameSize = 0; }
接下來(lái),我們將使用方法引用中的新構(gòu)造函數(shù),并從原始的String列表中生成一個(gè)Bicycle數(shù)組:
bikeBrands.stream() .map(Bicycle::new) .toArray(Bicycle[]::new);
注意如何使用方法引用調(diào)用Bicycle和Array構(gòu)造函數(shù),從而使代碼看起來(lái)更加簡(jiǎn)潔明了。
6. 其他示例和限制
目前為止,方法引用是一個(gè)使代碼非常清晰和易讀的好方法。但是,我們不能用它們來(lái)代替各種lambda表達(dá)式,因?yàn)樗鼈冇幸恍┚窒扌浴?/p>
它們的主要局限性是由于它們最大的優(yōu)點(diǎn):前一個(gè)表達(dá)式的輸出需要與引用的方法聲明的輸入?yún)?shù)匹配。
看看這個(gè)限制的例子:
createBicyclesList().forEach(b -> System.out.printf( "Bike brand is '%s' and frame size is '%d'%n", b.getBrand(), b.getFrameSize()));
這個(gè)簡(jiǎn)單的例子不能用方法引用來(lái)表示,因?yàn)樵谖覀兊睦又?,printf 方法需要3個(gè)參數(shù),而使用createBicyclesList().forEach()只允許方法引用一個(gè)參數(shù)(Bicycle對(duì)象)。
最后,我們研究下,如何創(chuàng)建一個(gè)可以從lambda表達(dá)式引用的no-operation函數(shù)。
在本例中,我們希望使用lambda表達(dá)式而不使用其參數(shù)。
首先,創(chuàng)建 doNothingAtAll 方法:
private static <T> void doNothingAtAll(Object... o) { }
因?yàn)檫@是一個(gè)varargs方法,它可執(zhí)行在任意 lambda 表達(dá)式中,而不管引用的對(duì)象或參數(shù)的數(shù)量。我們看看它的作用:
createBicyclesList() .forEach((o) -> MethodReferenceExamples.doNothingAtAll(o));
7. 總結(jié)
在這篇文章中,我們學(xué)習(xí)了Java中的方法引用,以及如何使用它們來(lái)替換lambda表達(dá)式,從而提高了可讀性并闡明編程的意圖。
到此這篇關(guān)于Java 8 中的方法引用使用的文章就介紹到這了,更多相關(guān)Java8 方法引用內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Java冒泡排序(Bubble Sort)實(shí)例講解
冒泡排序的原理:假設(shè)要求的數(shù)組是正序,兩兩進(jìn)行比較,如果前一個(gè)書比后一個(gè)數(shù)小,位置不變。如果前一個(gè)數(shù)比后一個(gè)數(shù)大,位置互換,再跟后一個(gè)數(shù)進(jìn)行比較,直到最后。就是逐步把大數(shù)送到最后,下面來(lái)個(gè)實(shí)例給大家看看2013-11-11Netty網(wǎng)絡(luò)編程實(shí)戰(zhàn)之搭建Netty服務(wù)器
Netty是JBOSS開源的一款NIO網(wǎng)絡(luò)編程框架,可用于快速開發(fā)網(wǎng)絡(luò)的應(yīng)用。Netty是一個(gè)異步的、基于事件驅(qū)動(dòng)的網(wǎng)絡(luò)應(yīng)用框架,用于快速開發(fā)高性能的服務(wù)端和客戶端。本文將詳細(xì)說(shuō)說(shuō)如何搭建Netty服務(wù)器,需要的可以參考一下2022-10-10java實(shí)現(xiàn)建造者模式(Builder Pattern)
這篇文章主要為大家詳細(xì)介紹了java實(shí)現(xiàn)建造者模式Builder Pattern,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-10-10分析Java非阻塞算法Lock-Free的實(shí)現(xiàn)
非阻塞算法一般會(huì)使用CAS來(lái)協(xié)調(diào)線程的操作。雖然非阻塞算法有諸多優(yōu)點(diǎn),但是在實(shí)現(xiàn)上要比基于鎖的算法更加繁瑣和負(fù)責(zé)。本文將會(huì)介紹兩個(gè)是用非阻塞算法實(shí)現(xiàn)的數(shù)據(jù)結(jié)構(gòu)。2021-06-06如何使用lamda表達(dá)式對(duì)list進(jìn)行求和
這篇文章主要介紹了如何使用lamda表達(dá)式對(duì)list進(jìn)行求和問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-06-06