Java8新特性:Stream語法詳解

你們能夠把Stream當成一個高級版本的Iterator。原始版本的Iterator,用戶只能一個一個的遍歷元素並對其執行某些操做;高級版本的Stream,用戶只要給出須要對其包含的元素執行什麼操做,好比「過濾掉長度大於10的字符串」、「獲取每一個字符串的首字母」等,具體這些操做如何應用到每一個元素上,就給Stream就行了!(這個祕籍,通常人我不告訴他:)css

List<Integer> nums = Lists.newArrayList(1,null,3,4,null,6);
nums.stream().filter(num -> num != null).count();java

list.stream() .filter(student -> student.getSex().equals("G")) .forEach(student -> System.out.println(student.toString()));

List<String> lastStoneList =
                     stoneLine.stream()
                     .filter(s -> s.getWeight() < 500)//挑選出質量小於500g的鵝卵石
                     .sorted(comparing(Stone::getWeight))//按照質量進行排序
                     .map(Stone::getName)//提取知足要求的鵝卵石的名字
                    .collect(toList());//將名字保存到List中
--------------------- 數組

  1. 建立Stream;
  2. 轉換Stream,每次轉換原有Stream對象不改變,返回一個新的Stream對象(**能夠有屢次轉換**);
  3. 對Stream進行聚合(Reduce)操做,獲取想要的結果;

2.1 使用Stream靜態方法來建立Stream的三種方法:

1. of方法:有兩個overload方法,一個接受變長參數,一個接口單一值dom

Stream<Integer> integerStream = Stream.of(1, 2, 3, 5);
Stream<String> stringStream = Stream.of("taobao");函數

2. generator方法:生成一個無限長度的Stream,其元素的生成是經過給定的Supplier(這個接口能夠當作一個對象的工廠,每次調用返回一個給定類型的對象)測試

Stream.generate(() -> Math.random());
Stream.generate(Math::random);ui

3. iterate方法:也是生成無限長度的Stream,和generator不一樣的是,其元素的生成是重複對給定的種子值(seed)調用用戶指定函數來生成的。其中包含的元素能夠認爲是:seed,f(seed),f(f(seed))無限循環。spa

Stream.iterate(1, item -> item + 1).limit(10).forEach(System.out::println);code

3. 轉換Stream:

轉換Stream其實就是把一個Stream經過某些行爲轉換成一個新的Stream。Stream接口中定義了幾個經常使用的轉換方法,下面咱們挑選幾個經常使用的轉換方法來解釋。orm

1. distinct: 對於Stream中包含的元素進行去重操做(去重邏輯依賴元素的equals方法),新生成的Stream中沒有重複的元素;

2. filter: 對於Stream中包含的元素使用給定的過濾函數進行過濾操做,新生成的Stream只包含符合條件的元素;

3. map: 對於Stream中包含的元素使用給定的轉換函數進行轉換操做,新生成的Stream只包含轉換生成的元素。這個方法有三個對於原始類型的變種方法,分別是:mapToInt,mapToLong和mapToDouble。

4. flatMap:和map相似,不一樣的是其每一個元素轉換獲得的是Stream對象,會把子Stream中的元素壓縮到父集合中;

5. peek: 生成一個包含原Stream的全部元素的新Stream,同時會提供一個消費函數(Consumer實例),新Stream每一個元素被消費的時候都會執行給定的消費函數;

6. limit: 對一個Stream進行截斷操做,獲取其前N個元素,若是原Stream中包含的元素個數小於N,那就獲取其全部的元素;

7. skip: 返回一個丟棄原Stream的前N個元素後剩下元素組成的新Stream,若是原Stream中包含的元素個數小於N,那麼返回空Stream;

Stream的類型和建立方式2:

// 從數組建立 int [] source = {1,2,3,4,5,6}; IntStream s = Arrays.stream(source); // 從集合建立 List list = Arrays.asList(1,2,3,4,5); Stream s2 = list.stream(); // 建立1到10的流 IntStream s3 = IntStream.range(1,10); // 直接建立 Stream s4 = Stream.of("wo", "ai", "?")
// 支持串行並行操做的序列,元素只有double,int,Long類型的流 DoubleStream,IntStream,LongStream。

案例:

// 將元素中的全部偶數累加求和
int[] nums = {2, 3, 4, 5, 6}; System.out.println( Arrays.stream(nums) .map(i -> i % 2 == 0 ? i : 0) .reduce(0, Integer::sum) );


案例三:假設有N條營業數據,前5條是無關的測試數據,中間10條是要參加考覈的,參與考覈的須要知道其中超過50w(包括50)的數據的交易額平均值,其餘不參與考覈的忽略// flatMap處理嵌套的list List<List<Integer>> ll = Arrays.asList( Arrays.asList(1, 2, 3), Arrays.asList(11, 22, 33), Arrays.asList(0xF1, 0xF2, 0xF3) ); ll.stream() .flatMap(list -> list.stream()) .map(i -> 2 * i) .forEach(i -> System.out.println(i));
Stream<Integer> trans = Stream.of(11, 9, 2, 13, 1, 2, 99, 54, 23, 66, 70, 23, 46, 50, 100, 10, 24, 18, 19, 2); IntSummaryStatistics all = trans // 前5條跳過,2, 99, 54, 23, 66, 70, 23, 46, 50, 100, 10, 24, 18, 19, 2 .skip(5) // 取10條考覈交易 2, 99, 54, 23, 66, 70, 23, 46, 50, 100 .limit(10) // 將50如下的交易剔除 99, 54, 66, 70, 50, 100 .filter(i -> i >= 50) // 轉換成數字。若是是IntStream 則不須要轉換 .mapToInt(i->i) // 將流的統計結果放入包裝對象中 .summaryStatistics(); // 交易總量 439w,平均值爲439/6 System.out.println(all.getAverage());

Stream流的特性:

1.不能重複使用。

Stream<Integer> trans = Stream.of(11, 9, 2); trans.forEach(i -> System.out.println(i)); trans.reduce(0, Integer::sum); 

當我第二次使用trans時,報錯了。


 

2.驗證流延遲操做:流只要在終止操做(及早求值)時,纔會對數據統一作操做,在沒有遇到求值操做的時候,惰性操做代碼不會被執行。

Stream<Integer> trans = Stream.of(11, 70, 23, 46, 50, 100, 10, 24, 18, 19, 2); trans.map(i->{ System.out.println(i); return i; }); 
 
3.不影響源數據。
相關文章
相關標籤/搜索