函數(shù)式編程_類型拆裝及重載解析
朝臣待漏五更寒,
鐵甲將軍夜渡關(guān)。
山寺日高僧未起,
看來名利不如閑。
????一首定場消聲去,醒木拍桌開書來。各位看官,別來無恙,今兒個我們聊一番函數(shù)式編程的類庫。
????現(xiàn)如今jdk8,在各大公司可謂大行其道,對比前一代的code套路,jdk8的惰性求值、及早求值和內(nèi)部迭代等一系列小操作可說是無往不勝,再加之引入接口靜態(tài)方法、默認方法等等新特性,還有來自外界鋪天蓋地的職位投遞要求,晦澀卻有生動地的入職相邀,也難怪一眾公眾號競相投遞推送花樣繁多卻又內(nèi)容高度統(tǒng)一地培訓(xùn)套餐廣告及軟文,話雖如此,有道是人各有志,老韭新韭皆是道友,入相飛天皆為修煉。值得一說的是,基于安全和開發(fā)舒適感考慮,雷記推薦嘗試使用open jdk。
????書歸正傳,讓我們來探一番函數(shù)式類庫地究竟。在雷記很久之前地帖子中,對于函數(shù)式地流做了一些簡單的介紹,還有一些基于lambda和stream地使用的例子,讓我們繼續(xù)沿著這個思路搞下去。
要怎樣在代碼中使用lambda表達式?
????由于lambda表達式函數(shù)接口的類型可以內(nèi)部推導(dǎo),因此在調(diào)用角度看來,調(diào)用lambda表達式和調(diào)用普通的接口方法沒有區(qū)別。讓我們看一個日常處理中十分常見的場景:
????公司分派了一個新的項目下來,要處理大數(shù)據(jù)量的日志,在編碼時日志框架中要設(shè)置類似void debug(String message)的方法,在判斷上下文日志級別為debug時,要打印對應(yīng)日志級別的日志。那么這時就會出現(xiàn)一個問題,要在各處判斷日志級別是否為debug級別,頻繁地計算判斷會影響系統(tǒng)性能,海量的數(shù)據(jù)寫入也會導(dǎo)致系統(tǒng)io占用率被打到很高。
????面對這個情況,要拆分一下問題,首先日志等級判斷的頻繁性,其次是海量日志的io寫,針對這兩個問題,第一個可以采用lambda+判定開關(guān)降低性能開銷,第二個可以采用基于epoll原型的nio方式,第二個問題展開講在這里會有跑題的嫌疑,所以暫且不表。關(guān)于第一個問題,具體處理:
·重寫logger類的debug方法:
????public void debug(Supplier
????????if(isDebugEnaled()){
????????????debug(message.get());
????????}
????}
·日志判定采用lambda參數(shù):
????Logger log = new Logger();
????log.debug(() -> "xxxx");
這里對于Supplier
????@FunctionalInterface
????public interface Supplier
????? ? /**
????? ? ?* Gets a result.
????? ? ?*
????? ? ?* @return a result
????? ? ?*/
????? ? T get();
????}
函數(shù)式中對于基本類型、裝箱類型的拆裝箱處理
????在java中有時我們想要一個包含整數(shù)型值的List
????為了減小這類的性能開銷,java8中stream對于整型、長整型、雙浮點數(shù)進行了特殊處理,stream方法中命名帶有to或以類型名開頭的方法即是,因為經(jīng)過了改善和優(yōu)化,所以要盡可能多的使用這類函數(shù),此外它還有很多額外的方法,可以避免我們重復(fù)造輪子實現(xiàn)一些通用且容易處bug的方法。
重載解析
????java通過不同方法簽名實現(xiàn)重載,這對于stream推斷類型時會帶來問題,導(dǎo)致推斷出很多種類型,所以javac會挑出最具體的類型,對此有一個默認的規(guī)則:
·只有一個可能的目標類型,由相應(yīng)函數(shù)接口的參數(shù)類型推到;
·有多個可能的目標類型,由最具體的類型推導(dǎo)得出;
·有多個可能的目標類型且最具體的類型不明確,需要人為指定類型;
@FunctionalInterface
????為提高stream對象可操作性而引入的各類接口,都需要lambda表達式惡意實現(xiàn)它們,這類接口存在的意義是將代碼塊作為數(shù)據(jù)打包起來,這正是通過@FunctionalInterface做到的,@FunctionalInterface會強制javac檢查一個接口是否符合函數(shù)接口標準,如果這個注釋加到枚舉類、類或另一個注釋或接口包含不止一個抽象方法,在javac層面就會報錯,使用它在重構(gòu)代碼時能很快發(fā)現(xiàn)問題。
結(jié)語
????最近這段時間因為家庭和公司瑣事,導(dǎo)致更新變慢,承蒙各位錯愛,惶恐惶恐。后面地更新里,雷記打算嘗試加一些vue的前端內(nèi)容,進而最終過渡到小程序和app制作上,目前是這么打算。如果各位看官有更好的想法,歡迎私信雷記交流,那么今天的更新就是這樣,愿諸位,酒色財氣君莫占,招財進寶,日進斗金~
