• 【Java】Stream规约操作及使用场景


    reduce

    reduce操作可以从一组元素中规约生成一个值, 它可以实现多种操作, 在java流max, min, sum, count的本质都是规约操作; 下面是规约操作的定义, 它通过一个初始值identity进行累加, 最后生成一个值, 在并发并发情况下, 还可能会需要对多个累加的值进行合并

    <U> U reduce(U identity,
                 BiFunction<U, ? super T, U> accumulator,
                 BinaryOperator<U> combiner);
    
    • 1
    • 2
    • 3

    max

    下面是对reduce的一个最基本的使用, 找到长度最大的字符串的值; 它从第一个元素开始累计, 每次对比两个元素并取较大的元素; 如此进行累加, 最后得到的便是最大的元素

    System.out.println(Stream.of("I", "love", "you", "too")
            .reduce((s1, s2) -> s1.length() >= s2.length() ? s1 : s2)
            .orElse(null));
    
    System.out.println(Stream.of("I", "love", "you", "too")
            .max((s1, s2) -> s1.length() - s2.length())
            .orElse(null));
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    sum

    max无需指定幺元identitycombiner因为它是从第一个元素开始累加的; 其会从第一个元素开始累积, 并且会调用acuumulator进行combine; 而sum方法需要自己指定初始值为0, 并指定combiner的逻辑为两个分段的相加, 如下面的例子计算流中的字符数

    public void totalLength() {
        System.out.println(Stream.of("I", "love", "you", "too")
                .reduce(0
                        , (total, s) -> total + s.length()
                        , (a, b) -> a + b));
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    collect

    基本使用

    相比于之前的通过reduce生成单个元素, collect可以生成一个新的集合; 它也是java Stream中最灵活的api, 下面是将Java流转化为各种集合的例子, 它将字符串集合转化为了字符串列表和字符串与字符串长度映射的map, 为了方便操作, jdk还为我们提供了Collectors工具类, 包含了大多数jdk自带类型的操作:

    public void collect() {
        System.out.println(Stream.of("I", "love", "you", "too")
                .collect(ArrayList::new, ArrayList::add, ArrayList::addAll)
                .toString());
    
        System.out.println(Stream.of("I", "love", "you", "too")
                .collect(Collectors.toList())
                .toString());
    
        System.out.println(Stream.of("I", "love", "you", "too")
                .collect(Collectors.toCollection(LinkedList::new))
                .toString());
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    除了对集合的collect, 对于字符串还有一些扩展的功能, 如join, 下面会将字符串包裹在大括号中, 并使用, 进行分隔

    public void collectorJoin() {
        String collect = Stream.of("I", "love", "you", "too")
                .collect(Collectors.joining(",", "{", "}"));
        System.out.println(collect);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    生成map

    collect不仅可以根据集合中的数据直接生成map, 如下面就生成字符串与长度的map

    public void collectToMap() {
        Map<String, Integer> collect = Stream.of("I", "love", "you", "too")
                .collect(Collectors.toMap(Function.identity(), String::length));
        System.out.println(collect);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    还可以通过groupby进行分组, 如下面的例子中就根据字符串的长度进行分组, groupCollector是根据某个classifier进行分组, 而partitioningBy是根据predicate进行分组即将符合条件和不符合条件的分为两组

    public void groupCollector() {
        Map<Integer, List<String>> collect = Stream.of("I", "love", "you", "too")
                .collect(Collectors.groupingBy(String::length));
        System.out.println(collect);
    }
    public void partitionCollector() {
        Map<Boolean, List<String>> collect = Stream.of("I", "love", "you", "too")
                .collect(Collectors.partitioningBy(s -> s.length() > 3));
        System.out.println(collect);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    有的时候, 我们分组后并不想要原来的数据, 而是想要获得加工后的数据, collect提供了下游处理器downstream对分组后的结果进行处理; 如下面的例子中, 就对分组后的结果进行计数

    public void collectorDownstream() {
        Map<Integer, Long> collect = Stream.of("I", "love", "you", "too")
                .collect(Collectors.groupingBy(String::length, Collectors.counting()));
        System.out.println(collect);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
  • 相关阅读:
    小程序自定义tabbar如何显示隐藏
    NMap使用技巧总结(三)
    01-ZooKeeper快速入门
    Java Array、List、Set互相转化
    密码学的基础:X.690和对应的BER CER DER编码
    Camera Tuning 术语
    Ansys Zemax | 大功率激光系统的STOP分析2:如何进行光机械设计准备
    python基于django的高校奖学金管理系统
    Docsify 顶部的导航是如何配置
    3.2 AOP之代理模式
  • 原文地址:https://blog.csdn.net/apple_50661801/article/details/133526882