一、Lambda簡介
Lambda 表達(dá)式是 JDK8 的一個(gè)新特性酪我,可以取代大部分的匿名內(nèi)部類消痛,寫出更優(yōu)雅的 Java 代碼,尤其在集合的遍歷和其他集合操作中都哭,可以極大地優(yōu)化代碼結(jié)構(gòu)秩伞。
JDK 也提供了大量的內(nèi)置函數(shù)式接口供我們使用,使得 Lambda 表達(dá)式的運(yùn)用更加方便欺矫、高效纱新。
Lambda表達(dá)式允許把函數(shù)作為一個(gè)方法的參數(shù)(函數(shù)作為參數(shù)傳遞到方法中)。lambda表達(dá)式是一個(gè)可傳遞的代碼塊汇陆,可以在以后執(zhí)行一次或多次怒炸,它可以傳遞到函數(shù)式接口带饱。
二毡代、Lambda 基礎(chǔ)語法
語法形式為 () -> {},其中 () 用來描述參數(shù)列表勺疼,{} 用來描述方法體教寂,-> 為 lambda運(yùn)算符 ,讀作(goes to)执庐。
(parameters) -> expression
或
(parameters) ->{ statements; }
Lambda 語法簡化
1.簡化參數(shù)類型酪耕,可以不寫參數(shù)類型,但是必須所有參數(shù)都不寫轨淌;
2.簡化參數(shù)小括號迂烁,如果只有一個(gè)參數(shù)則可以省略參數(shù)小括號;
3.簡化方法體大括號递鹉,如果方法條只有一條語句盟步,則可以省略方法體大括號;
4.簡化返回關(guān)鍵字躏结,如果方法體只有一條語句却盘,并且是 return 語句,則可以省略方法體大括號及返回關(guān)鍵字return媳拴。
三黄橘、變量作用域
Lambda表達(dá)式只能引用標(biāo)記了final的外層局部變量,即不能在Lambda內(nèi)部修改定義在外層的局部變量屈溉,否則會編譯報(bào)錯(cuò)塞关。外層的局部變量可以不用聲明為final,但是必須不可被后面的代碼修改(即隱性的具有final的語義)子巾。
在Lambda表達(dá)式中不允許聲明一個(gè)與外層的局部變量同名的參數(shù)或者局部變量帆赢。
四驶睦、方法引用
方法引用通過方法的名字來指向一個(gè)方法,可以使語言的構(gòu)造更緊湊簡潔匿醒,減少冗余代碼场航,方法引用使用一對冒號 :: 。
語法
? 方法歸屬者::方法名 靜態(tài)方法的歸屬者為類名廉羔,普通方法歸屬者為對象溉痢。
構(gòu)造器引用:它的語法是Class::new,或者更一般的Class< T >::new憋他。
靜態(tài)方法引用:它的語法是Class::static_method孩饼。
特定類的任意對象的方法引用:它的語法是Class::method。
特定對象的方法引用:它的語法是instance::method竹挡。
五镀娶、函數(shù)式接口
函數(shù)式接口(Functional Interface)就是一個(gè)有且僅有一個(gè)抽象方法,但是可以有多個(gè)非抽象方法的接口揪罕。
函數(shù)式接口可以被隱式轉(zhuǎn)換為 lambda 表達(dá)式梯码。
JDK 1.8 之前已有的函數(shù)式接口:
java.lang.Runnable
java.util.concurrent.Callable
java.security.PrivilegedAction
java.util.Comparator
java.io.FileFilter
java.nio.file.PathMatcher
java.lang.reflect.InvocationHandler
java.beans.PropertyChangeListener
java.awt.event.ActionListener
javax.swing.event.ChangeListener
JDK 1.8 新增加的函數(shù)接口:
java.util.function
java.util.function 它包含了很多類,用來支持 Java的函數(shù)式編程好啰。
1.新注解@FunctionalInterface
Java 8為函數(shù)式接口引入了一個(gè)新注解@FunctionalInterface轩娶,主要用于編譯級錯(cuò)誤檢查,加上該注解框往,當(dāng)你寫的接口不符合函數(shù)式接口定義的時(shí)候鳄抒,編譯器會報(bào)錯(cuò)。
提醒:加不加 @FunctionalInterface 對于接口是不是函數(shù)式接口沒有影響椰弊,該注解只是提醒編譯器去檢查該接口是否僅包含一個(gè)抽象方法许溅。
2.函數(shù)式接口里允許定義默認(rèn)方法
函數(shù)式接口里可以包含默認(rèn)方法,因?yàn)槟J(rèn)方法不是抽象方法秉版,其有一個(gè)默認(rèn)實(shí)現(xiàn)贤重,所以是符合函數(shù)式接口的定義的。
實(shí)現(xiàn)接口后沐飘,因?yàn)槟J(rèn)方法不是抽象方法游桩,所以可以不重寫,但是如果開發(fā)需要耐朴,也可以重寫 借卧。如果接口中的默認(rèn)方法不能滿足某個(gè)實(shí)現(xiàn)類需要,那么實(shí)現(xiàn)類可以覆蓋默認(rèn)方法筛峭。簽名跟接口default方法一致铐刘,但是不能再加default修飾符。
3.函數(shù)式接口里允許定義 java.lang.Object 里的 public 方法
函數(shù)式接口里是可以包含Object里的public方法影晓,這些方法對于函數(shù)式接口來說镰吵,不被當(dāng)成是抽象方法(雖然它們是抽象方法)檩禾;因?yàn)槿魏我粋€(gè)函數(shù)式接口的實(shí)現(xiàn),默認(rèn)都繼承了 Object 類疤祭,包含了來自 java.lang.Object 里對這些抽象方法的實(shí)現(xiàn)盼产。
4.常用函數(shù)式接口
Supplier<T>,主要方法:T get(),這是一個(gè)生產(chǎn)者,可以提供一個(gè)T對象勺馆。
Consumer<T>,主要方法:void accept(T),這是一個(gè)消費(fèi)者戏售,默認(rèn)方法:andthen(),稍后執(zhí)行草穆。
Predicate<T>,主要方法:boolean test(T t),這是一個(gè)判斷者灌灾,接受一個(gè)輸入?yún)?shù) T,返回一個(gè)布爾值結(jié)果悲柱。默認(rèn)方法:and():且锋喜,or():或,negate():非豌鸡。
Function<T,R>,主要方法:R apply(T t),這是一個(gè)修改者嘿般,默認(rèn)方法:compose():優(yōu)先執(zhí)行,andThen(),稍后執(zhí)行直颅,identity():直接傳自身博个。