一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務(wù)器之家:專注于服務(wù)器技術(shù)及軟件下載分享
分類導(dǎo)航

PHP教程|ASP.NET教程|JAVA教程|ASP教程|

服務(wù)器之家 - 編程語(yǔ)言 - JAVA教程 - Java8新特性lambda表達(dá)式有什么用(用法實(shí)例)

Java8新特性lambda表達(dá)式有什么用(用法實(shí)例)

2019-11-23 17:28Java教程網(wǎng) JAVA教程

這篇文章主要介紹了Java8新特性lambda表達(dá)式有什么用,著重以實(shí)例講解lambda表達(dá)式,需要的朋友可以參考下

我們期待了很久lambda為java帶來(lái)閉包的概念,但是如果我們不在集合中使用它的話,就損失了很大價(jià)值。現(xiàn)有接口遷移成為lambda風(fēng)格的問(wèn)題已經(jīng)通過(guò)default methods解決了,在這篇文章將深入解析Java集合里面的批量數(shù)據(jù)操作(bulk operation),解開lambda最強(qiáng)作用的神秘面紗。

1.關(guān)于JSR335

JSR是Java Specification Requests的縮寫,意思是Java 規(guī)范請(qǐng)求,Java 8 版本的主要改進(jìn)是 Lambda 項(xiàng)目(JSR 335),其目的是使 Java 更易于為多核處理器編寫代碼。JSR 335=lambda表達(dá)式+接口改進(jìn)(默認(rèn)方法)+批量數(shù)據(jù)操作。加上前面兩篇,我們已是完整的學(xué)習(xí)了JSR335的相關(guān)內(nèi)容了。

2.外部VS內(nèi)部迭代

以前Java集合是不能夠表達(dá)內(nèi)部迭代的,而只提供了一種外部迭代的方式,也就是for或者while循環(huán)。

復(fù)制代碼代碼如下:

List persons = asList(new Person("Joe"), new Person("Jim"), new Person("John"));
for (Person p :  persons) {
   p.setLastName("Doe");
}

 

上面的例子是我們以前的做法,也就是所謂的外部迭代,循環(huán)是固定的順序循環(huán)。在現(xiàn)在多核的時(shí)代,如果我們想并行循環(huán),不得不修改以上代碼。效率能有多大提升還說(shuō)定,且會(huì)帶來(lái)一定的風(fēng)險(xiǎn)(線程安全問(wèn)題等等)。 

要描述內(nèi)部迭代,我們需要用到Lambda這樣的類庫(kù),下面利用lambda和Collection.forEach重寫上面的循環(huán)

復(fù)制代碼代碼如下:
persons.forEach(p->p.setLastName("Doe"));


現(xiàn)在是由jdk 庫(kù)來(lái)控制循環(huán)了,我們不需要關(guān)心last name是怎么被設(shè)置到每一個(gè)person對(duì)象里面去的,庫(kù)可以根據(jù)運(yùn)行環(huán)境來(lái)決定怎么做,并行,亂序或者懶加載方式。這就是內(nèi)部迭代,客戶端將行為p.setLastName當(dāng)做數(shù)據(jù)傳入api里面。 

內(nèi)部迭代其實(shí)和集合的批量操作并沒有密切的聯(lián)系,借助它我們感受到語(yǔ)法表達(dá)上的變化。真正有意思的和批量操作相關(guān)的是新的流(stream)API。新的java.util.stream包已經(jīng)添加進(jìn)JDK 8了。

 

3.Stream API

流(Stream)僅僅代表著數(shù)據(jù)流,并沒有數(shù)據(jù)結(jié)構(gòu),所以他遍歷完一次之后便再也無(wú)法遍歷(這點(diǎn)在編程時(shí)候需要注意,不像Collection,遍歷多少次里面都還有數(shù)據(jù)),它的來(lái)源可以是Collection、array、io等等。

3.1中間與終點(diǎn)方法

