美文网首页
JDK8-Stream-Collectors

JDK8-Stream-Collectors

作者: 张明学 | 来源:发表于2020-09-10 23:30 被阅读0次

    Collectors类作为Collector接口对应的工具类,除提供了对应的实现类(CollectorImpl)以外,还提供了各种快速生成Collector实例的工具方法.

    JDK8-Stream

    toList/toSet/(toCollection)

    无入参, 转set集合、List集合或自定义的集合

    @Test
    public void test1() {
        // 转Set集合
        Set<String> set = Stream.of("ZH", "cn", "hello", "Word").collect(Collectors.toSet());
        // 转List集合
        List<String> list = Stream.of("ZH", "cn", "hello", "Word").collect(Collectors.toList());
        // 特定转换
        LinkedList linkedList = Stream.of("ZH", "cn", "hello", "Word").collect(Collectors.toCollection(()->{
            return new LinkedList<>();
        }));
    }
    

    toMap/toConcurrentMap及各种重载形式

    此两类方法之间为是否并发的区别,最终结果分别为Map和ConcurrentMap,同时各自有三种重载形式

    入参说明

    keyMapper: 将stream内部元素映射为key的表达式
    valueMapper: 将stream内部元素映射为value的表达式
    mergeFunction: 当同一个key对应的value冲突时,重新映射的表达式
    mapSupplier: map的supplier

    // 只需要提供key的生成器和value生成器
    public static <T, K, U>
    Collector<T, ?, Map<K,U>> toMap(Function<? super T, ? extends K> keyMapper,
                                    Function<? super T, ? extends U> valueMapper) {
        return toMap(keyMapper, valueMapper, throwingMerger(), HashMap::new);
    }
    // 只需要提供key的生成器、value生成器、同一个key对应的value冲突时,重新映射的表达式
    public static <T, K, U>
        Collector<T, ?, Map<K,U>> toMap(Function<? super T, ? extends K> keyMapper,
                                        Function<? super T, ? extends U> valueMapper,
                                        BinaryOperator<U> mergeFunction) {
            return toMap(keyMapper, valueMapper, mergeFunction, HashMap::new);
        }
    // 只需要提供key的生成器、value生成器、同一个key对应的value冲突时,重新映射的表达式、map的生成方法
    public static <T, K, U, M extends Map<K, U>>
        Collector<T, ?, M> toMap(Function<? super T, ? extends K> keyMapper,
                                    Function<? super T, ? extends U> valueMapper,
                                    BinaryOperator<U> mergeFunction,
                                    Supplier<M> mapSupplier) {
            BiConsumer<M, T> accumulator
                    = (map, element) -> map.merge(keyMapper.apply(element),
                                                  valueMapper.apply(element), mergeFunction);
            return new CollectorImpl<>(mapSupplier, accumulator, mapMerger(mergeFunction), CH_ID);
        }
    

    示例:

    /**
     * toMap/toConcurrentMap及各种重载形式
     */
    @Test
    public void testToMap() {
        List<Person> listPerson = new ArrayList<>();
        listPerson.add(new Person(10, "张三"));
        listPerson.add(new Person(12, "李四"));
        listPerson.add(new Person(14, "王五"));
        // 简单API的使用
        Map result = listPerson.stream().collect(Collectors.toMap(
                // key的生成
                (item) -> {
                    return item.getId();
                },
                // value的生成
                (item) -> {
                    return item;
                }));
    
        System.out.println(result);//{10=Person(id=10, name=张三), 12=Person(id=12, name=李四), 14=Person(id=14, name=王五)}
    
        listPerson.add(new Person(14, "王麻子"));
        // 复杂API的使用
        result = listPerson.stream().collect(Collectors.toMap(
                // 将stream内部元素映射为key的表达式
                (item) -> item.getId(),
                // 将stream内部元素映射为value的表达式
                (item) -> item,
                // 同一个key对应的value冲突时,重新映射的表达式
                (item1Value, item2Value) -> {
                    if (item1Value.getName().length() > item2Value.getName().length()) {
                        return item1Value;
                    } else {
                        return item2Value;
                    }
                },
                // map的构造器
                () -> {
                    return new TreeMap();
                }));
        System.out.println(result);//{10=Person(id=10, name=张三), 12=Person(id=12, name=李四), 14=Person(id=14, name=王麻子)}
    
    }
    

    joining 连接器

    将steam里的元素连接成一个String

    @Test
    public void testJoining() {
        String result = Stream.of("ZH", "cn", "hello", "Word").collect(Collectors.joining());
        System.out.println(result);//ZHcnhelloWord
        // 连接符、前缀、后缀
        result = Stream.of("ZH", "cn", "hello", "Word").collect(Collectors.joining("-", "pre", "fix"));
        System.out.println(result);//preZH-cn-hello-Wordfix
    }
    

    reducing及其重载形式,maxBy,minBy

    reducing表示对steam里的元素做运算,最终等到一个值。
    identity:初值,设置一个steam元素与外部比较的一个初始值。
    mapper: 将stream内部类型映射为U类型的方法
    BinaryOperator:op两个U类型值合并运算的方法

    // 直接对steam里的元素做合并运算,比较类型即为steam里的类型
    public static <T> Collector<T, ?, Optional<T>> reducing(BinaryOperator<T> op){
    }
    // 设置一个初始值,直接对steam里的元素做合并运算
    public static <T> Collector<T, ?, T> reducing(T identity, BinaryOperator<T> op){
    }
    // identity设置一个初始值, mapper将steam里的元素转成合并运算的对象,op合并运算的方法
    public static <T, U> Collector<T, ?, U> reducing(U identity, Function<? super T, ? extends U> mapper, BinaryOperator<U> op){
    }
    

    示例:

    @Test
    public void testReducing1() {
        Stream<String> stream = Stream.of("ZH", "cn", "hello", "Word");
        Optional<String> op1 = stream.collect(Collectors.reducing((item1, item2) -> {
            if (item1.compareTo(item2) >= 0) {
                return item1;
            } else {
                return item2;
            }
        }));
        System.out.println(op1.get());//hello
    }
    
    @Test
    public void testReducing2() {
        Stream<String> stream = Stream.of("ZH", "cn", "hello", "Word");
        String init = "WWW";
        String s1 = stream.collect(Collectors.reducing(init, (item1, item2) -> {
            if (item1.compareTo(init) > 0) {
                return item1;
            } else {
                return init;
            }
        }));
        System.out.println(s1);//WWW
    }
    
    @Test
    public void testReducing3() {
        Stream<String> stream = Stream.of("ZH", "cn", "hello", "Word");
    
        Person person = new Person();
    
        Person p1 = stream.collect(Collectors.reducing(
                // 初始值
                person,
                // 将stream内部类型转化成合并运算的对象(Person)
                (item) -> {
                    Person personItem = new Person();
                    personItem.setName(item);
                    personItem.setId(item.length());
                    return personItem;
                },
                // 根据转换后的值做合并运算
                (item1, item2) -> {
                    if (item1.getId() > item2.getId()) {
                        return item1;
                    } else {
                        return item2;
                    }
                }
        ));
        System.out.println(p1);//Person(id=5, name=hello)
    }
    

    minBy maxBy 就是BinaryOperator提供的简洁方法

    @Test
    public void testMinBy() {
        Stream<String> stream = Stream.of("ZH", "cn", "hello", "Word");
        Optional<String> p1 = stream.collect(Collectors.reducing(BinaryOperator.minBy((item1, item2) -> {
            return item1.compareTo(item2);
        })));
        System.out.println(p1.get());
    }
    

    summingLong、summingInt、summingDouble

    将steam元素转成long,int,double后做累计

    @Test
    public void testSummingInt() {
        Stream<String> stream = Stream.of("ZH", "cn", "hello", "Word");
        int count = stream.collect(Collectors.summingInt(
                // 将item转成统计维度的数字
                (item) -> {
                    return item.length();
                }));
        System.out.println(count);
    }
    

    averagingInt/averagingDouble/averagingLong

    将steam元素转成long,int,double后做平均值

    @Test
    public void testAveragingInt() {
        Stream<String> stream = Stream.of("ZH", "cn", "hello", "Word");
        double count = stream.collect(Collectors.averagingInt((item)->{
            return item.length();
        }));
        System.out.println(count);
    }
    

    summarizingInt/summarizingLong/summarizingDouble

    将steam元素转成long,int,double后做统计(最大,最小、平均值)

    @Test
    public void testSummarizingInt(){
        Stream<String> stream = Stream.of("ZH", "cn", "hello", "Word");
        IntSummaryStatistics intSummaryStatistics = stream.collect(Collectors.summarizingInt((item)->{
            return item.length();
        }));
        System.out.println(intSummaryStatistics);//IntSummaryStatistics{count=4, sum=13, min=2, average=3.250000, max=5}
    }
    

    groupingBy/groupingByConcurrent及其重载形式

    将steam元素分组后聚合,API有两种形式

    public static <T, K, A, D>
    Collector<T, ?, Map<K, D>> groupingBy(Function<? super T, ? extends K> classifier,// 分组结果map的key的生成
                                          Collector<? super T, A, D> downstream) {//分组结果map的value的生成
    }
    
    public static <T, K, D, A, M extends Map<K, D>>
        Collector<T, ?, M> groupingBy(Function<? super T, ? extends K> classifier,// 分组结果map的key的生成
                                      Supplier<M> mapFactory,// 分组结果map的生成
                                      Collector<? super T, A, D> downstream) {//分组结果map的value的生成
    }
    

    示例:

    @Test
    public void testGroupingBy1() {
        Stream<String> stream = Stream.of("ZH", "cn", "hello", "Word");
        Map<String, Long> stat = stream.collect(Collectors.groupingBy(
                // key的生成方法
                (item) -> {
                    return item.toUpperCase();
                },
                // value的内容
                Collectors.counting()));
        System.out.println(stat);//{WORD=1, HELLO=1, CN=1, ZH=1}
    }
    
    @Test
    public void testGroupingBy2() {
    
        List<Person> listPerson = new ArrayList<>();
        listPerson.add(new Person(10, "张三"));
        listPerson.add(new Person(12, "李四"));
        listPerson.add(new Person(14, "王五"));
        listPerson.add(new Person(16, "王麻子"));
    
        TreeMap obj = listPerson.stream().collect(Collectors.groupingBy(
                // key的生成方法
                (item) -> {
                    return item.getName().substring(0, 1);
                },
                // 返回Map的生成方法
                () -> {
                    return new TreeMap();
                },
                // Map的Value内容
                Collectors.toList()));
    
        System.out.println(obj);//{张=[Person(id=10, name=张三)], 李=[Person(id=12, name=李四)], 王=[Person(id=14, name=王五), Person(id=16, name=王麻子)]}
    }
    

    相关文章

      网友评论

          本文标题:JDK8-Stream-Collectors

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