摘要:實(shí)際上方法引用是表達(dá)式的一種語(yǔ)法糖。小結(jié)本篇全面介紹了方法引用的四種使用方式,且每種方式都有對(duì)應(yīng)一個(gè)示例來(lái)幫助大家理解。
上一篇我們?cè)敿?xì)介紹了Optional類用來(lái)避免空指針問(wèn)題,本篇我們?nèi)媪私庖幌翵ava8中的方法引用特性。
方法引用是lambda表達(dá)式的一種特殊形式,如果正好有某個(gè)方法滿足一個(gè)lambda表達(dá)式的形式,那就可以將這個(gè)lambda表達(dá)式用方法引用的方式表示,但是如果這個(gè)lambda表達(dá)式的比較復(fù)雜就不能用方法引用進(jìn)行替換。實(shí)際上方法引用是lambda表達(dá)式的一種語(yǔ)法糖。
在介紹方法引用使用方式之前,先將方法引用分下類
方法引用共分為四類:
1.類名::靜態(tài)方法名
2.對(duì)象::實(shí)例方法名
3.類名::實(shí)例方法名
4.類名::new
首先來(lái)看下第一種 類名::靜態(tài)方法名 為了演示我們自定義了一個(gè)Student類
public class Student { private String name; private int score; public Student(){ } public Student(String name,int score){ this.name = name; this.score = score; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getScore() { return score; } public void setScore(int score) { this.score = score; } public static int compareStudentByScore(Student student1,Student student2){ return student1.getScore() - student2.getScore(); } }
Student類有兩個(gè)屬性name和score并提供了初始化name和score的構(gòu)造方法,并且在最下方提供了兩個(gè)靜態(tài)方法分別按score和name進(jìn)行比較先后順序。
接下來(lái)的需求是,按著分?jǐn)?shù)由小到大排列并輸出,在使用方法引用前,我們先使用lambda表達(dá)式的方式進(jìn)行處理
Student student1 = new Student("zhangsan",60); Student student2 = new Student("lisi",70); Student student3 = new Student("wangwu",80); Student student4 = new Student("zhaoliu",90); Liststudents = Arrays.asList(student1,student2,student3,student4); students.sort((o1, o2) -> o1.getScore() - o2.getScore()); students.forEach(student -> System.out.println(student.getScore()));
sort方法接收一個(gè)Comparator函數(shù)式接口,接口中唯一的抽象方法compare接收兩個(gè)參數(shù)返回一個(gè)int類型值,下方是Comparator接口定義
@FunctionalInterface public interface Comparator{ int compare(T o1, T o2); }
我們?cè)倏聪耂tudent類中定義的compareStudentByScore靜態(tài)方法
public static int compareStudentByScore(Student student1,Student student2){ return student1.getScore() - student2.getScore(); }
同樣是接收兩個(gè)參數(shù)返回一個(gè)int類型值,而且是對(duì)Student對(duì)象的分?jǐn)?shù)進(jìn)行比較,所以我們這里就可以 使用類名::靜態(tài)方法名 方法引用替換lambda表達(dá)式
students.sort(Student::compareStudentByScore); students.forEach(student -> System.out.println(student.getScore()));
第二種 對(duì)象::實(shí)例方法名
我們?cè)僮远x一個(gè)用于比較Student元素的類
public class StudentComparator { public int compareStudentByScore(Student student1,Student student2){ return student2.getScore() - student1.getScore(); } }
StudentComparator中定義了一個(gè)非靜態(tài)的,實(shí)例方法compareStudentByScore,同樣該方法的定義滿足Comparator接口的compare方法定義,所以這里可以直接使用 對(duì)象::實(shí)例方法名 的方式使用方法引用來(lái)替換lambda表達(dá)式
StudentComparator studentComparator = new StudentComparator(); students.sort(studentComparator::compareStudentByScore); students.forEach(student -> System.out.println(student.getScore()));
第三種 類名::實(shí)例方法名
這種方法引用的方式較之前兩種稍微有一些不好理解,因?yàn)闊o(wú)論是通過(guò)類名調(diào)用靜態(tài)方法還是通過(guò)對(duì)象調(diào)用實(shí)例方法這都是符合Java的語(yǔ)法,使用起來(lái)也比較清晰明了。那我們帶著這個(gè)疑問(wèn)來(lái)了解一下這個(gè)比較特殊的方法引用。
現(xiàn)在再看一下Student類中靜態(tài)方法的定義
public static int compareStudentByScore(Student student1,Student student2){ return student1.getScore() - student2.getScore(); }
雖然這個(gè)方法在語(yǔ)法上沒(méi)有任何問(wèn)題,可以作為一個(gè)工具正常使用,但是有沒(méi)有覺(jué)得其在設(shè)計(jì)上是不合適的或者是錯(cuò)誤的。這樣的方法定義放在任何一個(gè)類中都可以正常使用,而不只是從屬于Student這個(gè)類,那如果要定義一個(gè)只能從屬于Student類的比較方法下面這個(gè)實(shí)例方法更合適一些
public int compareByScore(Student student){ return this.getScore() - student.getScore(); }
接收一個(gè)Student對(duì)象和當(dāng)前調(diào)用該方法的Student對(duì)象的分?jǐn)?shù)進(jìn)行比較即可?,F(xiàn)在我們就可以使用 類名::實(shí)例方法名 這種方式的方法引用替換lambda表達(dá)式了
students.sort(Student::compareByScore); students.forEach(student -> System.out.println(student.getScore()));
這里非常奇怪,sort方法接收的lambda表達(dá)式不應(yīng)該是兩個(gè)參數(shù)么,為什么這個(gè)實(shí)例方法只有一個(gè)參數(shù)也滿足了lambda表達(dá)式的定義(想想這個(gè)方法是誰(shuí)來(lái)調(diào)用的)。這就是 類名::實(shí)例方法名 這種方法引用的特殊之處:當(dāng)使用 類名::實(shí)例方法名 方法引用時(shí),一定是lambda表達(dá)式所接收的第一個(gè)參數(shù)來(lái)調(diào)用實(shí)例方法,如果lambda表達(dá)式接收多個(gè)參數(shù),其余的參數(shù)作為方法的參數(shù)傳遞進(jìn)去。
結(jié)合本例來(lái)看,最初的lambda表達(dá)式是這樣的
students.sort((o1, o2) -> o1.getScore() - o2.getScore());
那使用 類名::實(shí)例方法名 方法引用時(shí),一定是o1來(lái)調(diào)用了compareByScore實(shí)例方法,并將o2作為參數(shù)傳遞進(jìn)來(lái)進(jìn)行比較。是不是就符合了compareByScore的方法定義。
第四種 類名::new
也稱構(gòu)造方法引用,和前兩種類似只要符合lambda表達(dá)式的定義即可,回想下Supplier函數(shù)式接口的get方法,不接收參數(shù)有返回值,正好符合無(wú)參構(gòu)造方法的定義
@FunctionalInterface
public interface Supplier
/** * Gets a result. * * @return a result */ T get();
}
Suppliersupplier = Student::new;
上面就是使用了Student類構(gòu)造方法引用創(chuàng)建了supplier實(shí)例,以后通過(guò)supplier.get()就可以獲取一個(gè)Student類型的對(duì)象,前提是Student類中存在無(wú)參構(gòu)造方法。
小結(jié):本篇全面介紹了方法引用的四種使用方式,且每種方式都有對(duì)應(yīng)一個(gè)示例來(lái)幫助大家理解。當(dāng)我們使用lambda表達(dá)式進(jìn)行函數(shù)式編程時(shí),如果某個(gè)方法正好滿足lambda的定義,也滿足實(shí)際需求的邏輯,就可以使用方法引用的方式來(lái)替換lambda表達(dá)式。接下來(lái)我們將真正開始學(xué)習(xí)stream api,并結(jié)合前面學(xué)習(xí)的內(nèi)容體驗(yàn)stream api的強(qiáng)大之處。
下一篇
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/70722.html
摘要:不是引用類型,無(wú)法輸出簡(jiǎn)而言之,堆內(nèi)存存放引用值,棧內(nèi)存存放固定類型值。變量的查詢?cè)谧兞康牟樵冎?,訪問(wèn)局部變量要比全局變量來(lái)得快,因此不需要向上搜索作用域鏈。 贊助我以寫出更好的文章,give me a cup of coffee? 2017最新最全前端面試題 基本類型值有:undefined,NUll,Boolean,Number和String,這些類型分別在內(nèi)存中占有固定的大小空...
摘要:也就是說(shuō)當(dāng)使用后,當(dāng)前執(zhí)行上下文中的對(duì)象已被替換為,后續(xù)執(zhí)行將以所持有的狀態(tài)屬性繼續(xù)執(zhí)行。借用的方法替換的實(shí)例去調(diào)用相應(yīng)的方法。實(shí)現(xiàn)引用類型的繼承其實(shí)沒(méi)有類這一概念,我們平時(shí)使用的等嚴(yán)格來(lái)說(shuō)被稱作引用類型。 call 方法:object.method.call(targetObj[, argv1, argv2, .....]) apply 方法:object.method.apply(...
摘要:事實(shí)上,最新的已經(jīng)支持了私有屬性。而的私有方法是提案的一部分。自從年雙十一正式上線,累計(jì)處理了億錯(cuò)誤事件,付費(fèi)客戶有金山軟件百姓網(wǎng)等眾多品牌企業(yè)。 譯者按: 為什么偏要用#符號(hào)? 原文:JavaScripts new #private class fields 譯者:Fundebug 本文采用意譯,版權(quán)歸原作者所有 proposal-class-fields與proposa...
摘要:類型使用自,國(guó)際協(xié)調(diào)時(shí)間年月日午夜零時(shí)開始經(jīng)過(guò)的毫秒數(shù)來(lái)保存日期。日期時(shí)間組件方法到目前為止,剩下還未介紹的類型的方法如下表所示,都是直接取得和設(shè)置日期值中特定部分的方法了。 Date類型使用自UTC(Coordinated Universal Time,國(guó)際協(xié)調(diào)時(shí)間)1970 年1 月1 日午夜(零時(shí))開始經(jīng)過(guò)的毫秒數(shù)來(lái)保存日期。在使用這種數(shù)據(jù)存儲(chǔ)格式的條件下,Date 類型保存的日...
摘要:前兩天看到大神的關(guān)于基本數(shù)據(jù)類型和引用類型的區(qū)別的文章覺(jué)得寫得非常不錯(cuò),就想著在其基礎(chǔ)上加上自己平時(shí)看到的一些知識(shí)點(diǎn)和理解,所以就有了以下的文章基本數(shù)據(jù)類型基本數(shù)據(jù)類型包括基本數(shù)據(jù)類型是按值訪問(wèn)的,就是說(shuō)我們可以操作保存在變量中的實(shí)際的值基 前兩天看到kraaas大神的關(guān)于基本數(shù)據(jù)類型和引用類型的區(qū)別的文章覺(jué)得寫得非常不錯(cuò),就想著在其基礎(chǔ)上加上自己平時(shí)看到的一些知識(shí)點(diǎn)和理解,所以就有了...
閱讀 912·2021-09-22 15:17
閱讀 1949·2021-09-22 15:06
閱讀 2231·2021-09-08 09:35
閱讀 5119·2021-09-01 11:43
閱讀 3488·2019-08-30 15:55
閱讀 2162·2019-08-30 12:48
閱讀 3163·2019-08-30 12:45
閱讀 1792·2019-08-29 17:31