流作用是提供了一種操作大數(shù)據(jù)接口,讓數(shù)據(jù)操作更容易和更快。它具有過(guò)濾、映射以及減少遍歷數(shù)等方法,這些方法分兩種:中間方法和終端方法,“流”抽象天生就該是持續(xù)的,中間方法永遠(yuǎn)返回的是Stream,因此如果我們要獲取最終結(jié)果的話,必須使用終點(diǎn)操作才能收集流產(chǎn)生的最終結(jié)果。區(qū)分這兩個(gè)方法是看他的返回值,如果是Stream則是中間方法,否則是終點(diǎn)方法。具體請(qǐng)參照Stream的api。

簡(jiǎn)單介紹下幾個(gè)中間方法(filter、map)以及終點(diǎn)方法(collect、sum)

3.1.1Filter

在數(shù)據(jù)流中實(shí)現(xiàn)過(guò)濾功能是首先我們可以想到的最自然的操作了。Stream接口暴露了一個(gè)filter方法,它可以接受表示操作的Predicate實(shí)現(xiàn)來(lái)使用定義了過(guò)濾條件的lambda表達(dá)式。

復(fù)制代碼代碼如下:

List persons = …
Stream personsOver18 = persons.stream().filter(p -> p.getAge() > 18);//過(guò)濾18歲以上的人

 

3.1.2Map

假使我們現(xiàn)在過(guò)濾了一些數(shù)據(jù),比如轉(zhuǎn)換對(duì)象的時(shí)候。Map操作允許我們執(zhí)行一個(gè)Function的實(shí)現(xiàn)(Function<T,R>的泛型T,R分別表示執(zhí)行輸入和執(zhí)行結(jié)果),它接受入?yún)⒉⒎祷亍J紫龋屛覀儊?lái)看看怎樣以匿名內(nèi)部類的方式來(lái)描述它:

 

復(fù)制代碼代碼如下:

Stream adult= persons
              .stream()
              .filter(p -> p.getAge() > 18)
              .map(new Function() {
                  @Override
                  public Adult apply(Person person) {
                     return new Adult(person);//將大于18歲的人轉(zhuǎn)為成年人
                  }
              });

 

現(xiàn)在,把上述例子轉(zhuǎn)換成使用lambda表達(dá)式的寫法:

復(fù)制代碼代碼如下:

Stream map = persons.stream()
                    .filter(p -> p.getAge() > 18)
                    .map(person -> new Adult(person));

 

3.1.3Count

count方法是一個(gè)流的終點(diǎn)方法,可使流的結(jié)果最終統(tǒng)計(jì),返回int,比如我們計(jì)算一下滿足18歲的總?cè)藬?shù):

復(fù)制代碼代碼如下:

int countOfAdult=persons.stream()
                       .filter(p -> p.getAge() > 18)
                       .map(person -> new Adult(person))
                       .count();

 

3.1.4Collect

collect方法也是一個(gè)流的終點(diǎn)方法,可收集最終的結(jié)果

復(fù)制代碼代碼如下:

List adultList= persons.stream()
                       .filter(p -> p.getAge() > 18)
                       .map(person -> new Adult(person))
                       .collect(Collectors.toList());

 

或者,如果我們想使用特定的實(shí)現(xiàn)類來(lái)收集結(jié)果:

復(fù)制代碼代碼如下:

List adultList = persons
                 .stream()
                 .filter(p -> p.getAge() > 18)
                 .map(person -> new Adult(person))
                 .collect(Collectors.toCollection(ArrayList::new));

 

篇幅有限,其他的中間方法和終點(diǎn)方法就不一一介紹了,看了上面幾個(gè)例子,大家明白這兩種方法的區(qū)別即可,后面可根據(jù)需求來(lái)決定使用。

3.2順序流與并行流

每個(gè)Stream都有兩種模式:順序執(zhí)行和并行執(zhí)行。
順序流:

復(fù)制代碼代碼如下:

List <Person> people = list.getStream.collect(Collectors.toList());


并行流:

復(fù)制代碼代碼如下:

List <Person> people = list.getStream.parallel().collect(Collectors.toList());

 

