樂猿社區,程序員的花果山java
Stream 做爲 Java 8 的一大亮點,它與 java.io 包裏的 InputStream 和 OutputStream 是徹底不一樣的概念。Java 8 中的 Stream 是對集合(Collection)對象功能的加強,它專一於對集合對象進行各類很是便利、高效的聚合操做(aggregate operation),或者大批量數據操做 (bulk data operation)。Stream API 藉助於 Lambda 表達式,極大的提升編程效率和程序可讀性。程序員
Stream 就如同一個迭代器(Iterator),單向,不可往復,數據只能遍歷一次,遍歷過一次後即用盡了,就比如流水從面前流過,一去不復返。而和迭代器又不一樣的是,Stream 能夠並行化操做,迭代器只能命令式地、串行化操做。顧名思義,當使用串行方式去遍歷時,每一個 item 讀完後再讀下一個 item。而使用並行去遍歷時,數據會被分紅多個段,其中每個都在不一樣的線程中處理,而後將結果一塊兒輸出。編程
操做 | 類型 | 返回類型 | 目的 |
---|---|---|---|
filter | 中間操做 | Stream<T> | 過濾元素 |
distinct | 中間操做 | Stream<T> | 去掉重複的元素 |
skip | 中間操做 | Stream<T> | 跳過指定數量的元素 |
limit | 中間操做 | Stream<T> | 限制元素的數量 |
map | 中間操做 | Stream<T> | 流的轉化 |
flatmap | 中間操做 | Stream<T> | 流的扁平化 |
sorted | 中間操做 | Stream<T> | 元素排序 |
map與flatmap的區別:map是將list轉成list,而flatmap是將多個List合併成一個list併發
操做 | 類型 | 返回類型 | 目的 |
---|---|---|---|
forEach | 終端操做 | void | 消費流中的每一個元素,返回void |
count | 終端操做 | R | 返回流中元素的個數,返回long |
collect | 終端操做 | Stream<T> | 把流歸約爲一個集合 |
anyMatch | 終端操做 | boolean | 流中是否有符合要求的元素 |
noneMatch | 終端操做 | boolean | 流中是否沒有任何符合要求的元素 |
allMatch | 終端操做 | boolean | 流中是否全部元素都是符合要求的 |
findAny | 終端操做 | Optional<T> | 查找符合要求的元素 |
findFirst | 終端操做 | Optional<T> | 查找第一個符合要求的元素 |
reduce | 終端操做 | Optional<T> | 歸約 |
Stream 提供兩咱建立流的方式dom
Stream提供串行和並行兩種模式進行匯聚操做,併發模式可以充分利用多核處理器的優點,使用 fork/join 並行方式來拆分任務和加速處理過程。stream 是一個函數式語言+多核時代綜合影響的產物。編程語言
如下的代碼返回不爲空的字符串ide
List<String>strings = Arrays.asList("abc", "", "bc", "efg", "abcd","", "jkl"); // 獲取不爲空的字符串 List<String> result = strings.stream().filter(string -> string.isEmpty()).collect(Collectors.toList());
如下代碼會篩選出列表中全部的偶數,並確保沒有 重複函數
List<Integer> numbers = Arrays.asList(1,2,1,3,3,2,4); //去重元素2 numbers.stream().filter(i -> i % 2 == 0).distinct().forEach(System.out::println);
返回一個扔掉了前n個元素的流。若是流中元素不足n個,則返回一 個空流。limit(n) 和 skip(n) 是互補的。線程
//去掉符合要求的集合中的前2個元素後返回 List<User> dishSkip = userList.stream() .filter(d -> d.getAge() > 20).skip(2).collect(Collectors.toList());
返回一個不超過給定長度的流。所需的長度做爲參數傳遞 給limit。若是流是有序的,則最多會返回前n個元素。code
//只返回符合要求的前3個元素 List<User> dishLimits = userList.stream().filter(d -> d.getAge() > 30).limit(3).collect(Collectors.toList());
接受一個函數做爲參數。這個函數會被應用到每一個元素上,並將其映 射成一個新的元素
//轉爲字符串長度的集合 List<String> words = Arrays.asList("Hello", "World"); List<Integer> wordLens = words.stream().map(String::length).collect(Collectors.toList());
flatmap 方法讓你把一個流中的每一個值都換成另外一個流,而後把全部的流鏈接起來成爲一個流。
//使用flatMap找出單詞列表中各不相同的字符 List<String> words = Arrays.asList("Hello", "World"); List<String> wordMap = words.stream() .map(word -> word.split("")) .flatMap(Arrays::stream).distinct().collect(Collectors.toList());
sorted 方法用於對流進行排序。如下代碼片斷使用 sorted 方法對輸出的 10 個隨機數進行排序:
Random random = new Random(); random.ints().limit(10).sorted().forEach(System.out::println);
Collectors 類實現了不少歸約操做,例如將流轉換成集合和聚合元素。Collectors 可用於返回列表或字符串:
List<String>strings = Arrays.asList("abc", "", "bc", "efg", "abcd","", "jkl"); List<String> filtered = strings.stream().filter(string -> !string.isEmpty()).collect(Collectors.toList()); System.out.println("篩選列表: " + filtered); String mergedString = strings.stream().filter(string -> !string.isEmpty()).collect(Collectors.joining(", ")); System.out.println("合併字符串: " + mergedString);
查找和匹配操做包含anyMatch,allMatch,noneMatch,findFirst,findAny,通常狀況下使用的少
reduce操做是如何做用於一個流的:Lambda反覆結合每一個元素,直到流被歸約成一個值。reduce方法接受兩個參數:一個初始值,這裏是0;一個 BinaryOperator<T> 來將兩個元素結合起來產生一個新值, 這裏咱們用的是 lambda (a, b) -> a + b 歸約操做包含sum(元素求和)、min(最小值)、max(最大值)、count(求總數)
鼓勵把新的Java8特性引入到目前的項目中,一個長期配合的團隊以及一門古老的編程語言都須要不斷的注入新活力,不然不進則退
[]