成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

Java8-8-方法引用詳解

劉東 / 1519人閱讀

摘要:實(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);
List students = 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();

}

Supplier supplier = 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

相關(guān)文章

  • 詳解js變量、作用域及內(nèi)存

    摘要:不是引用類型,無(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)存中占有固定的大小空...

    waltr 評(píng)論0 收藏0
  • js 中的 call / apply 方法詳解引用類型的繼承

    摘要:也就是說(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(...

    cod7ce 評(píng)論0 收藏0
  • JavaScript 新語(yǔ)法詳解:Class 的私有屬性與私有方法

    摘要:事實(shí)上,最新的已經(jīng)支持了私有屬性。而的私有方法是提案的一部分。自從年雙十一正式上線,累計(jì)處理了億錯(cuò)誤事件,付費(fèi)客戶有金山軟件百姓網(wǎng)等眾多品牌企業(yè)。 譯者按: 為什么偏要用#符號(hào)? 原文:JavaScripts new #private class fields 譯者:Fundebug 本文采用意譯,版權(quán)歸原作者所有 proposal-class-fields與proposa...

    opengps 評(píng)論0 收藏0
  • 詳解日期(Date)引用類型

    摘要:類型使用自,國(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 類型保存的日...

    Shisui 評(píng)論0 收藏0
  • 基本數(shù)據(jù)類型和引用類型的區(qū)別詳解

    摘要:前兩天看到大神的關(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)和理解,所以就有了...

    CoffeX 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<