顧名思義,當(dāng)使用順序方式去遍歷時(shí),每個(gè)item讀完后再讀下一個(gè)item。而使用并行去遍歷時(shí),數(shù)組會(huì)被分成多個(gè)段,其中每一個(gè)都在不同的線程中處理,然后將結(jié)果一起輸出。

3.2.1并行流原理:
 

復(fù)制代碼代碼如下:

List originalList = someData;
split1 = originalList(0, mid);//將數(shù)據(jù)分小部分
split2 = originalList(mid,end);
new Runnable(split1.process());//小部分執(zhí)行操作
new Runnable(split2.process());
List revisedList = split1 + split2;//將結(jié)果合并

 

3.2.2順序與并行性能測(cè)試對(duì)比

如果是多核機(jī)器,理論上并行流則會(huì)比順序流快上一倍,下面是測(cè)試代碼

復(fù)制代碼代碼如下:


long t0 = System.nanoTime();

 

//初始化一個(gè)范圍100萬(wàn)整數(shù)流,求能被2整除的數(shù)字,toArray()是終點(diǎn)方法

int a[]=IntStream.range(0, 1_000_000).filter(p -> p % 2==0).toArray();

long t1 = System.nanoTime();

//和上面功能一樣,這里是用并行流來(lái)計(jì)算

int b[]=IntStream.range(0, 1_000_000).parallel().filter(p -> p % 2==0).toArray();

long t2 = System.nanoTime();

//我本機(jī)的結(jié)果是serial: 0.06s, parallel 0.02s,證明并行流確實(shí)比順序流快

System.out.printf("serial: %.2fs, parallel %.2fs%n", (t1 - t0) * 1e-9, (t2 - t1) * 1e-9);

 

3.3關(guān)于Folk/Join框架

應(yīng)用硬件的并行性在java 7就有了,那就是 java.util.concurrent 包的新增功能之一是一個(gè) fork-join 風(fēng)格的并行分解框架,同樣也很強(qiáng)大高效,有興趣的同學(xué)去研究,這里不詳談了,相比Stream.parallel()這種方式,我更傾向于后者。

4.總結(jié)

如果沒有l(wèi)ambda,Stream用起來(lái)相當(dāng)別扭,他會(huì)產(chǎn)生大量的匿名內(nèi)部類,比如上面的3.1.2map例子,如果沒有default method,集合框架更改勢(shì)必會(huì)引起大量的改動(dòng),所以lambda+default method使得jdk庫(kù)更加強(qiáng)大,以及靈活,Stream以及集合框架的改進(jìn)便是最好的證明。

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 欧美影院天天5g天天爽 | 视频在线观看高清免费 | 欧美成人影院免费观 | 好吊妞视频998www | 男同gay玩奴男同玩奴 | 精品国产品香蕉在线观看 | 好大好爽好舒服视频 | 四虎在线网址 | 国产ay | 日本精工厂网址 | 黑人巨大精品战中国美女 | 韩国成人毛片aaa黄 含羞草国产亚洲精品岁国产精品 | 美女模特被c免费视频 | 国产a一级 | 国产欧美va欧美va香蕉在线观 | 四虎影院入口 | 办公室出轨秘书高h | 热99re国产久热在线 | 黑人巨荃大战乌克兰美女 | avtt天堂在线 | 久久精品国产免费播放 | 免费片在线观看 | 好男人天堂网 | 国产精品边做边接电话在线观看 | 免费免费啪视频在线观播放 | 精品精品国产自在久久高清 | 69av免费视频 | 亚洲欧美日韩在线观看看另类 | 好吊操这里有精品 | 国产高清国内精品福利色噜噜 | 日本三级在丈面前被耍了 | 日韩成人影视 | 日本高清中文字幕一区二区三区 | 欧美一级特黄aaa大片 | 四虎一影院区永久精品 | 日韩欧美高清视频 | 国产高清露脸学生在线观看 | 免费在线观看中文字幕 | 欧美一级一级做性视频 | 国产色网址 | 色综合久久综精品 |