collector接口
//Collector<T, A, R>
//T: stream中的元素类型;
//A:累加器的类型,可以想象成一个容器。比如T要累加,转化为List<T>,A就是List类型。
//R:最终返回值类型
public interface Collector<T, A, R> {
Supplier<A> supplier();
BiConsumer<A, T> accumulator();
BinaryOperator<A> combiner();
Function<A, R> finisher();
Set<Characteristics> characteristics();
}
- supplier():提供者方法,用来创建一个新的A的方法
- accumulator():累加器方法,怎么把T放到A里面的方法(主要逻辑)
- combiner():组合器方法,两个A怎么合并成一个A
- finisher():修正器方法,通过A获取R的方法
- characteristics():特色方法,characteristics 该方法返回一个 Characteristics 的集合,它有如下值可选
UNORDERED—— 归约结果不受流中项目的遍历和累积顺序的影响。
CONCURRENT—— accumulator函数可以从多个线程同时调用,且该收集器可以并行执行。如果收集器没有标为UNORDERED,那 它仅在用于用于无序数据源时才可以并行归约。
IDENTITY_ FINISH—— 这表明完成器方法返回的函数是一个不改变的函数,这种情况下,累加器对象将会直接用作合并过程 的最终结果。
public Set characteristics() {
return Collections.unmodifiableSet(EnumSet.of(Characteristics.IDENTITY_FINISH));
}
创建自定义Collector方法
public static<T, A, R> Collector<T, A, R> of(Supplier<A> supplier,
BiConsumer<A, T> accumulator,
BinaryOperator<A> combiner,
Function<A, R> finisher,
Characteristics... characteristics) {
测试
需求:给一个stringList,把string元素第二个字符合并成一个string返回
“Java 8”, “Hello”, “Collector”, “Custom”, “Stream”
public static void main(String[] args) throws ParseException {
String[] array = new String[]{"Java 8", "Hello", "Collector", "Custom", "Stream"};
Collector<String, List<String>, String> collector = Collector.of(
ArrayList::new,
(a, b) -> {
if (b.length() > 2) {
a.add(String.valueOf(b.charAt(1)));
}
},
(agg1, agg2) -> {
agg1.addAll(agg2);
return agg1;
},
agg-> String.join("", agg)
);
String collect = Arrays.stream(array).collect(collector);
System.out.println(collect);
}