Lambda表達(dá)式入門(mén)
當(dāng)前位置:點(diǎn)晴教程→知識(shí)管理交流
→『 技術(shù)文檔交流 』
導(dǎo)讀 1、前言 2、Lambda類(lèi)型 3、Lambda的域以及訪問(wèn)限制 4、內(nèi)置函數(shù)式接口 5、方法引用 6、靜態(tài)方法引用 7、實(shí)例方法引用 8、對(duì)象方法引用 9、構(gòu)造方法引用 10、總結(jié)
一、前言 上一篇介紹了lambda表達(dá)式的語(yǔ)法,今天繼續(xù)介紹。
二、Lambda類(lèi)型 Lambda表達(dá)式可以被當(dāng)做是一個(gè)Object。Lambda表達(dá)式的類(lèi)型,叫做“目標(biāo)類(lèi)型(target type)”。Lambda表達(dá)式的目標(biāo)類(lèi)型是“函數(shù)接口(functionalinterface)”。 有一個(gè)接口,如果只有一個(gè)顯式聲明的抽象方法,那么它就是一個(gè)函數(shù)接口。一般用@Functionallnterface標(biāo)注出來(lái)(也可以不標(biāo))。 舉例如下:
我們看到最后的Comparator接口,聲明了兩個(gè)方法,好像不符合函數(shù)接口的定義,但Comparator確實(shí)是函數(shù)接口。這個(gè)是因?yàn)閑quals方法是Object的,所有的接口都會(huì)聲明Object的public方法(雖然大多是隱式的)。所以,Comparator顯式的聲明了equals不影響它依然是個(gè)函數(shù)接口。 雖然Lambda雖然可以當(dāng)作是Object類(lèi)型,但需要顯式轉(zhuǎn)換才行。 我們可以用一個(gè)Lambda表達(dá)式為一個(gè)函數(shù)接口賦值:
然后再賦值給一個(gè)Object:
但卻不能這樣干:
必須顯式的轉(zhuǎn)型成一個(gè)函數(shù)接口才可以:
-個(gè)Lambda表達(dá)式只有在轉(zhuǎn)型成一個(gè)函數(shù)接口后才能被當(dāng)做Object使用。所以下面這句也不能編譯:
必須先轉(zhuǎn)型:
我們可以定義一個(gè)無(wú)參數(shù),無(wú)返回值的接口,類(lèi)似Runnable
那下面的寫(xiě)法,都是正確的
這說(shuō)明一個(gè)Lambda表達(dá)式可以有多個(gè)目標(biāo)類(lèi)型(函數(shù)接口),只要函數(shù)匹配成功即可。 但需注意一個(gè)Lambda表達(dá)式必須至少有一個(gè)目標(biāo)類(lèi)型。
三、Lambda的域及訪問(wèn)限制 域即作用域,Lambda表達(dá)式中的參數(shù)列表中的參數(shù)在該Lambda表達(dá)式范圍內(nèi)(域)有效。 在作用Lambda表達(dá)式內(nèi),可以訪問(wèn)外部的變量:局部變量、類(lèi)變量和靜態(tài)變量,但操作受限程度不一。 1、訪問(wèn)局部變量 在Lambda表達(dá)式外部的局部變量會(huì)被JVM隱式的編譯成final類(lèi)型,因此只能訪問(wèn)外而不能修改。 2、訪問(wèn)靜態(tài)變量和成員變量 在Lambda表達(dá)式內(nèi)部,對(duì)靜態(tài)變量和成員變量可讀可寫(xiě)
四、內(nèi)置函數(shù)式接口 小伙伴們有沒(méi)有發(fā)現(xiàn),如果使用Lambda表達(dá)式,還是需要我們自己寫(xiě)一個(gè)接口定義的,其實(shí)很多接口無(wú)非是入?yún)㈩?lèi)型和返回值不一樣而已,所以Java給我們提供了幾個(gè)常用的標(biāo)準(zhǔn)函數(shù)接口: Consumer<T>con 消費(fèi)型接口: void accept(Tt); Supplier<T>sup 供給型接口: Tget(); Function<T,R>fun 函數(shù)型接口: R apply(Tt); Predicate<T>: 斷言型接口:boolean test(Tt); 1、Consumer<T>消費(fèi)型接口 接口中的方法為 void accept(Tt),1個(gè)參數(shù),無(wú)返回值。調(diào)用方要傳入值,而不需要返回,形象比喻成消費(fèi)型 這個(gè)就是對(duì)傳入num參數(shù)值,進(jìn)行相關(guān)的處理(消費(fèi))。到底進(jìn)行處理,具體就在
上面的代碼中,是一個(gè)典型的1個(gè)參數(shù),無(wú)返回值的消費(fèi);如果沒(méi)有內(nèi)置的函數(shù)接口,那我們就需要自己定義一個(gè),如:
我們發(fā)現(xiàn)和內(nèi)置函數(shù)接口,沒(méi)有什么區(qū)別,就是接口名和方法名稱(chēng)不一樣而已,其實(shí)本質(zhì)是一樣的,這就是為什么Java會(huì)提供一些內(nèi)置的函數(shù),這樣可以減少大量的代碼。 2、Supplier<T>供給型接口 接口中的方法Tget(),無(wú)參數(shù),有返回值;不需要對(duì)方給參數(shù),而是一直返回給對(duì)方,形象定義為供給型接口 上面代碼就是返回一個(gè)新的實(shí)體對(duì)象。 3、Function<T, R>函數(shù)式接口
接口實(shí)現(xiàn)轉(zhuǎn)換成大寫(xiě)的字符。 4、Predicate<T>斷言型接口
內(nèi)置的函數(shù)接口,大大的提高開(kāi)發(fā)的效率,減少了開(kāi)發(fā)代碼
五、方法引用 方法引用是Lambda表達(dá)式的一個(gè)簡(jiǎn)化寫(xiě)法其語(yǔ)法結(jié)構(gòu)為 ObjectRef::methodName 左邊可以是類(lèi)名或者實(shí)例名,中間是方法引用符號(hào)“::”,右邊是相應(yīng)的方法名。方法引用可以分為三類(lèi)。 使用前提:Lambda體中調(diào)用方法的參數(shù)列表和返回值類(lèi)型,要和函數(shù)式接口中抽象方法的參數(shù)列表和返回值類(lèi)型保持一致。
六、靜態(tài)方法引用 先上一個(gè)案例 上面的代碼中,我們發(fā)現(xiàn)Converter匿名類(lèi)重載方法中,調(diào)用了ReferenceTest的靜態(tài)方法String2Int。再有函數(shù)接口的方法參數(shù)類(lèi)型 和 返回值類(lèi)型,跟String2Int是一樣的,入?yún)镾tring,返回值為Integer。那我們這個(gè)時(shí)候可以簡(jiǎn)化成 直接用靜態(tài)方法進(jìn)行賦值,是不是很簡(jiǎn)潔。
七、實(shí)例方法引用 如果函數(shù)式接口的實(shí)現(xiàn)恰好可以通過(guò)調(diào)用一個(gè)實(shí)例的實(shí)例方法來(lái)實(shí)現(xiàn),那么就可以使用實(shí)例方法引用 ?
八、對(duì)象方法引用 抽象方法的第一個(gè)參數(shù)類(lèi)型剛好是實(shí)例方法的類(lèi)型(函數(shù)式接口的抽象方法必須要有輸入?yún)?shù))抽象方法剩余的參數(shù)恰好可以當(dāng)做實(shí)例方法的參數(shù)。
九、構(gòu)造方法引用 如果函數(shù)式接口的實(shí)現(xiàn)恰好可以通過(guò)調(diào)用一個(gè)類(lèi)的構(gòu)造方法來(lái)實(shí)現(xiàn),那么就可以使用構(gòu)造方法引用,語(yǔ)法【類(lèi)名::new】 上面是無(wú)參數(shù)的構(gòu)造函數(shù),再來(lái)看看有參構(gòu)造函數(shù) 到這里,來(lái)個(gè)方法引用的總結(jié):
十、總結(jié) Lambda表達(dá)式要熟練掌握,是要小伙伴們經(jīng)常去寫(xiě),才能夠運(yùn)用自如,代碼雖然比較簡(jiǎn)潔,但確實(shí)沒(méi)有接觸的開(kāi)發(fā)人員看上去,就懵逼了,可讀性不強(qiáng)。 閱讀原文:https://mp.weixin.qq.com/s/QhjAC15Y1w0evnRFu8BgDw 該文章在 2025/2/25 17:11:33 編輯過(guò) |
關(guān)鍵字查詢(xún)
相關(guān)文章
正在查詢(xún)... |