[TOC]
## 1. stream特點
`Stream`?流分為**順序流**和**并行流**,所謂順序流就是按照順序對集合中的元素進行處理,而并行流則是使用多線程同時對集合中多個元素進行處理,所以在使用并行流的時候就要注意線程安全的問題了。
1. stream不是一種數據結構,不保存數據,只是在原數據上封裝了一組操作
2. 這些操作是惰性的,即每當訪問到流中的一個元素,才會在此元素上執行這一系列操作。
3. Stream不保存數據,故每個Stream流只能使用一次。
4. 提供并行化流,不用開發人員自己寫多線程
## 2. stream操作分類
可以分成兩種:**Intermediate(中間操作)** 和**Terminal(終止操作)**。
1. 中間操作的返回結果都是Stream,故可以多個中間操作疊加;
2. 終止操作用于返回我們最終需要的數據,只能有一個終止操作。
## 3. 流的產生方法
1. Collection接口的stream()或parallelStream()方法
2. 靜態的Stream.of()、Stream.empty()方法
3. Arrays.stream(array, from, to)
4. 靜態的Stream.generate()方法生成無限流,接受一個不包含引元的函數
5. 靜態的Stream.iterate()方法生成無限流,接受一個種子值以及一個迭代函數
6. Pattern接口的splitAsStream(input)方法
7. 靜態的Files.lines(path)、Files.lines(path, charSet)方法
8. 靜態的Stream.concat()方法將兩個流連接起來
## 4. 流的Intermediate方法(中間操作)
集合可以直接調用
1. filter(Predicate)
將結果為false的元素過濾掉
2. map(fun)
轉換元素的值,可以用方法引元或者lambda表達式
3. flatMap(fun)
若元素是流,將流攤平為正常元素,再進行元素轉換
4. limit(n)
保留前n個元素
5. skip(n)
跳過前n個元素
6. distinct()
剔除重復元素
7. sorted()
將Comparable元素的流排序
8. sorted(Comparator)
將流元素按Comparator排序
9. peek(fun)
流不變,但會把每個元素傳入fun執行,可以用作調試
## 5. 流的Terminal方法(終結操作)
### 5.1 約簡統計操作
1. max(Comparator)
2. min(Comparator)
3. count()
4. findFirst()
返回第一個元素
5. findAny()
返回任意元素
6. anyMatch(Predicate)
任意元素匹配時返回true
7. allMatch(Predicate)
所有元素匹配時返回true
8. noneMatch(Predicate)
沒有元素匹配時返回true
9. reduce(fun)
從流中計算某個值,接受一個二元函數作為累積器,從前兩個元素開始持續應用它,累積器的中間結果作為第一個參數,流元素作為第二個參數
10. reduce(a, fun)
a為幺元值,作為累積器的起點
11. reduce(a, fun1, fun2)
與二元變形類似,并發操作中,當累積器的第一個參數與第二個參數都為流元素類型時,可以對各個中間結果也應用累積器進行合并,但是當累積器的第一個參數不是流元素類型而是類型T的時候,各個中間結果也為類型T,需要fun2來將各個中間結果進行合并
### 5.2 收集操作
1. iterator()
2. forEach(fun)
3. forEachOrdered(fun)
可以應用在并行流上以保持元素順序
4. toArray()
5. toArray(T[] :: new)
返回正確的元素類型
**6. collect(Collector),Collector是收集器,用于將流數據收集成Java集合對象**
7. collect(fun1, fun2, fun3)
fun1轉換流元素;fun2為累積器,將fun1的轉換結果累積起來;fun3為組合器,將并行處理過程中累積器的各個結果組合起來
### 5.3 實例
```
public static void streamImpl(List<Student> students) {
List<Student> filterStudent = students.stream()
.filter(one -> one.getScore() <? 60).collect(Collectors.toList());
System.out.println(filterStudent);
}
```
#### flatMap()

`flatMap()`操作能把原始流中的元素進行一對多的轉換,并且將新生成的元素全都合并到它返回的流里面。假如現每個班的學生都學了不同的課程,現在需要統計班里所有學生所學的課程列表,該如何實現呢?
##### 清單 12.?`flatMap ()`?方法的使用示例
```
`public static void useFlatMap() {`
`List<``Student``> students = initData();`
`List<``String``> course = students.stream().flatMap(one -> one.getCourse().stream()).distinct()`
`.collect(Collectors.toList());`
`System.out.println(course);`
`}`
```
# 實例
## 1. reduce實例
Reduce,顧名思義為減少的意思,就是根據指定的計算模型將Stream中的值計算**得到一個最終結果**。首先來看一下Reduce三種形式:

1. 第一種,無初始值,依次累加
```
public static void reduceFirstSign() {
List<Integer> list = Arrays.asList(1,2,3,4,5,6);
ptional<Integer> count = list.stream().reduce((a, b) -> (a + b));
System.out.println(count.get()); // 21
}
```
2. 第二種,有初始值依次計算
```
public static void reduceSecondSign() {
List<Integer> list = Arrays.asList(1,2,3,4,5,6);
Integer count = list.stream().reduce(2, (a, b) -> (a * b));
System.out.println(count); // 1440
}
```
(((((2 x 1) x 2) x 3 )x 4) x 5) x 6 )
3. 第三種,并行化計算統計
```
public static void main(String[] args) {
List<Integer> list = Arrays.asList(2,2);
Integer result = list.stream().parallel().reduce(2, (a, b) -> (a + b), (a, b) -> (a + b));
System.out.println(result);
}
```
上面的代碼實際上是先使用累加器把 Stream 流中的兩個元素都加?`2`?后,然后再使用合并器將兩部分的結果相加。最終得到的結果也就是?`8`。
## 2. 收集器實例
#### list轉map
利用收集器 Collectors.toMap
```
public static void list2Map() {
List<Student> students = initData();
Map<String, Double> collect = students.stream()
.collect(Collectors.toMap(one -> one.getName(),
one -> one.getScore()));
System.out.println(collect);
}
```
## 6. 流類型轉換
### 6.1 對象流轉基本流
對象流轉換為基本類型流:mapToInt()、mapToLong()、mapToDouble()
### 6.2 基本流轉對象流
基本類型流轉換為對象流:
boxed() :類似于包裝類
mapToObj(func):用函數構造對象
- 計算機網絡
- 基礎_01
- tcp/ip
- http轉https
- Let's Encrypt免費ssl證書(基于haproxy負載)
- what's the http?
- 網關
- 網絡IO
- http
- 工具
- Git
- 初始本地倉庫并上傳
- git保存密碼
- Gitflow
- maven
- 1.生命周期命令
- 聚合與繼承
- 插件管理
- assembly
- 資源管理插件
- 依賴范圍
- 分環境打包
- dependencyManagement
- 版本分類
- 找不到主類
- 無法加載主類
- 私服
- svn
- gradle
- 手動引入第三方jar包
- 打包exe文件
- Windows
- java
- 設計模式
- 七大原則
- 1.開閉原則
- 2. 里式替換原則
- 3. 依賴倒置原則
- 4. 單一職責原則
- 單例模式
- 工廠模式
- 簡單工廠
- 工廠方法模式
- 抽象工廠模式
- 觀察者模式
- 適配器模式
- 建造者模式
- 代理模式
- 適配器模式
- 命令模式
- json
- jackson
- poi
- excel
- easy-poi
- 規則
- 模板
- 合并單元格
- word
- 讀取
- java基礎
- 類路徑與jar
- 訪問控制權限
- 類加載
- 注解
- 異常處理
- String不可變
- 跨域
- transient關鍵字
- 二進制編碼
- 泛型1
- 與或非
- final詳解
- Java -jar
- 正則
- 讀取jar
- map
- map計算
- hashcode計算原理
- 枚舉
- 序列化
- URLClassLoader
- 環境變量和系統變量
- java高級
- java8
- 1.Lambda表達式和函數式接口
- 2.接口的默認方法和靜態方法
- 3.方法引用
- 4.重復注解
- 5.類型推斷
- 6.拓寬注解的應用場景
- java7-自動關閉資源機制
- 泛型
- stream
- 時區的正確理解
- StringJoiner字符串拼接
- 注解
- @RequestParam和@RequestBody的區別
- 多線程
- 概念
- 線程實現方法
- 守護線程
- 線程阻塞
- 筆試題
- 類加載
- FutureTask和Future
- 線程池
- 同步與異步
- 高效簡潔的代碼
- IO
- ThreadLocal
- IO
- NIO
- 圖片操作
- KeyTool生成證書
- 壓縮圖片
- restful
- 分布式session
- app保持session
- ClassLoader.getResources 能搜索到的資源路徑
- java開發規范
- jvm
- 高并發
- netty
- 多線程與多路復用
- 異步與事件驅動
- 五種IO模型
- copy on write
- code style
- 布隆過濾器
- 筆試
- 數據庫
- mybatis
- mybatis與springboot整合配置
- pagehelper
- 分頁數據重復問題
- Java與數據庫之間映射
- 攔截器
- 攔截器應用
- jvm
- 堆內存測試
- 線程棧
- 直接內存
- 內存結構
- 內存模型
- 垃圾回收
- 調優
- 符號引用
- 運行參數
- 方法區
- 分帶回收理論
- 快捷開發
- idea插件
- 注釋模板
- git
- pull沖突
- push沖突
- Excel處理
- 圖片處理
- 合并單元格
- easypoi
- 模板處理
- 響應式編程
- reactor
- reactor基礎
- jingyan
- 規范
- 數據庫