Collectors解析

作者: shz_Minato | 来源:发表于2019-01-23 16:16 被阅读7次

    一 概述

     Collectors是Collector规范的实现,并不是接口意义上的实现。该类中提供了许多有用的聚合操作,比如讲元素累积到集合中、通过指定的规则总结元素。

        一些常见的实例如下:
        
         // 累积名字属性到一个集合中
         List<String> list = people.stream().map(Person::getName).collect(Collectors.toList());
    
          // 累积名字属性到一个TreeSet中
          Set<String> set = people.stream().map(Person::getName).collect(Collectors.toCollection(TreeSet::new));
     
          
          // 将元素转为String,并串联他们,中间的分隔符是逗号
          String joined = things.stream()
                                .map(Object::toString)
                                .collect(Collectors.joining(", "));
     
          // 见员工的工资求和
          int total = employees.stream()
                               .collect(Collectors.summingInt(Employee::getSalary)));
     
          // 将员工按部门分组
          Map<Department, List<Employee>> byDept
              = employees.stream()
                         .collect(Collectors.groupingBy(Employee::getDepartment));
     
          // 求出各部门的薪资总和
          Map<Department, Integer> totalByDept
              = employees.stream()
                         .collect(Collectors.groupingBy(Employee::getDepartment,
                                                        Collectors.summingInt(Employee::getSalary)));
     
          // 按照分数及格与否对学生分区
          Map<Boolean, List<Student>> passingFailing =
              students.stream()
                      .collect(Collectors.partitioningBy(s -> s.getGrade() >= PASS_THRESHOLD));
    
    

    二 常用静态工具方法

    Collector<T, ?, C> toCollection(Supplier<C> collectionFactory)
     含义:将元素聚合成Collection
     泛型含义:
      T 输入的元素的类型
      C 聚合结果的Collection类型
     参数含义:Supplier接口的作用是不接受参数,返回C类型,collectionFactory的含义就是提供聚合的结果集合,通过该参数我们可以构造ArrayList、Set等等
     实例分析:

    public class StreamTest {
        public static void main(String[] args) {
    
            List<String> stringList = Arrays.asList("Hello", "Java", "JDK", "Android","Kotlin","World");
            ArrayList<Integer> collect = stringList.stream()
                    .map(String::length)//将字符串转为长度
                    .collect(Collectors.toCollection(ArrayList::new));//聚合至ArrayList
            System.out.println(collect);
    
            TreeSet<Integer> treeSet = stringList.stream()
                    .map(String::length)
                    .collect(Collectors.toCollection(TreeSet::new));//聚合至TreeSet
            System.out.println(treeSet);
            //TreeSet的特点是 无序和唯一
    
        }
    }
    

    Collector<T, ?, List<T>> toList()
     含义:将元素聚合成ArrayList,是上述的方法的特殊化
     泛型含义:
      T 输入的元素的类型和结果集合的元素类型
     实例分析:

    public class StreamTest {
        public static void main(String[] args) {
            List<String> stringList = Arrays.asList("Hello", "Java", "JDK", "Android","Kotlin","World");
            List<Integer> collect = stringList.stream()
                    .map(String::length)//将元素转为长度
                    .collect(Collectors.toList());//生成ArrayList集合
            System.out.println(collect);
        }
    }
    

    Collector<T, ?, Set<T>> toSet()
     含义:将元素聚合成HashSet,是上述的方法的特殊化
     泛型含义:
      T 输入的元素的类型和结果集合的元素类型
     实例分析:

    public class StreamTest {
        public static void main(String[] args) {
            List<String> stringList = Arrays.asList("Hello", "Java", "JDK", "Android", "Kotlin", "World");
            Set<Integer> collect = stringList.stream()
                    .map(String::length)//将元素转为长度
                    .collect(Collectors.toSet());//生成HashSet集合
            System.out.println(collect);
        }
    }
    

    Collector<CharSequence, ?, String> joining()
     含义:拼接输入元素到一个String中,是有序的
     实例分析:

    public class StreamTest {
        public static void main(String[] args) {
            List<String> stringList = Arrays.asList("Hello", "Java", "JDK", "Android", "Kotlin", "World");
            String collect = stringList.stream()
                    .collect(Collectors.joining());
            System.out.println(collect);
            //结果 HelloJavaJDKAndroidKotlinWorld 按着元素的顺序拼接
        }
    }
    

    Collector<CharSequence, ?, String> joining(CharSequence delimiter)
     含义:以指定的分隔符,有序的拼接输入元素到一个String
     参数含义:delimiter就是分隔符,比如元素是a和b,分隔符是、。拼接后的结果是a、b
     实例分析:

    public class StreamTest {
        public static void main(String[] args) {
    
            List<String> stringList = Arrays.asList("Hello", "Java", "JDK", "Android", "Kotlin", "World");
            String collect = stringList.stream()
                    .collect(Collectors.joining("、"));
            System.out.println(collect);
            
            结果 Hello、Java、JDK、Android、Kotlin、World 
        }
    }
    

    Collector<CharSequence, ?, String> joining(CharSequence delimiter,
    CharSequence prefix, CharSequence suffix)

     含义:以指定的分隔符、前缀和后缀,有序的拼接输入元素到一个String
     参数含义:delimiter就是分隔符,prefix是前缀,suffix是后缀。比如元素是a和b,分隔符是、,前缀是[,后缀是]。拼接后的结果是[a、b]
     实例分析:

    public class StreamTest {
        public static void main(String[] args) {
            List<String> stringList = Arrays.asList("Hello", "Java", "JDK", "Android", "Kotlin", "World");
            String collect = stringList.stream()
                    .collect(Collectors.joining("、","[","]"));
            System.out.println(collect);
            结果 [Hello、Java、JDK、Android、Kotlin、World]
        }
    }
    

    Collector<T, ?, R> mapping(Function<? super T, ? extends U> mapper, Collector<? super U, A, R> downstream)
     含义:将一个Collector的类型进行转换,在进行元素聚合之前,使用mapper参数将每一个输入的T类型的元素转换为U类型。mapping函数常用于多级分区和多级分组
     泛型含义:
      T 输入的元素的类型
      U downstream的输入类型,也就是mapper的结果类型
      A downstream的中间聚合的类型
      R 聚合的结果类型
     参数含义:Function接口的作用是接受一个T类型的参数,返回U类型,mapper的含义就是装换流中元素,downstream接受转换后的类型,downstream的聚合结果是R类型,同返回值的结果聚合类型一致。约等于 downstream的结果就是该函数返回的结果
     实例分析:

    public class StreamTest {
        public static void main(String[] args) {
            List<String> stringList = Arrays.asList("Hello", "Java", "JDK", "Android", "Kotlin", "World");
    
            List<Integer> collect = stringList.stream()
                    .collect(Collectors.mapping(String::length, Collectors.toList()));
                    //将集合的元素转为长度,同时聚合至list,
                    //Collectors.toList()的结果就是整个链的结果
            System.out.println(collect);
            结果 [5, 4, 3, 7, 6, 5]
        }
    }
    

    Collector<T,A,RR> collectingAndThen(Collector<T,A,R> downstream, Function<R,RR> finisher)
     含义:对参数的Collector的聚合结果进行终端转换。比如downstream的聚合结果是List,通过finisher的转换行为将其转为Class类型
     泛型含义:
      T 输入的元素的类型
      A downstream的中间聚合的类型
      R downstream聚合的结果类型
      RR downstream的聚合结果转换后的最终类型
     参数含义:downstream进行聚合操作,操作的结果是R类型。finisher的接受一个参数,返回一个结果,接受downstream的R类型的聚合结果,返回一个RR类型的结果
     实例分析:

    public class StreamTest {
        public static void main(String[] args) {
            List<String> stringList = Arrays.asList("Hello", "Java", "JDK", "Android", "Kotlin", "World");
    
            Class<? extends List> collect = stringList.stream()
                    .collect(
                            //首先将元素聚合至list
                            //然后将List类型转为Class
                            //最终聚合的结果就是Class对象
                            Collectors.collectingAndThen(Collectors.toList(), it -> it.getClass())
                    );
            System.out.println(collect);
            结果就是 class java.util.ArrayList
        }
    }
    

    Collector<T, ?, Long> counting()
     含义:计算出输入元素的个数,如果没有输入元素,结果就是0
     泛型含义:
      T 输入的元素的类型
      Long 结算的结果是Long
     实例分析:

    public class StreamTest {
        public static void main(String[] args) {
            List<String> stringList = Arrays.asList("Hello", "Java", "JDK", "Android", "Kotlin", "World");
    
            Long collect = stringList.stream()
                    .collect(Collectors.counting());
            System.out.println(collect);
            //结果就是 6
        }
    }
    

    Collector<T, ?, Optional<T>>
    minBy(Comparator<? super T> comparator)

     含义:根据参数中的比较器计算出输入元素中逻辑意义最小的元素
     泛型含义:
      T 输入的元素的类型
      Optional<T> 结果元素,设计的意义是避免空指针异常
     参数含义:comparator比较器
     实例分析:

    public class StreamTest {
        public static void main(String[] args) {
            List<String> stringList = Arrays.asList("Hello", "Java", "JDK", "Android", "Kotlin", "World");
    
            Optional<String> collect = stringList.stream()
                    //比较器比较的是字符串的长度
                    .collect(Collectors.minBy(Comparator.comparingInt(String::length)));
            System.out.println(collect.orElse(""));
            //结果就是 JDK
        }
    }
    

    Collector<T, ?, Integer> summingInt(ToIntFunction<? super T> mapper)
     含义:根据参数的mapper将T类型的元素,转为Integer,然后求和。
     泛型含义:
      T 输入的元素的类型
      Integer 求和的结果是Integer
     参数含义:mapper转换器,用于将T转为Integer
     实例分析:

    public class StreamTest {
        public static void main(String[] args) {
            List<String> stringList = Arrays.asList("Hello", "Java", "JDK", "Android", "Kotlin", "World");
    
            Integer collect = stringList.stream()
                    //将字符串转为其长度,然后聚合其和
                    .collect(Collectors.summingInt(String::length));
            System.out.println(collect);
            //结果就是 字符串的总长度
        }
    }
    

    Collector<T, ?, Double> averagingDouble(ToDoubleFunction<? super T> mapper)
     含义:根据参数的mapper将T类型的元素,转为Double,然后求出所有Double的平均值。
     泛型含义:
      T 输入的元素的类型
      Double 平均值的结果是Double
     参数含义:
      mapper转换器,用于将T转为Double
     实例分析:

    public class StreamTest {
        public static void main(String[] args) {
            List<String> stringList = Arrays.asList("Hello", "Java", "JDK", "Android", "Kotlin", "World");
    
            Double collect = stringList.stream()
                    //将字符串转为其长度,然后聚合其平均值
                    .collect(Collectors.averagingDouble(String::length));
            System.out.println(collect);
            //结果就是 字符串的平均值
        }
    }
    

    Collector<T, ?, T> reducing(T identity, BinaryOperator<T> op)
     含义:使用identity初始值和op函数对输入的元素进行聚合操作
     泛型含义:
      T 输入的元素的类型和结果类型
     参数含义:
      identity是聚合的初始值,op是聚合函数。比如元素求和:identity就是0,op的行为就是累加
     实例分析:

    public class StreamTest {
        public static void main(String[] args) {
            List<String> stringList = Arrays.asList("Hello", "Java", "JDK", "Android", "Kotlin", "World");
    
            String collect = stringList.stream()
                    //元素的拼接,初始值为“”,left就是上次聚合的结果 right就是新的输入元素
                    .collect(Collectors.reducing("", (left, right) -> left + right));
            System.out.println(collect);
            //结果就是 字符串的拼接结果
        }
    }
    

    groupingByConcurrent、groupingBy、partitioningBy
     含义:对输入的元素分组和分区

    Collector<T, ?, M> toMap(Function<? super T, ? extends K> keyMapper,Function<? super T, ? extends U> valueMapper, BinaryOperator<U> mergeFunction , Supplier<M> mapSupplier )
     含义:将流中的元素聚合至Map,keyMapper将元素转为Map的Key,valueMapper将元素转为Map的value,mergeFunction用于处理key相同的情况,mapSupplier用于构造聚合结果Map
     泛型含义:
      T 输入的元素的类型
      K 聚合结果Map的key的类型
      U 聚合结果Map的value的类型
      M 聚合结果Map类型
     参数含义:
      keyMapper:接受一个T类型的参数,输出一个K类型的结果,用于将元素转为Map的key
      valueMapper:接受一个T类型的参数,输出一个U类型的结果,用于将元素转为Map的value
      mergeFunction:接受两个U类型的参数,返回一个U类型的结果,当key出现重复时,此参数用于将两个value转为一个新value
      mapSupplier:构造聚合的Map
     实例分析:

    public class StreamTest {
        public static void main(String[] args) {
            List<String> stringList = Arrays.asList("Hello", "Java", "JDK", "Android", "Kotlin", "World");
            //以字符串长度为key,字符串本身为value
            //如果两个key重复了,将两个字符串的拼接作为其value
            //聚合结果是HashMap
            HashMap<Integer, String> collect = stringList.stream()
                    .collect(Collectors.toMap(String::length,//key
                            it -> it,//value
                            (left, right) -> left + right,//处理key重复
                            HashMap::new));//构造聚合结果
            System.out.println(collect);
            结果就是 {3=JDK, 4=Java, 5=Hello, 6=Kotlin, 7=Android}
        }
    }
    

    Collector<T, ?, IntSummaryStatistics> summarizingInt(ToIntFunction<? super T> mapper)
     含义:将流中元素聚合为一个IntSummaryStatistics,IntSummaryStatistics封装了许多常见的数值操作:求和、均值以及最值等
     泛型含义:
      T 输入的元素的类型
     参数含义:
       mapper:接受一个T类型,返回一个Integer
     实例分析:

    public class StreamTest {
        public static void main(String[] args) {
            List<String> stringList = Arrays.asList("Hello", "Java", "JDK", "Android", "Kotlin", "World");
    
            IntSummaryStatistics collect = stringList.stream()
                    .collect(Collectors.summarizingInt(String::length));
    
            //平均字符串的长度
            System.out.println(collect.getAverage());
    
            //字符串的个数
            System.out.println(collect.getCount());
    
            //字符串长度的总和
            System.out.println(collect.getSum());
        }
    }
    

    相关文章

      网友评论

        本文标题:Collectors解析

        本文链接:https://www.haomeiwen.com/subject/dwfsjqtx.html