jdk8_Stream流-自定义收集器

介绍

对于自定义收集器实现,需要对Collector接口中的方法进行实现
Collector接口需要三个参数。T:流中要收集的元素类型、A:累加器的类型、R:收集的结果类型

public interface Collector<T, A, R> {

    Supplier<A> supplier();

    BiConsumer<A, T> accumulator();

    BinaryOperator<A> combiner();

    Function<A, R> finisher();

    Set<Characteristics> characteristics();
}

需要实现Collector接口中的五个方法:supplier、accumulator、finisher、combiner、characteristics

  • **supplier:**用于创建一个容器,在调用它时,需要创建一个空的累加器实例,供后续方法使用
  • **accumulator:**基于supplier中创建的累加容器,进行累加操作
  • **finisher:**当遍历完流后,在其内部完成最终转换,返回一个最终结果
  • **combiner:**用于在并发情况下,将每个线程的容器进行合并
  • **characteristics:**用于定义收集器行为,如是否可以并行或使用哪些优化。其本身是一个枚举,内部有三个值,分别为:
    • **CONCURRENT:**表明收集器是并行的且只会存在一个中间容器
    • **UNORDERED:**表明结果不受流中顺序影响,收集是无序的
    • **IDENTITY_FINISH:**表明累积器的结果将会直接作为归约的最终结果,跳过finisher()、

自定义实现

返回及格的学生信息

自定义器实现

public class MyCollector implements Collector<Student, List<Student>, List<Student>> {
    @Override
    public Supplier<List<Student>> supplier() {
        return ArrayList::new;
    }

    @Override
    public BiConsumer<List<Student>, Student> accumulator() {
        return ((students, student) -> {
            if (student.isPass()) {
                students.add(student);
            }
        });
    }

    @Override
    public BinaryOperator<List<Student>> combiner() {
        return null;
    }

    @Override
    public Function<List<Student>, List<Student>> finisher() {
        return Function.identity();
    }

    @Override
    public Set<Characteristics> characteristics() {
        return EnumSet.of(Characteristics.IDENTITY_FINISH, Characteristics.UNORDERED);
    }
}

使用自定义收集器

public class MyCollectorDemo {
    public static void main(String[] args) {
        List<Student> studentList = new ArrayList<>();
        studentList.add(new Student("张三", 23, true, 100));
        studentList.add(new Student("李四", 23, false, 20));
        studentList.add(new Student("王五", 19, true, 80));
        studentList.add(new Student("小明", 19, false, 40));
        studentList.add(new Student("小红", 19, true, 80));

        List<Student> collect = studentList.stream().collect(new MyCollector());
        System.out.println(collect);
    }
}

运行结果:

[Student{id=null, name='张三', age=23, pass=true}, Student{id=null, name='王五', age=19, pass=true}, Student{id=null, name='小红', age=19, pass=true}]