一文帶你徹底搞懂Lambda表達(dá)式
1. 為什么使用Lambda表達(dá)式
Lambda是一個(gè)匿名函數(shù),我們可以把Lambda表達(dá)式理解為是一段可以傳遞的代碼(將代碼像數(shù)據(jù)一樣進(jìn)行傳遞)。可以寫(xiě)出更簡(jiǎn)潔、更靈活的代碼。作為一種更緊湊的代碼風(fēng)格,使Java的語(yǔ)言表達(dá)能力得到了提升。
我們來(lái)看一下使用lambda之前創(chuàng)建匿名內(nèi)部類:
new Thread(new Runnable() { @Override public void run() { System.out.println("執(zhí)行Runnable方法"); } });
lambda表達(dá)式:
new Thread(() -> System.out.println("執(zhí)行Runnable方法")); // 無(wú)參Lambda表達(dá)式
在Idea中遇到可以轉(zhuǎn)換lambda的代碼會(huì)有灰色提示,按alt+enter可自動(dòng)轉(zhuǎn)換:
2. Lambda語(yǔ)法
Java8中引入了一個(gè)新的操作符"->”該操作符稱為箭頭操作符或Lambda 操作符。
箭頭操作符將Lambda表達(dá)式拆分成兩部分:
左側(cè): Lambda表達(dá)式的參數(shù)列表
右側(cè): Lambda表達(dá)式中所需執(zhí)行的功能,即Lambda體
示例:
語(yǔ)法格式一:無(wú)參數(shù),無(wú)返回值。
Runnable r = () -> System.out.println("Hello World");
r.run();
語(yǔ)法格式二:有一個(gè)參數(shù),并且無(wú)返回值。
Consumer consumer = (x) -> System.out.println(x); //或者寫(xiě)成: x -> System. out.println(x); 只有一個(gè)參數(shù),括號(hào)可以省略 consumer.accept("Hello");
語(yǔ)法格式三:有兩個(gè)以上的參數(shù),有返回值,并且Lambda體中有多條語(yǔ)句。
Comparator<Integer> comparator = (x, y) -> { System.out.println("Hello"); return Integer.compare(x, y); }; TreeSet<Integer> treeSet = new TreeSet<>(comparator);
語(yǔ)法格式四:若Lambda體中只有一條語(yǔ)句,return 和大括號(hào)都可以省略不寫(xiě),Lambda 表達(dá)式的參數(shù)列表的數(shù)據(jù)類型可以省略不寫(xiě),因?yàn)镴VM編譯器通過(guò)上下文推斷出數(shù)據(jù)類型,即類型推斷
Comparator<Integer> com = (x, y) -> Integer .compare(x, y);
關(guān)于類型推斷,其實(shí)在數(shù)組中我們?cè)缫呀?jīng)使用過(guò):
String[] strArr = {"a","b", "c"}; // 類型推斷 // 寫(xiě)成下面這種方式則編譯報(bào)錯(cuò) String [] strArr; strArr = {"a","b", "c"}; // 還有List的類型推斷: List<String> list = new ArrayList<>();
3. 函數(shù)式編程接口
上面我們看到的lambda表達(dá)式,其實(shí)都依賴于接口的支持,lambda表達(dá)式的本質(zhì)是對(duì)接口的一種實(shí)現(xiàn)。這種接口稱為函數(shù)式接口,即接口中只有一個(gè)抽象方法的接口。函數(shù)式接口可以使用@FunctionInterface注解修飾,表示被修飾的接口必須是函數(shù)式接口。
// 函數(shù)式接口只能有一個(gè)抽象方法 @FunctionalInterface public interface FuncTest { void accept(Object o); }
如果在函數(shù)式接口中寫(xiě)兩個(gè)以上的方法,編譯會(huì)報(bào)錯(cuò):
我們來(lái)自己寫(xiě)一個(gè)實(shí)際的例子了解下函數(shù)式接口的使用:
// 1.寫(xiě)一個(gè)對(duì)傳入?yún)?shù)進(jìn)行操作的函數(shù)式接口 @FunctionalInterface public interface FuncTest { void operation(Integer x); } // 2.寫(xiě)一個(gè)方法,將函數(shù)式,接口作為參數(shù) private static Integer operate(Integer a, FuncTest funcTest) { return funcTest.operation(a); } // 3.使用函數(shù)式接口 System.out.println(operate(1, (x) -> x + x)); // 輸出 2
可以看到,我們?cè)诘?步才開(kāi)始定義函數(shù)式接口的實(shí)際功能,對(duì)兩個(gè)數(shù)進(jìn)行相加操作并返回結(jié)果。lambda的最大便捷之處就在于此,將代碼作為參數(shù)傳遞,非常靈活,大大精簡(jiǎn)我們的代碼。
4. Java8內(nèi)置的4種常用函數(shù)式接口
Consumer :消費(fèi)型接口
方法:void accept(T t);
Consumer<String> consumer = x -> System.out.println(x);
consumer.accept("Hello"); // 打印Hello
Supplier :供給型接口
方法:T get();
Supplier<String> supplier = () -> "Hello";
System.out.println(supplier.get()); // 打印Hello
Function<T, R> :函數(shù)型接口
方法:R apply(T t);
Function function = x -> "Hello " + x;
System.out.println(function.apply("World"));
Predicate :斷言型接口
方法:boolean test(T t);
Predicate predicate = x -> x == "Hello";
System.out.println(predicate.test("Hello"));
ava.util.function 它包含了很多類,用來(lái)支持 Java的 函數(shù)式編程,該包中的函數(shù)式接口有:
5. 總結(jié)
Java8引入lambda表達(dá)式是接收了函數(shù)式編程語(yǔ)言的思想,例如scala之類的,它將函數(shù)視為一等公民,可以使用高階函數(shù)等。和指令式編程相比,函數(shù)式編程強(qiáng)調(diào)函數(shù)的計(jì)算比指令的執(zhí)行重要。和過(guò)程化編程相比,函數(shù)式編程里函數(shù)的計(jì)算可隨時(shí)調(diào)用。
lambda表達(dá)式可以使代碼看起來(lái)簡(jiǎn)潔,但一定程度上增加了代碼的可讀性以及調(diào)試的復(fù)雜性,所以在使用時(shí)應(yīng)盡量是團(tuán)隊(duì)都熟悉使用,要么干脆就別用,不然維護(hù)起來(lái)是件較痛苦的事。
以上這篇一文帶你徹底搞懂Lambda表達(dá)式就是小編分享給大家的全部?jī)?nèi)容了,希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
SpringMVC @RequestBody Date類型的Json轉(zhuǎn)換方式
這篇文章主要介紹了SpringMVC @RequestBody Date類型的Json轉(zhuǎn)換方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-10-10Java實(shí)現(xiàn)發(fā)送手機(jī)短信語(yǔ)音驗(yàn)證功能代碼實(shí)例
這篇文章主要介紹了Java實(shí)現(xiàn)發(fā)送手機(jī)短信語(yǔ)音驗(yàn)證功能代碼實(shí)例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2019-09-09Elasticsearch?mapping?概念及自動(dòng)創(chuàng)建示例
這篇文章主要為大家介紹了Elasticsearch?mapping?概念及自動(dòng)創(chuàng)建示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-11-11springboot中.yml文件的值無(wú)法讀取的問(wèn)題及解決
這篇文章主要介紹了springboot中.yml文件的值無(wú)法讀取的問(wèn)題及解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-02-02ThreadPoolExecutor中的submit()方法詳細(xì)講解
在使用線程池的時(shí)候,發(fā)現(xiàn)除了execute()方法可以執(zhí)行任務(wù)外,還發(fā)現(xiàn)有一個(gè)方法submit()可以執(zhí)行任務(wù),本文就詳細(xì)的介紹一下ThreadPoolExecutor中的submit()方法,具有一定的參考價(jià)值,感興趣的可以了解一下2022-04-04解決@Value注解不能注入static修飾的屬性問(wèn)題
這篇文章主要介紹了解決@Value注解不能注入static修飾的屬性問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-07-07idea2020.2卡死在reading maven projects
這篇文章主要介紹了idea2020.2卡死在reading maven projects,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-09-09Java 高并發(fā)七:并發(fā)設(shè)計(jì)模型詳解
本文主要介紹Java高并發(fā) 并發(fā)設(shè)計(jì)模型的知識(shí),這里主要講解 1. 什么是設(shè)計(jì)模式 2. 單例模式 3. 不變模式 4. Future模式 5. 生產(chǎn)者消費(fèi)者,有需要的小伙伴可以參考下2016-09-09