java8保姆級(jí)lambda表達(dá)式教程
1.替代匿名內(nèi)部類
毫無(wú)疑問(wèn),lambda表達(dá)式用得最多的場(chǎng)合就是替代匿名內(nèi)部類,而實(shí)現(xiàn)Runnable接口是匿名內(nèi)部類的經(jīng)典例子。lambda表達(dá)式的功能相當(dāng)強(qiáng)大,用()->就可以代替整個(gè)匿名內(nèi)部類!請(qǐng)看代碼:
如果使用匿名內(nèi)部類:
@Test public void oldRunable() { new Thread(new Runnable() { @Override public void run() { System.out.println("The old runable now is using!"); } }).start(); }
而如果使用lambda表達(dá)式:
@Test public void runable() { new Thread(() -> System.out.println("It's a lambda function!")).start(); }
最后的輸出:
The old runable now is using!
It's a lambda function!
是不是強(qiáng)大到可怕?是不是簡(jiǎn)單到可怕?是不是清晰明了重點(diǎn)突出到可怕?這就是lambda表達(dá)式的可怕之處,用極少的代碼完成了之前一個(gè)類做的事情!
2.使用lambda表達(dá)式對(duì)集合進(jìn)行迭代
Java的集合類是日常開發(fā)中經(jīng)常用到的,甚至說(shuō)沒(méi)有哪個(gè)java代碼中沒(méi)有使用到集合類。。。而對(duì)集合類最常見的操作就是進(jìn)行迭代遍歷了。請(qǐng)看對(duì)比:
@Test public void iterTest() { List<String> languages = Arrays.asList("java","scala","python"); //before java8 for(String each:languages) { System.out.println(each); } //after java8 languages.forEach(x -> System.out.println(x)); languages.forEach(System.out::println); }
如果熟悉scala的同學(xué),肯定對(duì)forEach不陌生。它可以迭代集合中所有的對(duì)象,并且將lambda表達(dá)式帶入其中。
languages.forEach(System.out::println);
這一行看起來(lái)有點(diǎn)像c++里面作用域解析的寫法,在這里也是可以的。
3.用lambda表達(dá)式實(shí)現(xiàn)map
一提到函數(shù)式編程,一提到lambda表達(dá)式,怎么能不提map。。。沒(méi)錯(cuò),java8肯定也是支持的。請(qǐng)看示例代碼:
@Test public void mapTest() { List<Double> cost = Arrays.asList(10.0, 20.0,30.0); cost.stream().map(x -> x + x*0.05).forEach(x -> System.out.println(x)); }
最后的輸出結(jié)果:
10.5
21.0
31.5
map函數(shù)可以說(shuō)是函數(shù)式編程里最重要的一個(gè)方法了。map的作用是將一個(gè)對(duì)象變換為另外一個(gè)。在我們的例子中,就是通過(guò)map方法將cost增加了0,05倍的大小然后輸出。
4.用lambda表達(dá)式實(shí)現(xiàn)map與reduce
既然提到了map,又怎能不提到reduce。reduce與map一樣,也是函數(shù)式編程里最重要的幾個(gè)方法之一。。。map的作用是將一個(gè)對(duì)象變?yōu)榱硗庖粋€(gè),而reduce實(shí)現(xiàn)的則是將所有值合并為一個(gè),請(qǐng)看:
@Test public void mapReduceTest() { List<Double> cost = Arrays.asList(10.0, 20.0,30.0); double allCost = cost.stream().map(x -> x+x*0.05).reduce((sum,x) -> sum + x).get(); System.out.println(allCost); }
最終的結(jié)果為:
63.0
如果我們用for循環(huán)來(lái)做這件事情:
@Test public void sumTest() { List<Double> cost = Arrays.asList(10.0, 20.0,30.0); double sum = 0; for(double each:cost) { each += each * 0.05; sum += each; } System.out.println(sum); }
相信用map+reduce+lambda表達(dá)式的寫法高出不止一個(gè)level。
5.filter操作
filter也是我們經(jīng)常使用的一個(gè)操作。在操作集合的時(shí)候,經(jīng)常需要從原始的集合中過(guò)濾掉一部分元素。
@Test public void filterTest() { List<Double> cost = Arrays.asList(10.0, 20.0,30.0,40.0); List<Double> filteredCost = cost.stream().filter(x -> x > 25.0).collect(Collectors.toList()); filteredCost.forEach(x -> System.out.println(x)); }
最后的結(jié)果:
30.0
40.0
將java寫出了python或者scala的感覺(jué)有沒(méi)有!是不是帥到爆!
6.與函數(shù)式接口Predicate配合
除了在語(yǔ)言層面支持函數(shù)式編程風(fēng)格,Java 8也添加了一個(gè)包,叫做 java.util.function。它包含了很多類,用來(lái)支持Java的函數(shù)式編程。其中一個(gè)便是Predicate,使用 java.util.function.Predicate 函數(shù)式接口以及l(fā)ambda表達(dá)式,可以向API方法添加邏輯,用更少的代碼支持更多的動(dòng)態(tài)行為。Predicate接口非常適用于做過(guò)濾。
public static void filterTest(List<String> languages, Predicate<String> condition) { languages.stream().filter(x -> condition.test(x)).forEach(x -> System.out.println(x + " ")); } public static void main(String[] args) { List<String> languages = Arrays.asList("Java","Python","scala","Shell","R"); System.out.println("Language starts with J: "); filterTest(languages,x -> x.startsWith("J")); System.out.println("\nLanguage ends with a: "); filterTest(languages,x -> x.endsWith("a")); System.out.println("\nAll languages: "); filterTest(languages,x -> true); System.out.println("\nNo languages: "); filterTest(languages,x -> false); System.out.println("\nLanguage length bigger three: "); filterTest(languages,x -> x.length() > 4); }
最后的輸出結(jié)果:
Language starts with J:
JavaLanguage ends with a:
Java
scalaAll languages:
Java
Python
scala
Shell
RNo languages:
Language length bigger three:
Python
scala
Shell
可以看到,Stream API的過(guò)濾方法也接受一個(gè)Predicate,這意味著可以將我們定制的 filter() 方法替換成寫在里面的內(nèi)聯(lián)代碼,這也是lambda表達(dá)式的魔力!
到此這篇關(guān)于java8手把手教你學(xué)會(huì)寫lambda表達(dá)式的文章就介紹到這了,更多相關(guān)java8教你學(xué)會(huì)lambda表達(dá)式內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
java開發(fā)微服務(wù)架構(gòu)設(shè)計(jì)消息隊(duì)列的水有多深
今天我們說(shuō)說(shuō)消息隊(duì)列的問(wèn)題,來(lái)帶大家探一探消息隊(duì)列的水有多深,希望看完本文大家在引入消息隊(duì)列的時(shí)候先想一想,是不是一定要引入?引入消息隊(duì)列后產(chǎn)生的問(wèn)題能不能解決2021-10-10Java long 轉(zhuǎn)成 String的實(shí)現(xiàn)
這篇文章主要介紹了Java long 轉(zhuǎn)成 String的實(shí)現(xiàn),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-09-09SpringBoot使用MyBatis時(shí)的幾種傳參規(guī)范示例
使用Mybatis作為持久層框架時(shí),對(duì)于數(shù)據(jù)庫(kù)的增刪改查等操作都需要參數(shù)的傳遞,本文就詳細(xì)的介紹了一下SpringBoot使用MyBatis時(shí)的幾種傳參規(guī)范示例,感興趣的可以了解一下2022-02-02JavaWeb實(shí)現(xiàn)郵件發(fā)送功能
這篇文章主要為大家詳細(xì)介紹了JavaWeb實(shí)現(xiàn)郵件發(fā)送功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-12-12Java中避免NullPointerException的方法總結(jié)
這篇文章主要介紹了Java中避免NullPointerException的方法總結(jié)的相關(guān)資料,需要的朋友可以參考下2017-07-07Springboot?異步任務(wù)和定時(shí)任務(wù)的異步處理
本文介紹了Springboot異步任務(wù)和定時(shí)任務(wù)的異步處理,Springboot?中,異步任務(wù)和定時(shí)任務(wù)是經(jīng)常遇到的處理問(wèn)題方式,為了能夠用好這兩項(xiàng)配置,不干擾正常的業(yè)務(wù),需要對(duì)其進(jìn)行異步化配置。怎么設(shè)置合理的異步處理線程就是其核心和關(guān)鍵,下文詳情需要的朋友可以參考下2022-05-05java8 對(duì)象轉(zhuǎn)Map時(shí)重復(fù) key Duplicate key xxxx的解決
這篇文章主要介紹了java8 對(duì)象轉(zhuǎn)Map時(shí)重復(fù) key Duplicate key xxxx的解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-09-09