成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

Java 8新特性探究(3):解開lambda最強作用的神秘面紗

開發 后端
JSR是Java Specification Requests的縮寫,意思是Java 規范請求,Java 8 版本的主要改進是 Lambda 項目(JSR 335),其目的是使 Java 更易于為多核處理器編寫代碼。JSR 335=lambda表達式+接口改進(默認方法)+批量數據操作。加上前面兩篇,我們已是完整的學習了JSR335的相關內容了。

 

我們期待了很久lambda為java帶來閉包的概念,但是如果我們不在集合中使用它的話,就損失了很大價值。現有接口遷移成為lambda風格的問題已經通過default methods解決了,在這篇文章將深入解析Java集合里面的批量數據操作(bulk operation),解開lambda***作用的神秘面紗。

1.關于JSR335

JSR是Java Specification Requests的縮寫,意思是Java 規范請求,Java 8 版本的主要改進是 Lambda 項目(JSR 335),其目的是使 Java 更易于為多核處理器編寫代碼。JSR 335=lambda表達式+接口改進(默認方法)+批量數據操作。加上前面兩篇,我們已是完整的學習了JSR335的相關內容了。

2.外部VS內部迭代

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

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

上面的例子是我們以前的做法,也就是所謂的外部迭代,循環是固定的順序循環。在現在多核的時代,如果我們想并行循環,不得不修改以上代碼。效率能有多大提升還說定,且會帶來一定的風險(線程安全問題等等)。
要描述內部迭代,我們需要用到Lambda這樣的類庫,下面利用lambda和Collection.forEach重寫上面的循環

  1. persons.forEach(p->p.setLastName("Doe")); 

現在是由jdk 庫來控制循環了,我們不需要關心last name是怎么被設置到每一個person對象里面去的,庫可以根據運行環境來決定怎么做,并行,亂序或者懶加載方式。這就是內部迭代,客戶端將行為p.setLastName當做數據傳入api里面。

內部迭代其實和集合的批量操作并沒有密切的聯系,借助它我們感受到語法表達上的變化。真正有意思的和批量操作相關的是新的流(stream)API。新的java.util.stream包已經添加進JDK 8了。

3.Stream API

流(Stream)僅僅代表著數據流,并沒有數據結構,所以他遍歷完一次之后便再也無法遍歷(這點在編程時候需要注意,不像Collection,遍歷多少次里面都還有數據),它的來源可以是Collection、array、io等等。

3.1中間與終點方法

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

簡單介紹下幾個中間方法(filter、map)以及終點方法(collect、sum)

3.1.1Filter

在數據流中實現過濾功能是首先我們可以想到的最自然的操作了。Stream接口暴露了一個filter方法,它可以接受表示操作的Predicate實現來使用定義了過濾條件的lambda表達式。

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

3.1.2Map

假使我們現在過濾了一些數據,比如轉換對象的時候。Map操作允許我們執行一個Function的實現(Function<T,R>的泛型T,R分別表示執行輸入和執行結果),它接受入參并返回。首先,讓我們來看看怎樣以匿名內部類的方式來描述它:

  1. Stream adult= persons  
  2.               .stream()  
  3.               .filter(p -> p.getAge() > 18)  
  4.               .map(new Function() {  
  5.                   @Override 
  6.                   public Adult apply(Person person) {  
  7.                      return new Adult(person);//將大于18歲的人轉為成年人  
  8.                   }  
  9.               }); 

現在,把上述例子轉換成使用lambda表達式的寫法:

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

3.1.3Count

count方法是一個流的終點方法,可使流的結果最終統計,返回int,比如我們計算一下滿足18歲的總人數

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

3.1.4Collect

collect方法也是一個流的終點方法,可收集最終的結果

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

或者,如果我們想使用特定的實現類來收集結果:

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

篇幅有限,其他的中間方法和終點方法就不一一介紹了,看了上面幾個例子,大家明白這兩種方法的區別即可,后面可根據需求來決定使用。

3.2順序流與并行流

每個Stream都有兩種模式:順序執行和并行執行。
順序流:

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

并行流:

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

顧名思義,當使用順序方式去遍歷時,每個item讀完后再讀下一個item。而使用并行去遍歷時,數組會被分成多個段,其中每一個都在不同的線程中處理,然后將結果一起輸出。

3.2.1并行流原理:

  1. List originalList = someData;  
  2. split1 = originalList(0, mid);//將數據分小部分  
  3. split2 = originalList(mid,end);  
  4. new Runnable(split1.process());//小部分執行操作  
  5. new Runnable(split2.process());  
  6. List revisedList = split1 + split2;//將結果合并 

