Java8 - Method Reference

什么是method reference

  • 通常我們可以用lambda表達(dá)式去創(chuàng)建一個(gè)匿名方法厦章,然而有的時(shí)候灭衷,一個(gè)lambda表達(dá)式什么都不做只是調(diào)用一個(gè)已經(jīng)存在的方法,這種情況下显拳,我們可以使用一個(gè)更緊湊易讀的方式去表達(dá)就是method reference ::
  • 我們調(diào)用的這個(gè)方法可以是靜態(tài)方法也可以是實(shí)例方法
  • 我們調(diào)用的這個(gè)方法要求跟Function Interface里面的方法有同樣的參數(shù)變量窿克,但是其他的比如返回類(lèi)型,方法名稱(chēng)髓涯,方法修飾符是不要求一樣的

Method Reference的類(lèi)型

類(lèi)型 例子
Reference to a static method ContainingClass::staticMethodName
Reference to an instance method of a particular object containingObject::instanceMethodName
Reference to an instance method of an arbitrary object of a particular type ContainingType::methodName
Reference to a constructor ClassName::new

類(lèi)型1: 引用static method

語(yǔ)法: Classname::methodName
舉例:

public class Person {

    public enum Sex {
        MALE, FEMALE
    }

    String name;
    LocalDate birthday;
    Sex gender;
    String emailAddress;

    public int getAge() {
        // ...
    }
    
    public Calendar getBirthday() {
        return birthday;
    }    

    public static int compareByAge(Person a, Person b) {
        return a.birthday.compareTo(b.birthday);
    }}
Person[] rosterAsArray = roster.toArray(new Person[roster.size()]);

class PersonAgeComparator implements Comparator<Person> {
    public int compare(Person a, Person b) {
        return a.getBirthday().compareTo(b.getBirthday());
    }
}
        
Arrays.sort(rosterAsArray, new PersonAgeComparator());

這里Comparator是個(gè)Functional Interface所以我們可以寫(xiě)成Lambda表達(dá)式:


Arrays.sort(rosterAsArray, (Person a, Person b) -> {return a.getBirthday().compareTo(b.getBirthday());});

然而比較生日的方法已經(jīng)在Person類(lèi)里面定義了袒啼,所以我們可以簡(jiǎn)單的寫(xiě)成:

Arrays.sort(rosterAsArray, ( a, b) -> Person.compareByAge(a,b););

因?yàn)長(zhǎng)ambda表達(dá)式調(diào)用了一個(gè)已經(jīng)存在的方法,所以我們可以用method reference來(lái)代替Lambda表達(dá)式

Arrays.sort(rosterAsArray, Person::compareByAge);

method reference Person::compareByAge 跟 lambda 表達(dá)式(a, b) -> Person.compareByAge(a, b) 是一樣的. method reference的參數(shù)來(lái)自 Comparator<Person>.compare, 就是 (Person, Person).方法內(nèi)容本身來(lái)自 Person.compareByAge.

類(lèi)型:引用實(shí)例方法


class ComparisonProvider {
    public int compareByName(Person a, Person b) {
        return a.getName().compareTo(b.getName());
    }
        
    public int compareByAge(Person a, Person b) {
        return a.getBirthday().compareTo(b.getBirthday());
    }
}
ComparisonProvider myComparisonProvider = new ComparisonProvider();
Arrays.sort(rosterAsArray, myComparisonProvider::compareByName);

我們?cè)倏磦€(gè)例子:

//首先定義個(gè)Functional Interface
interface interf{
    void m1(int i);
}

Class Test{
    public void m2(int i) { 
       System.out.println("From Method Reference:"+i);
    }
    public static void main(String[] args){
        interf inter1 = i -> System.out.println("From Lambda expression:"+i);
        inter1.m1(10);
        Test test = new Test();
        Interf inter2 =test:m2;
        inter2.m1(20);
    }
}

在上面這個(gè)例子中纬纪,我們實(shí)現(xiàn)的是接口里的方法m1()直接引用Test類(lèi)里面的實(shí)例方法m2().
這里的主要的優(yōu)勢(shì)是我們可以重用已經(jīng)存在的方法去實(shí)現(xiàn)interface蚓再,輕易的達(dá)到代碼重用

任意對(duì)象的實(shí)例方法引用

