### Stream(惰性求值)
Collection 是一種靜態的內存數據結構,而 Stream 是有關計算的。前者是主要面向內存,存儲在內存中,后者主要是面向 CPU,通過 CPU 實現計算。
集合講的是數據,流講的是計算。
**注意點**
1. Stream 自己不會存儲元素。
2. Stream 不會改變源對象 相反 它會返回一個持有結果的新的Stream。
3. Stream 操作是延遲的 只有在需要結果的情況下才會執行一系列的流操作。
## Stream操作
### 1. Stream 創建
1. list.stream() or list.parallelStream()
2. Arrays.stream(new Integer[10]) 數組流
3. Stream.of(1,2,3) 通過of方法
4. IntStream Stream.iterate(1,t->t+1) 無限流
### 2. Stream 中間操作
#### filter篩選=過濾
list.stream().filter(e->e.getAge>35).forEach(System.out::println)
#### limit切片
list.stream().filter(e->e.getAge>35).limit(3).forEach(System.out::println)
#### skip
跳過前面n個元素 與limit互補、
list.stream().skip(3).forEach(System.out::print);
#### distinct去重
通過hashcode和equals進行去重的。
list.stream().distinct().forEach(System.out::print);
#### Map flatMap映射
Map將流中的的元素經過處理轉換成別的元素 成為一個新的Stream。
flatMap接受一個函數作為參數 將流中的每一個值都換成另一個流 然后把所有的流連接成一個新的流。
Map和flatMap處理返回一個流的函數的時候類似于add和addAll
list.map(Car::getName).forEach(System.out::println)
#### sort排序
1. 自然排序 sorted()--自然排序(Comparable)
2. 定制排序 sorted(Comparator com)
list.stream().sorted((x, y) -> -Integer.compare(x, y)).forEach(System.out::println);
### 3. 終止操作
1. allMatch 檢查是否匹配所有元素
2. anyMatch 檢查是否至少匹配一個元素
3. noneMatch 檢查是否沒有匹配的元素
4. findFirst 返回第一個元素
5. findAny 返回當前流中的任意元素
6. count 返回流中元素的總個數
7. max 返回流中最大值
8. min 返回流中最小值
#### 9. reduce 歸約
將流中元素反復結合起來 生成一個新的值(就是對流中元素進行累加求值)。
list.stream().reduce(0, Integer::sum);//第一個參數為起始值 后面一次運用前一次生成的值和當前的值累加起來。
Optional<Integer> sum = list.stream().reduce(Integer::sum);
#### 10.collect收集
將一種流轉換為其他的形式。接收一個Collector接口的實現,用于給Streamz中元素做匯總的方法。
collect方法接收一個Collector的接口,但是Collectors實用類提供了很多的靜態方法,可以方便的創建常見收集器實例。
```java
// 收集
cars.stream().map(Car::getName)
.collect(Collectors.toList());
// 求平均值
cars.stream()
.collect(Collectors.averagingDouble(Car::getAge));
// 分組
Map<Integer, List<Car>> map = cars.stream()
.collect(Collectors.groupingBy(Car::getId));
// 多級分組
cars.stream()
.collect(Collectors.groupingBy(
Car::getId,
Collectors.groupingBy(Car::getName)
));
// 分區 true為一部分 false為一部分
Map<Boolean, List<Car>> maps = cars.stream()
.collect(Collectors.partitioningBy(t -> t.getAge() > 30));
```