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 |
组合 |
函数拼接 |
是 |