String[] stringArray = { "Barbara", "James", "Mary", "John",
    "Patricia", "Robert", "Michael", "Linda" };
Arrays.sort(stringArray, String::compareToIgnoreCase);

這里的compareToIgnoreCase是個(gè)實(shí)例方法,不是靜態(tài)方法包各,所以String::compareToIgnoreCase 相當(dāng)于任意定義了兩個(gè)變量 (String a, String b), 然后調(diào)用了a.compareToIgnoreCase(b).

調(diào)用構(gòu)造函數(shù)

我們可以調(diào)用構(gòu)造函數(shù)摘仅, 用new這個(gè)關(guān)鍵字類(lèi)似調(diào)用靜態(tài)方法一樣:



public static <T, SOURCE extends Collection<T>, DEST extends Collection<T>>
    DEST transferElements(
        SOURCE sourceCollection,
        Supplier<DEST> collectionFactory) {
        
        DEST result = collectionFactory.get();
        for (T t : sourceCollection) {
            result.add(t);
        }
        return result;
}

Set<Person> rosterSetLambda =
    transferElements(roster, () -> { return new HashSet<>(); });

這里我們可以用method reference:

Set<Person> rosterSet = transferElements(roster, HashSet::new);

Java編譯器推斷出,你想創(chuàng)建一個(gè)包含Person類(lèi)型的HashSet集合髓棋,或者你也可以寫(xiě)成如下:

Set<Person> rosterSet = transferElements(roster, HashSet<Person>::new);

Referece:

https://docs.oracle.com/javase/tutorial/java/javaOO/methodreferences.html

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末实檀,一起剝皮案震驚了整個(gè)濱河市惶洲,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌膳犹,老刑警劉巖恬吕,帶你破解...
    沈念sama閱讀 212,029評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異须床,居然都是意外死亡铐料,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,395評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門(mén)豺旬,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)钠惩,“玉大人,你說(shuō)我怎么就攤上這事族阅÷耍” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 157,570評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵坦刀,是天一觀的道長(zhǎng)愧沟。 經(jīng)常有香客問(wèn)我,道長(zhǎng)鲤遥,這世上最難降的妖魔是什么沐寺? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 56,535評(píng)論 1 284
  • 正文 為了忘掉前任,我火速辦了婚禮盖奈,結(jié)果婚禮上混坞,老公的妹妹穿的比我還像新娘。我一直安慰自己钢坦,他們只是感情好究孕,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,650評(píng)論 6 386
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著场钉,像睡著了一般蚊俺。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上逛万,一...
    開(kāi)封第一講書(shū)人閱讀 49,850評(píng)論 1 290
  • 那天泳猬,我揣著相機(jī)與錄音,去河邊找鬼宇植。 笑死得封,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的指郁。 我是一名探鬼主播忙上,決...
    沈念sama閱讀 39,006評(píng)論 3 408
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼闲坎!你這毒婦竟也來(lái)了疫粥?” 一聲冷哼從身側(cè)響起茬斧,我...
    開(kāi)封第一講書(shū)人閱讀 37,747評(píng)論 0 268
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎梗逮,沒(méi)想到半個(gè)月后项秉,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,207評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡慷彤,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,536評(píng)論 2 327
  • 正文 我和宋清朗相戀三年娄蔼,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片底哗。...
    茶點(diǎn)故事閱讀 38,683評(píng)論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡岁诉,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出跋选,到底是詐尸還是另有隱情涕癣,我是刑警寧澤,帶...
    沈念sama閱讀 34,342評(píng)論 4 330
  • 正文 年R本政府宣布野建,位于F島的核電站属划,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏候生。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,964評(píng)論 3 315
  • 文/蒙蒙 一绽昼、第九天 我趴在偏房一處隱蔽的房頂上張望唯鸭。 院中可真熱鬧,春花似錦硅确、人聲如沸目溉。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,772評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)缭付。三九已至,卻和暖如春循未,著一層夾襖步出監(jiān)牢的瞬間陷猫,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,004評(píng)論 1 266
  • 我被黑心中介騙來(lái)泰國(guó)打工的妖, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留绣檬,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,401評(píng)論 2 360
  • 正文 我出身青樓嫂粟,卻偏偏與公主長(zhǎng)得像娇未,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子星虹,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,566評(píng)論 2 349

推薦閱讀更多精彩內(nèi)容