当前位置: 首页 > 工具软件 > collect > 使用案例 >

Java新特性(4)collect深度解析

和和煦
2023-12-01
  1. 认真读完Collector的JDK源码上的注释文档
  2. collect:收集器
  3. Collector作为collect方法的参数
  4. Collector是一个接口,它是一个可变的汇聚操作,将输入元素累积到一个可变的结果容器中;它会在所有元素都处理完毕后,将累积的结果转化为一个最终的表示(这是一个可选操作);它支持串行与并行两种方式执行。
  5. Collectors本身提供了关于Collector得常见汇聚实现,Collectors本身实际上是一个工厂
  6. 为了确保串行与并行操作结果的等价性,Collector函数需要满足两个条件:identity(同一性)和association(结合性)
  7. a == combiner.apply(a,supplier.get())       ====>   (List<T> list1,List<T> list2)->{list1.addAll(list2); return list1}
  8. 函数式编程最大的特点:表示做什么,而不是如何做。

     
  9. Collectors类中包含由Collector接口的简单实现类:
    Collectors源文件中的内部类CollectorImpl实现了Collector接口
       /**
         * Simple implementation class for {@code Collector}.
         *
         * @param <T> the type of elements to be collected
         * @param <R> the type of the result
         */
        static class CollectorImpl<T, A, R> implements Collector<T, A, R> {
            private final Supplier<A> supplier;
            private final BiConsumer<A, T> accumulator;
            private final BinaryOperator<A> combiner;
            private final Function<A, R> finisher;
            private final Set<Characteristics> characteristics;
    
            CollectorImpl(Supplier<A> supplier,
                          BiConsumer<A, T> accumulator,
                          BinaryOperator<A> combiner,
                          Function<A,R> finisher,
                          Set<Characteristics> characteristics) {
                this.supplier = supplier;
                this.accumulator = accumulator;
                this.combiner = combiner;
                this.finisher = finisher;
                this.characteristics = characteristics;
            }
    
            CollectorImpl(Supplier<A> supplier,
                          BiConsumer<A, T> accumulator,
                          BinaryOperator<A> combiner,
                          Set<Characteristics> characteristics) {
                this(supplier, accumulator, combiner, castingIdentity(), characteristics);
            }
    
            @Override
            public BiConsumer<A, T> accumulator() {
                return accumulator;
            }
    
            @Override
            public Supplier<A> supplier() {
                return supplier;
            }
    
            @Override
            public BinaryOperator<A> combiner() {
                return combiner;
            }
    
            @Override
            public Function<A, R> finisher() {
                return finisher;
            }
    
            @Override
            public Set<Characteristics> characteristics() {
                return characteristics;
            }
        }
    

    一些示例应用:
     

        @Test
        public void Test2(){
            SomePerson somePerson1 = new SomePerson("liuliu", 21,100 );
            SomePerson somePerson2 = new SomePerson("tian", 11,100 );
            SomePerson somePerson3 = new SomePerson("men", 11,100 );
            SomePerson somePerson4 = new SomePerson("tian", 30,110 );
    
            List<SomePerson> somes = Arrays.asList(somePerson1,somePerson2,somePerson3,somePerson4);
    
            somes.stream().collect(Collectors.minBy(Comparator.comparingInt(SomePerson::getAge)))
                    .ifPresent(System.out::println);
            System.out.println(somes.stream().collect(Collectors.averagingDouble(SomePerson::getAge)));
            System.out.println(somes.stream().collect(Collectors.summarizingDouble(SomePerson::getAge)));
            System.out.println(somes.stream().map(SomePerson::getName).
                    collect(Collectors.joining(",")));
            System.out.println(somes.stream().map(SomePerson::getName).
                    collect(Collectors.joining(",","<begin>","<end>")));
    
            //多级分组:Height和name双重分组
            Map<Integer,Map<String,List<SomePerson>>> maps = somes.stream().
                    collect(Collectors.groupingBy(SomePerson::getHeight,Collectors.groupingBy(SomePerson::getName)));
            System.out.println(maps);
    
            //多级分区:age>20中age>30
            Map<Boolean,Map<Boolean,List<SomePerson>>> mapb = somes.stream().collect
                    (Collectors.partitioningBy(s->s.getAge()>20, Collectors.partitioningBy(s->s.getHeight()>30)));
            System.out.println(mapb);
    
            //年龄每个分区的人的个数
            Map<Boolean,Long> mapCount = somes.stream().collect
                    (Collectors.partitioningBy(s->s.getAge()>20,Collectors.counting()));
            System.out.println(mapCount);
    
            //按Name分组,并只取Age较小的
            Map<String,SomePerson> map2 = somes.stream().collect(groupingBy(SomePerson::getName,
                    collectingAndThen(minBy(Comparator.comparing(SomePerson::getAge)),Optional::get)));
            System.out.println(map2);
        }
    class SomePerson{
        private String name;
        private int age;
        private int height;
    
        public SomePerson(String name, int age, int height) {
            this.name = name;
            this.age = age;
            this.height = height;
        }
    
        @Override
        public String toString() {
            return "SomePerson{" +
                    "name='" + name + '\'' +
                    ", age=" + age +
                    ", height=" + height +
                    '}';
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public int getAge() {
            return age;
        }
    
        public void setAge(int age) {
            this.age = age;
        }
    
        public int getHeight() {
            return height;
        }
    
        public void setHeight(int height) {
            this.height = height;
        }
    }

     

  10. 重在理解,应用代码实现
 类似资料: