今天是劉小愛自學(xué)Java的第48天酱固。
感謝你的觀看蹄葱,謝謝你。
話不多說杜顺,開始今天的學(xué)習(xí):
昨天回顧了函數(shù)式編程的一些概念裁僧。
今天開始學(xué)習(xí)方法引用个束,它是lambda表達式的進一步簡化版,語法還要更加地簡潔聊疲。
一茬底、方法引用
現(xiàn)有一個需求:
將一個字符串信息全部轉(zhuǎn)換成大寫字母,再打印出來获洲。
利用函數(shù)式編程思想編寫代碼阱表。
1.lambda表達式編寫
①函數(shù)式接口Printable
這是一個自定義的打印接口,有一個打印信息的抽象方法printMsg()
②lambda表達式
method方法中有兩個參數(shù)贡珊,用lambda表達式表示的是接口的實現(xiàn)類對象最爬。并且在lambda表達式中,業(yè)務(wù)邏輯已經(jīng)寫出來了门岔。
什么叫業(yè)務(wù)邏輯爱致?
我的理解是方法內(nèi)容:根據(jù)什么參數(shù)得到了什么結(jié)果。
上述例子中就是:根據(jù)傳過來的字符串消息(也就是參數(shù)msg)
結(jié)果將msg全部變成大寫字母(msg.toUpperCase)
這就是業(yè)務(wù)邏輯寒随,當(dāng)然我舉的這個例子非常簡單糠悯,現(xiàn)實里肯定要復(fù)雜的多。
2.方法引用
方法引用是用來代替lambda表達式的妻往,更加地簡潔互艾,從某種意義上來說,它們的作用其實是差不多的讯泣。
①方法引用
具體格式為:new MyPrint()::printMsg
核心是這個雙冒號“::”纫普,如何理解這個格式?
就可以理解成是MyPrint對象在調(diào)用printMsg方法好渠。
為什么它能直接這樣使用局嘁?因為它的邏輯已經(jīng)存在溉箕,也就是MyPrint類中有printMsg方法以及其業(yè)務(wù)邏輯
②業(yè)務(wù)邏輯
將字符串msg全部變成大寫字母晦墙,這就相當(dāng)于是在MyPrint類中重寫了接口中的抽象方法悦昵。
3.方法引用和lambda表達式:
現(xiàn)在問題來了:方法引用不是對lambda表達式的簡化么?怎么感覺代碼還越來越繁瑣了晌畅?
我們只看①而言但指,方法引用要比lambda表達式簡單吧?
如果我使用方法引用抗楔,該業(yè)務(wù)邏輯無論被使用多少次棋凳,我只需要寫一次,其它時候直接調(diào)用连躏;
如果我是用lambda表達式剩岳,我每調(diào)用一次就要將業(yè)務(wù)邏輯寫一遍。
所以方法引用的簡潔之處在于相同邏輯不需要重復(fù)地寫入热。
這樣理解下來拍棕,方法引用要比lambda表達式簡潔很多,尤其是在業(yè)務(wù)邏輯很復(fù)雜的時候
當(dāng)然方法引用的前提:業(yè)務(wù)邏輯已經(jīng)存在勺良。
如果邏輯已經(jīng)存在绰播,我直接使用方法引用即可,
如果邏輯不存在尚困,還是乖乖地寫lambda表達式蠢箩。
二、方法引用的其它方式
上述例子中的方法引用是對象在引用方法事甜,除了對象引用之外還有很多其它方式谬泌。
1.類名引用
如果是靜態(tài)方法,直接用類名就可以調(diào)用方法逻谦。
Java底層中已經(jīng)寫好了很多工具類掌实,其大多數(shù)方法都是靜態(tài)方法,直接使用方法引用會方便很多跨跨。
Math是一個工具類潮峦,它有一個靜態(tài)方法abs()。
所以方法引用直接用類名引用abs方法勇婴,因為其中的邏輯在Java底層就已經(jīng)寫好了忱嘹。
類名引用格式如下:
lambda表達式:number->Math.abs(number)
方法引用:Math::abs
當(dāng)然這里面方法引用也有一個局限性,比如說我現(xiàn)在要求得到10倍的絕對值耕渴。
lambda表達式直接改業(yè)務(wù)邏輯就好了拘悦;
但是方法引用沒辦法,因為Java底層沒有這樣的業(yè)務(wù)邏輯橱脸,就算要用方法引用础米,我們也得先將邏輯寫出來分苇。
2.通過this引用成員方法
代碼這樣寫并不規(guī)范,只是為了好觀看屁桑,所以將它們寫在一起了医寿。
this引用格式如下:
lambda表達式:name->this.introduce(name)
方法引用:this::introduce
這里面this就是代表本類,本類中已經(jīng)有introduce方法了蘑斧,那我用this引用的就是本類中對應(yīng)的方法靖秩。
3.通過super引用成員方法
如果MyClass有個父類,它里面有一個fuIntroduce方法竖瘾,若是要引用該方法沟突,可以使用super關(guān)鍵字。
使用方式和this是一樣的捕传,就不再闡述了惠拭。
super引用格式如下:
lambda表達式:name->super.fuIntroduce(name)
方法引用:super::fuIntroduce
super就是代表父類,父類中已經(jīng)有fuIntroduce方法了庸论,那我用super引用的就是父類中對應(yīng)的方法职辅。
4.類的構(gòu)造器引用
類構(gòu)造其格式如下:
lambda表達式:name->new Person(name)
方法引用:Person::new
Person::new就相當(dāng)于創(chuàng)建對象(new Person())
不要看這代碼寫的這么復(fù)雜,其實上就相當(dāng)于new對象葡公。
當(dāng)然類的構(gòu)造器這一塊理解的還不算透徹罐农,暫且只需要記住方法引用這樣使用就是在創(chuàng)建對象就好了。
5.數(shù)組的構(gòu)造器引用
數(shù)組也是Object的子類對象催什,所以同樣具有構(gòu)造器涵亏,只是語法稍有不同。
數(shù)組構(gòu)造器格式如下:
lambda表達式:length->new int[length]
方法引用:int[]::new
和類的構(gòu)造器是一樣的道理:
int[]::new就相當(dāng)于創(chuàng)建數(shù)組(new int[length])