簡(jiǎn)單易懂的java8新特性之lambda表達(dá)式知識(shí)總結(jié)
一、概念
從本質(zhì)上來(lái)說(shuō),它就是一個(gè)匿名函數(shù),可以用來(lái)直接實(shí)現(xiàn)接口中的方法,從而簡(jiǎn)化代碼。但是Lambda有一個(gè)限制,不能實(shí)現(xiàn)接口中的所有方法,所以Lambda表達(dá)式只能用于有且僅有一個(gè)必須需要實(shí)現(xiàn)的方法接口,這里需要注意必須需要實(shí)現(xiàn)這六個(gè)字。
public interface Printer { //有一個(gè)需要實(shí)現(xiàn)的方法,可以使用Lambda表達(dá)式 void print(); }
public interface Printer { //有一個(gè)需要實(shí)現(xiàn)的方法,可以使用Lambda表達(dá)式 void print(); //這里雖然有一個(gè)方法,但接口提供了默認(rèn)實(shí)現(xiàn),因此不是必須要實(shí)現(xiàn)的 default void printDetail(){} }
public interface Printer { //有一個(gè)需要實(shí)現(xiàn)的方法,可以使用Lambda表達(dá)式 void print(); //這里雖然有一個(gè)需要實(shí)現(xiàn)的方法,但不是必須要實(shí)現(xiàn)的,因?yàn)閠oString()是Object類(lèi)中的. String toString(); }
public interface Printer { //有一個(gè)需要實(shí)現(xiàn)的方法,可以使用Lambda表達(dá)式 void print(); //這里雖然有一個(gè)需要實(shí)現(xiàn)的方法,但不是必須要實(shí)現(xiàn)的,因?yàn)閠oString()是Object類(lèi)中的. String toString(); }
像這種只有一個(gè)必須要實(shí)現(xiàn)的方法的接口,在java8中稱之為函數(shù)式接口,在定義接口時(shí)可以在接口名上方加上@FunctionInterface
標(biāo)簽,用于驗(yàn)證此接口是否為函數(shù)式接口。如果這個(gè)接口定義好之后不是函數(shù)式接口,那么接口名處會(huì)報(bào)錯(cuò)。
在使用Lambda表達(dá)式的時(shí)候,不需要關(guān)注方法名,只需要關(guān)注方法參數(shù)和返回值即可?;菊Z(yǔ)法很簡(jiǎn)單:
(參數(shù)列表)->{ 方法體 };
二、用法比較
java中實(shí)現(xiàn)接口的方式在java8之前有兩種:定義接口的實(shí)現(xiàn)類(lèi),使用匿名類(lèi),但Lambda表達(dá)式相比于這種方法都簡(jiǎn)單很多。以上文的Printer接口為例,實(shí)現(xiàn)如下:
2.1 實(shí)現(xiàn)類(lèi)
class PrinterImpl implements Printer{ @Override public void print() { System.out.println("Hello World"); } }
2.2 匿名類(lèi)
class PrinterAnonymous { Printer printer = new Printer() { @Override public void print() { System.out.println("Hello World"); } }; }
2.3 Lambda
class PrinterLambda{ Printer p = ()-> System.out.println("Hello World"); }
比較上文三種實(shí)現(xiàn)方式,很顯示Lambda的實(shí)現(xiàn)比前兩種簡(jiǎn)單很多。
三、基本用法
3.1 無(wú)參數(shù)無(wú)返回值接口方法
@FunctionalInterface public interface Printer { void print(); } public class Tester { public static void main(String[] args) { // 方法一,無(wú)返回值的情況,方法體只有一條語(yǔ)句,可以省略大括號(hào) Printer p1 = () -> System.out.println("Hello World 1"); p1.print(); // 方法二,標(biāo)準(zhǔn)定義 Printer p2 = () -> { System.out.println("Hello World 2"); }; p2.print(); } }
3.2 一個(gè)參數(shù)無(wú)返回值接口方法
@FunctionalInterface public interface Printer { void print(String str); } public class Tester { public static void main(String[] args) { // 方法一,無(wú)返回值的情況,方法體只有一條語(yǔ)句,可以省略大括號(hào) //因?yàn)檫@里只有一個(gè)參數(shù),小括號(hào)也可以省略,小括號(hào)省略的前提是:有且僅有一個(gè)參數(shù) //Printer p1 = s -> System.out.println(s); Printer p1 = (s) -> System.out.println(s); p1.print("Hello World 1"); // 方法二,無(wú)返回值的情況,方法體只有一條語(yǔ)句,可以省略大括號(hào) Printer p2 = (String s) -> System.out.println(s); p2.print("Hello World 2"); // 方法三,標(biāo)準(zhǔn)定義 Printer p3 = (String s) -> { System.out.println(s); }; p3.print("Hello World 3"); } }
3.3 多個(gè)參數(shù)無(wú)返回值接口方法
@FunctionalInterface public interface Printer { void print(String str1,String str2); } public class Tester { public static void main(String[] args) { // 方法一,無(wú)返回值的情況,方法體只有一條語(yǔ)句,可以省略大括號(hào) //參 Printer p1 = (s1,s2) -> System.out.println(s1+" "+s2); p1.print("Hello World 1","Java 1"); // 方法二,無(wú)返回值的情況,方法體只有一條語(yǔ)句,可以省略大括號(hào) Printer p2 = (String s1,String s2) -> System.out.println(s1+" "+s2); p2.print("Hello World 2","Java 2"); // 方法三,標(biāo)準(zhǔn)定義 Printer p3 = (String s1,String s2) -> { System.out.println(s1+" "+s2); }; p3.print("Hello World 3","Java 3"); } }
3.4 無(wú)參數(shù)有返回值接口方法
@FunctionalInterface public interface Printer { boolean print(); } public class Tester { public static void main(String[] args) { // 方法一,有返回值的情況,只有一條語(yǔ)句,return關(guān)鍵字的有無(wú)決定能否活力大括號(hào) Printer p1 = () -> true; boolean has1 = p1.print(); System.out.println(has1);//測(cè)試返回結(jié)果 // 方法二,標(biāo)準(zhǔn)定義 Printer p2 = () -> {return true;}; boolean has2 = p2.print(); System.out.println(has2);//測(cè)試返回結(jié)果 } }
3.5 一個(gè)參數(shù)有返回值接口方法
@FunctionalInterface public interface Printer { boolean print(boolean good); } public class Tester { public static void main(String[] args) { // 方法一,有返回值的情況,只有一條語(yǔ)句,return關(guān)鍵字的有無(wú)決定能否活力大括號(hào) //因?yàn)檫@里只有一個(gè)參數(shù),小括號(hào)也可以省略,小括號(hào)省略的前提是:有且僅有一個(gè)參數(shù) //Printer p1 = good -> good; Printer p1 = (good) -> good; boolean has1 = p1.print(true); System.out.println(has1); // 方法二,標(biāo)準(zhǔn)定義 Printer p2 = (good) -> {return good;}; boolean has2 = p2.print(false); System.out.println(has2); } }
3.6 多個(gè)參數(shù)有返回值接口方法
@FunctionalInterface public interface Printer { boolean print(boolean good1,boolean good2); } public class Tester { public static void main(String[] args) { // 方法一,有返回值的情況,只有一條語(yǔ)句,return關(guān)鍵字的有無(wú)決定能否活力大括號(hào) Printer p1 = (good1,good2) -> good1; boolean has1 = p1.print(true,false); System.out.println(has1); // 方法二,標(biāo)準(zhǔn)定義 Printer p2 = (good1,good2) -> {return good1;}; boolean has2 = p2.print(false,false); System.out.println(has2); } }
四、函數(shù)引用
在實(shí)現(xiàn)一個(gè)接口的方法時(shí),如果現(xiàn)有的其他地方的某個(gè)函數(shù)已經(jīng)實(shí)現(xiàn)了接口方法的邏輯,可以使用方法引用直接將這個(gè)邏輯引用過(guò)來(lái)。
4.1 靜態(tài)方法引用
語(yǔ)法:
接口名 變量名 = 類(lèi) ::已實(shí)現(xiàn)的方法
注意事項(xiàng):
- 在引用的方法后面,不要添加小括號(hào)
- 引用的這個(gè)方法,參數(shù)和返回值,必須要跟接口中定義的一致
示例:
Printer 需要實(shí)現(xiàn)的方法在Checker中有同樣的實(shí)現(xiàn),這樣就可以直接引用過(guò)來(lái)
@FunctionalInterface public interface Printer { String print(boolean good1,boolean good2); } public class Checker { public static String check(boolean a,boolean b) { if(a && b) { return "Java is good"; }else if (!a && b) { return "Java is better"; } return "Java is best"; } } public class Tester { public static void main(String[] args) { Printer p1 = Checker::check;//用類(lèi)名來(lái)引用 System.out.println(p1.print(true, true)); } }
4.2 非靜態(tài)方法引用
語(yǔ)法:
接口名 變量名 = 對(duì)象 ::靜態(tài)方法
注意事項(xiàng):
- 在引用的方法后面,不要添加小括號(hào)
- 引用的這個(gè)方法,參數(shù)和返回值,必須要跟接口中定義的一致
示例:
Printer 需要實(shí)現(xiàn)的方法在Checker中有同樣的實(shí)現(xiàn),這樣就可以直接引用過(guò)來(lái)
@FunctionalInterface public interface Printer { String print(boolean good1,boolean good2); } public class Checker { public String check(boolean a,boolean b) { if(a && b) { return "Java is good"; }else if (!a && b) { return "Java is better"; } return "Java is best"; } } public class Tester { public static void main(String[] args) { Printer p1 = new Checker()::check;//必須用對(duì)象來(lái)引用 System.out.println(p1.print(true, true)); } }
4.3 構(gòu)造方法的引用
如果一個(gè)函數(shù)式接口中定義的方法僅僅是為了得到一個(gè)對(duì)象,此時(shí)我們就可以使用構(gòu)造方法的引用,簡(jiǎn)化這個(gè)方法的實(shí)現(xiàn)
語(yǔ)法:
接口名 變量名 = 類(lèi)名 ::new
注意事項(xiàng):
可以通過(guò)接口中的方法參數(shù),區(qū)分引用不同的構(gòu)造方法
示例:
@FunctionalInterface public interface Printer1 { Checker getCheck(); } @FunctionalInterface public interface Printer2 { Checker getCheck(int a); } public class Checker { int times; public Checker() { System.out.println("I am none parameter"); } public Checker(int a) { System.out.println("I have one parameter"); } } public class Tester { public static void main(String[] args) { //引用無(wú)參構(gòu)造方法 Printer1 p1 = Checker::new; p1.getCheck(); //引用有參構(gòu)造方法 Printer2 p2 = Checker::new; p2.getCheck(1); } }
4.4 對(duì)象方法的特殊引用
如果實(shí)現(xiàn)某些接口的時(shí)候,Lambda表達(dá)式中包含了某一個(gè)對(duì)象,此時(shí)方法體中,直接使用這個(gè)對(duì)象調(diào)用它的某一個(gè)方法就可以完成整個(gè)的邏輯。其他的參數(shù),可以作為調(diào)用方法的參數(shù)。此時(shí),可以對(duì)這種實(shí)現(xiàn)進(jìn)行簡(jiǎn)化。
示例:
@FunctionalInterface public interface Printer1 { int getCheck(Checker checker); } @FunctionalInterface public interface Printer2 { void setCheck(Checker checker, int a); } public class Tester { public static void main(String[] args) { Checker checker = new Checker(); checker.setTimes(100); // 沒(méi)有簡(jiǎn)化前,按照之前的方法使用lambda表達(dá)式 Printer1 p1 = x -> x.getTimes(); System.out.println(p1.getCheck(checker));//測(cè)試 // 簡(jiǎn)化之后 Printer1 p11 = Checker::getTimes; System.out.println(p11.getCheck(checker));//測(cè)試 // 沒(méi)有簡(jiǎn)化前,按照之前的方法使用lambda表達(dá)式 Printer2 p2 = (x,y)-> x.setTimes(y); p2.setCheck(checker, 50); System.out.println(checker.getTimes());//測(cè)試 // 簡(jiǎn)化之后 Printer2 p22 = Checker::setTimes; p22.setCheck(checker, 30); System.out.println(checker.getTimes());//測(cè)試 } }
五、注意
當(dāng)在Lambda表達(dá)式中使用了某一個(gè)局部變量,那么這個(gè)局部變量的值在Lambda表達(dá)式之外,不可以被改變,因?yàn)槟J(rèn)將其定義成final常量。但全局變量變量沒(méi)有這方面的限制。
示例:
@FunctionalInterface public interface Printer { void setTime(); } public class Tester { public static void main(String[] args) { int time = 10; Printer p = () -> System.out.println(time);//這里出錯(cuò)了,因?yàn)橄乱恍袑?duì)time進(jìn)行修改 time = 15;//這里的值不能改變,會(huì)導(dǎo)致上一行出錯(cuò) } }
基本概括了Lambda表達(dá)式的所有用法,不足之處,請(qǐng)諒解,謝謝!
到此這篇關(guān)于簡(jiǎn)單易懂的java8新特性之lambda表達(dá)式知識(shí)總結(jié)的文章就介紹到這了,更多相關(guān)java lambda表達(dá)式內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- Java8新特性:lambda表達(dá)式總結(jié)
- JAVA8 lambda表達(dá)式權(quán)威教程
- Java8新特性之Lambda表達(dá)式的使用
- 詳解Java8中的lambda表達(dá)式、::符號(hào)和Optional類(lèi)
- java8 多個(gè)list對(duì)象用lambda求差集操作
- java8 forEach結(jié)合Lambda表達(dá)式遍歷 List操作
- Java8 Lambda表達(dá)式模板方法實(shí)現(xiàn)解析
- Java8 lambda表達(dá)式2種常用方法代碼解析
- Java8 Lambda和Invokedynamic詳情
相關(guān)文章
如何使用IDEA創(chuàng)建MAPPER模板過(guò)程圖解
這篇文章主要介紹了如何使用IDEA創(chuàng)建MAPPER模板,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-05-05Spring?Security實(shí)現(xiàn)基于RBAC的權(quán)限表達(dá)式動(dòng)態(tài)訪問(wèn)控制的操作方法
這篇文章主要介紹了Spring?Security實(shí)現(xiàn)基于RBAC的權(quán)限表達(dá)式動(dòng)態(tài)訪問(wèn)控制,資源權(quán)限表達(dá)式動(dòng)態(tài)權(quán)限控制在Spring Security也是可以實(shí)現(xiàn)的,首先開(kāi)啟方法級(jí)別的注解安全控制,本文結(jié)合實(shí)例代碼給大家介紹的非常詳細(xì),需要的朋友可以參考下2022-04-04Java使用OpenOffice將office文件轉(zhuǎn)換為PDF的示例方法
OpenOffice是一個(gè)開(kāi)源的辦公套件,它包含了文檔處理、電子表格、演示文稿以及繪圖等多種功能,類(lèi)似于Microsoft Office,本文將給大家介紹Java使用OpenOffice將office文件轉(zhuǎn)換為PDF的示例方法,需要的朋友可以參考下2024-09-09多數(shù)據(jù)源如何實(shí)現(xiàn)事務(wù)管理
Spring中涉及三個(gè)核心事務(wù)處理接口:PlatformTransactionManager、TransactionDefinition和TransactionStatus,PlatformTransactionManager提供事務(wù)操作的基本方法,如獲取事務(wù)、提交和回滾2024-09-09java synchronized同步靜態(tài)方法和同步非靜態(tài)方法的異同
這篇文章主要介紹了java synchronized同步靜態(tài)方法和同步非靜態(tài)方法的異同的相關(guān)資料,需要的朋友可以參考下2017-01-01Java 如何從spring容器中獲取注入的bean對(duì)象
這篇文章主要介紹了Java 如何從spring容器中獲取注入的bean對(duì)象,幫助大家更好的理解和使用Java,感興趣的朋友可以了解下2020-11-11volatile可見(jiàn)性的一些認(rèn)識(shí)和論證
volatile的關(guān)鍵詞的使用在JVM內(nèi)存模型中已是老生常談了,這篇文章主要結(jié)合自己對(duì)可見(jiàn)性的一些認(rèn)識(shí)和一些直觀的例子來(lái)談?wù)剉olatile,感興趣的朋友一起看看吧2017-08-08SpringBoot集成 Prometheus進(jìn)行高效監(jiān)控的實(shí)現(xiàn)
Prometheus作為一個(gè)開(kāi)源的監(jiān)控和告警工具,以其強(qiáng)大的數(shù)據(jù)采集、存儲(chǔ)和查詢能力,受到了眾多開(kāi)發(fā)者的青睞,本文主要介紹了SpringBoot集成 Prometheus進(jìn)行高效監(jiān)控的實(shí)現(xiàn),感興趣的可以了解一下2024-07-07