大家對hadoop有稍微了解就知道,里面的 MapReduce  本身就是用于并行處理大數據集的軟件框架,其 處理大數據的核心思想就是大而化小,分配到不同機器去運行map,最終通過reduce將所有機器的結果結合起來得到一個最終結果,與MapReduce不同,Stream則是利用多核技術可將大數據通過多核并行處理,而MapReduce則可以分布式的。

3.2.2順序與并行性能測試對比

如果是多核機器,理論上并行流則會比順序流快上一倍,下面是測試代碼

  1. long t0 = System.nanoTime();  
  2.  
  3. //初始化一個范圍100萬整數流,求能被2整除的數字,toArray()是終點方法  
  4.  
  5. int a[]=IntStream.range(0, 1_000_000).filter(p -> p % 2==0).toArray();  
  6.  
  7. long t1 = System.nanoTime();  
  8.  
  9. //和上面功能一樣,這里是用并行流來計算  
  10.  
  11. int b[]=IntStream.range(0, 1_000_000).parallel().filter(p -> p % 2==0).toArray();  
  12.  
  13. long t2 = System.nanoTime();  
  14.  
  15. //我本機的結果是serial: 0.06s, parallel 0.02s,證明并行流確實比順序流快  
  16.  
  17. System.out.printf("serial: %.2fs, parallel %.2fs%n", (t1 - t0) * 1e-9, (t2 - t1) * 1e-9); 

3.3關于Folk/Join框架

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

 

4.總結

如果沒有lambda,Stream用起來相當別扭,他會產生大量的匿名內部類,比如上面的3.1.2map例子,如果沒有default method,集合框架更改勢必會引起大量的改動,所以lambda+default method使得jdk庫更加強大,以及靈活,Stream以及集合框架的改進便是***的證明。

java 8特性探究系列寫了3篇了,作為大餐,將java 8的重量級特性lambda與default method寫在前面,下篇上個小菜,葷素搭配,也是語言相關的,JEP104 Java 類型的注解的探究,同時謝謝大家的支持,歡迎提出建議。如果你想了解哪些特性,歡迎給我發留言。

原文鏈接:http://my.oschina.net/benhaile/blog/177148

責任編輯:林師授 來源: oschina
相關推薦

2014-07-15 13:54:09

Java8

2014-07-15 14:48:26

Java8

2009-02-16 19:33:09

2014-07-14 11:34:53

Java 8Nashorn

2014-04-16 07:43:31

Java 8JRE

2014-07-15 14:12:17

Java8

2014-04-15 15:45:22

Java8Java8教程

2014-10-20 13:57:59

JavaFX 8Java 8

2011-11-18 09:26:18

Javafinally

2014-04-15 16:01:00

Java8泛型

2015-08-20 13:43:17

NFV網絡功能虛擬化

2014-07-15 13:57:53

Java8

2014-04-15 09:53:54

Java8類型注解

2010-05-17 09:13:35

2021-06-07 08:18:12

云計算云端阿里云

2014-03-12 11:11:39

Storage vMo虛擬機

2014-05-14 10:02:17

Java 8StampedLock

2014-04-16 07:48:56

Java 8Permgen

2010-05-26 19:12:41

SVN沖突

2010-05-11 10:19:17

VMforceJava云計算
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 成人在线免费看 | 国产精品福利一区二区三区 | 亚洲第一av网站 | 国产精品久久国产愉拍 | 欧美一卡二卡在线 | 日韩电影免费观看中文字幕 | 免费一级黄色录像 | 国产乱一区二区三区视频 | 日本免费在线 | 欧美性高潮 | 成人精品国产一区二区4080 | 99综合 | 亚洲日本中文 | 国产ts人妖一区二区三区 | 国产精品久久影院 | 精品96久久久久久中文字幕无 | 日本高清中文字幕 | 亚洲一在线 | 91精品国产一区二区三区香蕉 | 一本色道精品久久一区二区三区 | 精品国产一区二区久久 | 欧美精品国产精品 | 中文字幕在线一区二区三区 | 成人欧美一区二区三区1314 | 蜜臀久久99精品久久久久久宅男 | 一级片av | 国产精品视频入口 | 爱爱小视频 | 成人福利网 | 一区二区免费在线观看 | 国产精品视频网站 | 亚洲一区中文字幕 | 亚洲三区视频 | 日本超碰 | 国产亚洲精品综合一区 | 一区二区精品 | 久久天天躁狠狠躁夜夜躁2014 | 国产精品91久久久久久 | 宅女噜噜66国产精品观看免费 | 黄色欧美视频 | 天天操夜夜操 |