Collector位于java.util.stream下,根據javaDoc描述:
A mutable reduction operation that accumulates input elements into a mutable result container,
optionally transforming the accumulated result into a final representation after all input elements
have been processed. Reduction operations can be performed either sequentially or in parallel.
Collector是一種可變的聚集操作,將輸入的元素按照指定的策略收納到一個可變的容器中,待所有元素處理完成后,將結果轉換為一個最終的表示。這個最終表示例如常用的Map、Set、List等。
一、Collector接口定義
Collector是一個接口定義,接口包含了三個泛型和5個函數:
public interface Collector<T, A, R> {
Supplier<A> supplier();
BiConsumer<A, T> accumulator();
BinaryOperator<A> combiner();
Function<A, R> finisher();
Set<Characteristics> characteristics();
}
接口泛型
T是輸入的對象類型、A是累加器的類型、R是最終收集的結果類型
接口函數
1. 建立累加器容器的supplier方法
Supplier<A> supplier();
建立新的累加器容器。此方法定義如何收集數據,必須返回一個無參函數,此函數是用來創建一個空的累加器實例,供數據收集過程使用。
示例:
@Override
public Supplier<List<T>> supplier() {
return ArrayList::new;
}
2. 累加器執行累加的具體實現accumulator方法
BiConsumer<A, T> accumulator();
該方法會返回執行累加操作的函數,此函數有兩個參數返回值為空,第一個參數是累加器容器,第二個參數是要累加的元素。
示例:
@Override
public BiConsumer<List<T>, T> accumulator() {
return List::add;
}
3. 合并容器combiner方法
Collector支持并行,并行會涉及任務分段與結果合并。
BinaryOperator<A> combiner();
將兩個結果合并為一個,此方法返回一個供合并操作使用的函數。
示例:
@Override
public BinaryOperator<List<T>> combiner() {
return (list1, list2) -> {
list1.addAll(list2);
return list1;
};
}
4. 轉換為結果finisher方法
Function<A, R> finisher();
在容器上執行最終轉換,此方法返回一個轉換函數,參數為累計值,返回值就是最終要轉換返回的東西。
示例:
@Override
public Function<List<T>, List<T>> finisher() {
return (i) -> i * i;
}
5. characteristics方法
Set<Characteristics> characteristics();
返回一個不可變的Characteristics集合,其定義了收集器的行為,例如關于stream是否可以進行歸約,有哪些可以用的優化等。
Characteristics是一個包含三個項目的枚舉:
- UNORDERED--歸約結果不受流中項目的遍歷和累積順序的影響
- CONCURRENT--accumulator函數可以從多個線程同時調用,且該收集器可以并行歸約流。如果收集器沒有標為UNORDERED, 那它僅在用于無序數據源時才可以并行歸約。
- IDENTITY_FINISH--這表明完成器方法返回的函數是一個恒等函數,可以跳過。這種情況下,累加器對象將會直接用做歸約過程的最終結果。這也意味著,將累加器A不加檢查地轉換為結果R是安全的。
二、常用的Collector方法
// 類型歸納方法
// 通過Stream的.collect方法進行
Collector.toList();
Collector.toMap();
Collector.toSet();
Collector.toCollection();
Collector.toConcurrentMap();
// joining
// 將元素以某種規則連接起來
.stream().collect(Collectors.joining());
// collectingAndThen
// groupingBy
// partitioningBy
// counting
// maxBy/minBy
// summingInt/Double/Long
// summarizingInt/Double/Long
// mapping
// reducing
// 待更新
三、根據集合來獲取stream
stream的常用方法:
- 終結方法:返回值類型不再是stream接口本身類型的,例如forEach、count等。
- 非終結方法:返回值類型仍式stream接口自身類型的方法,例如filter、limit等。
|
方法名稱 |
方法作用 |
方法種類 |
是否支持鏈式調用 |
|
count |
統計個數 |
終結方法 |
否 |
|
forEach |
逐一處理 |
終結方法 |
否 |
|
filter |
過濾 |
函數拼接 |
是 |
|
limit |
取用前幾個 |
函數拼接 |
是 |
|
skip |
跳過前幾個 |
函數拼接 |
是 |
|
map |
映射 |
函數拼接 |
是 |
|
concat |
組合 |
函數拼接 |
是 |