zoukankan      html  css  js  c++  java
  • JDK1.8新特性(二):Collectors收集器类

    一. 什么是Collectors?

    Java 8 API添加了一个新的抽象称为流Stream,我们借助Stream API可以很方便的操作流对象。

    Stream中有两个方法collect和collectingAndThen,可以借助Collectors收集器类对流中的数据进行聚合操作,例如将元素累积到集合中,并根据各种标准对元素进行汇总,分类等操作。

    二. 举个例子?

    //获取String集合
    List<String> strings = Arrays.asList("ab", "", "bc", "cd", "abcd","", "jkl");
    //通过stream操作集合
    List<String> stringList = strings.stream()
        //为集合中的每一个元素拼接“???”
        .map(s -> s += "???")
        //返回集合
        .collect(Collectors.toList());
    

    如代码所示,我们可以很方便的通过Collectors类对被处理的流数据进行聚合操作,包括并不仅限与将处理过的流转换成集合

    三. 如何使用Collectors?

    1. Collectors类中提供的方法

    总结一下,就是以下几类方法:

    1.1 转换成集合:toList(),toSet(),toMap(),toCollection()

    1.2 将集合拆分拼接成字符串:joining()

    1.3 求最大值、最小值、求和、平均值 :maxBy(),minBy(),summingInt(),averagingDouble()

    1.4 对集合分组:groupingBy(),partitioningBy()

    1.5 对数据进行映射:mapping()

    2. Collectors类方法源码

    public final class Collectors {
    
        // 转换成集合
        public static <T> Collector<T, ?, List<T>> toList();
        public static <T> Collector<T, ?, Set<T>> toSet();
        public static <T, K, U> Collector<T, ?, Map<K,U>> toMap(Function<? super T, ? extends K> keyMapper,
                                                                Function<? super T, ? extends U> valueMapper);
        public static <T, C extends Collection<T>> Collector<T, ?, C> toCollection(Supplier<C> collectionFactory);
    
        // 拼接字符串,有多个重载方法                                  
        public static Collector<CharSequence, ?, String> joining(CharSequence delimiter);   
        public static Collector<CharSequence, ?, String> joining(CharSequence delimiter,
                                                                 CharSequence prefix,
                                                                 CharSequence suffix);      
        // 最大值、最小值、求和、平均值                                                         
        public static <T> Collector<T, ?, Optional<T>> maxBy(Comparator<? super T> comparator);
        public static <T> Collector<T, ?, Optional<T>> minBy(Comparator<? super T> comparator);
        public static <T> Collector<T, ?, Integer> summingInt(ToIntFunction<? super T> mapper);      
        public static <T> Collector<T, ?, Double> averagingDouble(ToDoubleFunction<? super T> mapper);                   
    
        // 分组:可以分成true和false两组,也可以根据字段分成多组                                 
        public static <T, K> Collector<T, ?, Map<K, List<T>>> groupingBy(Function<? super T, ? extends K> classifier);
        // 只能分成true和false两组
        public static <T> Collector<T, ?, Map<Boolean, List<T>>> partitioningBy(Predicate<? super T> predicate);
    
        // 映射
        public static <T, U, A, R> Collector<T, ?, R> mapping(Function<? super T, ? extends U> mapper,
                                                              Collector<? super U, A, R> downstream);
    
        public static <T, U> Collector<T, ?, U> reducing(U identity,
                                                         Function<? super T, ? extends U> mapper,
                                                         BinaryOperator<U> op);
    }
    

    四. 实例

    //接下来的示例代码基于此集合
    List<String> strings = Arrays.asList("ab", "s", "bc", "cd", "abcd","sd", "jkl");
    

    1. 将流数据转换成集合

    //转换成list集合
    List<String> stringList = strings.stream().collect(Collectors.toList());
    
    //转换成Set集合
    Set<String> stringSet = strings.stream().collect(Collectors.toSet());
    
    //转换成Map集合
    Map<String,Object> stringObjectMap = strings.stream()
        .collect(Collectors.toMap(k -> k, v -> v ));
    
    System.out.println(stringList);
    System.out.println(stringSet);
    System.out.println(stringObjectMap);
    
    //=================打印结果=================
    [ab, s, bc, cd, abcd, sd, jkl]
    [ab, bc, cd, sd, s, jkl, abcd]
    {sd=sd, cd=cd, bc=bc, ab=ab, s=s, jkl=jkl, abcd=abcd}
    

    2. 将集合拆分拼接成字符串

    //joining
    String str1 = strings.stream()
        .collect(Collectors.joining("--"));
    
    //collectingAndThen
    String str2 = strings.stream()
        .collect(Collectors.collectingAndThen(
            //在第一个joining操作的结果基础上再进行一次操作
            Collectors.joining("--"), s1 -> s1 += ",then"
        ));
    
    System.out.println(str1);
    System.out.println(str2);
    
    //=================打印结果=================
    ab--s--bc--cd--abcd--sd--jkl
    ab--s--bc--cd--abcd--sd--jkl,then
    

    3. 求最大值、最小值、求和、平均值

    List<Integer> list = Arrays.asList(1, 2, 3, 4, 5);
    
    //最大值
    Integer maxValue = list.stream().collect(Collectors.collectingAndThen(
        //maxBy需要Comparator.comparingInt来确定排序规则
        Collectors.maxBy(Comparator.comparingInt(a -> a)), Optional::get
    ));
    //最小值
    Integer minValue = list.stream().collect(Collectors.collectingAndThen(
        //minBy需要Comparator.comparingInt来确定排序规则
        Collectors.minBy(Comparator.comparingInt(a -> a)), Optional::get
    ));
    //求和
    Integer sumValue = list.stream().collect(Collectors.summingInt(i -> i));
    //平均值
    Double avgValue = list.stream().collect(Collectors.averagingDouble(i -> i));
    
    System.out.println("列表中最大的数 : " + maxValue);
    System.out.println("列表中最小的数 : " + minValue);
    System.out.println("所有数之和 : " + sumValue);
    System.out.println("平均数 : " + avgValue);
    
    //=================打印结果=================
    列表中最大的数 : 5
    列表中最小的数 : 1
    所有数之和 : 15
    平均数 : 3.0
    

    虽然这样也可以,但是明显IntSummaryStatistics要更灵活点

    4. 对集合分组

    Map<Integer, List<String>> map = strings.stream()
        //根据字符串长度分组(同理,对对象可以通过某个属性分组)
        .collect(Collectors.groupingBy(String::length));
    
    Map<Boolean, List<String>> map2 = strings.stream()
        //根据字符串是否大于2分组
        .collect(Collectors.groupingBy(s -> s.length() > 2));
    
    System.out.println(map);
    System.out.println(map2);
    
    //=================打印结果=================
    {1=[s], 2=[ab, bc, cd, sd], 3=[jkl], 4=[abcd]}
    {false=[ab, s, bc, cd, sd], true=[abcd, jkl]}
    

    5.对数据进行映射

    String str = strings.stream().collect(Collectors.mapping(
        //先对集合中的每一个元素进行映射操作
        s -> s += ",mapping",
        //再对映射的结果使用Collectors操作
        Collectors.collectingAndThen(Collectors.joining(";"), s -> s += "=====then" )
    ));
    
    System.out.println(str);
    
    //=================打印结果=================
    ab,mapping;s,mapping;bc,mapping;cd,mapping;abcd,mapping;sd,mapping;jkl,mapping=====then
    
  • 相关阅读:
    HashMap_经典存储_经典分拣思路
    (GOF23设计模式)_单例模式_应用场景_饿汉式_懒汉式
    sql简单测试
    Java概述
    搭建集群时的问题总结
    在Java连接hbase时出现的问题
    JavaAPI与hbase的交互
    Resourcemanager的高可用
    hbase安装
    hbase报错org.apache.hadoop.hbase.TableExistsException: hbase:namespace
  • 原文地址:https://www.cnblogs.com/Createsequence/p/11968254.html
Copyright © 2011-2022 走看看