• java-jdk8的stream 流对List<map>和list<对象>集合的一个字段值计算操作reduce() collect()的使用


    reduce()这个方法可能平时用得不多,因为它的常用方法都被单独封装起来了。比如sum()max()min()count()都是通过reduce()操作的。 

    另外的几种:

    1. Mqtt是javaBean对象:
    2. Optional<Mqtt> maxTemperature = list.stream().max(Comparator.comparingInt(Mqtt::getTemperature));
    3. Optional<Mqtt> maxMethane = list.stream().max(Comparator.comparingInt(Mqtt::getMethane));
    4. Optional<Mqtt> maxHumidity = list.stream().max(Comparator.comparingInt(Mqtt::getHumidity));

     

     不给定初始值也可,此时返回类型会变成 Optional

    1. @Test
    2. public void testReduce() {
    3. Stream stream = Arrays.stream(new Integer[]{1, 2, 3, 4, 5, 6, 7, 8});
    4. //求集合元素只和
    5. Integer result = stream.reduce(0, Integer::sum);
    6. System.out.println(result);
    7. stream = Arrays.stream(new Integer[]{1, 2, 3, 4, 5, 6, 7});
    8. //求和
    9. stream.reduce((i, j) -> i + j).ifPresent(System.out::println);
    10. stream = Arrays.stream(new Integer[]{1, 2, 3, 4, 5, 6, 7});
    11. //求最大值
    12. stream.reduce(Integer::max).ifPresent(System.out::println);
    13. stream = Arrays.stream(new Integer[]{1, 2, 3, 4, 5, 6, 7});
    14. //求最小值
    15. stream.reduce(Integer::min).ifPresent(System.out::println);
    16. stream = Arrays.stream(new Integer[]{1, 2, 3, 4, 5, 6, 7});
    17. //做逻辑
    18. stream.reduce((i, j) -> i > j ? j : i).ifPresent(System.out::println);
    19. stream = Arrays.stream(new Integer[]{1, 2, 3, 4, 5, 6, 7});
    20. //求逻辑求乘机
    21. int result2 = stream.filter(i -> i % 2 == 0).reduce(1, (i, j) -> i * j);
    22. Optional.of(result2).ifPresent(System.out::println);
    23. }

    给定一个初始化值开始计算: 

    不给定初始值也可,此时返回类型会变成 Optional,初始值为什么类型,返回值就是必须是什么类型

    1. /**
    2. * T reduce(T identity, BinaryOperator accumulator);
    3. * identity:它允许用户提供一个循环计算的初始值。
    4. * accumulator:计算的累加器,
    5. */
    6. private static void testReduce() {
    7. //T reduce(T identity, BinaryOperator accumulator);
    8. System.out.println("给定个初始值,求和");
    9. System.out.println(Stream.of(1, 2, 3, 4).reduce(100, (sum, item) -> sum + item));
    10. System.out.println(Stream.of(1, 2, 3, 4).reduce(100, Integer::sum));
    11. System.out.println("给定个初始值,求min");
    12. System.out.println(Stream.of(1, 2, 3, 4).reduce(100, (min, item) -> Math.min(min, item)));
    13. System.out.println(Stream.of(1, 2, 3, 4).reduce(100, Integer::min));
    14. System.out.println("给定个初始值,求max");
    15. System.out.println(Stream.of(1, 2, 3, 4).reduce(100, (max, item) -> Math.max(max, item)));
    16. System.out.println(Stream.of(1, 2, 3, 4).reduce(100, Integer::max));
    17. //Optional reduce(BinaryOperator accumulator);
    18. // 注意返回值,上面的返回是T,泛型,传进去啥类型,返回就是啥类型。
    19. // 下面的返回的则是Optional类型
    20. System.out.println("无初始值,求和");
    21. System.out.println(Stream.of(1, 2, 3, 4).reduce(Integer::sum).orElse(0));
    22. System.out.println("无初始值,求max");
    23. System.out.println(Stream.of(1, 2, 3, 4).reduce(Integer::max).orElse(0));
    24. System.out.println("无初始值,求min");
    25. System.out.println(Stream.of(1, 2, 3, 4).reduce(Integer::min).orElse(0));
    26. }

     进阶并行操作:

    主要功能 是单参数方法的 ,下面两个一个增加初始值identity,一个是增加并行处理时,多段值的操作

    定义初始值为string类型,返回值就是string类型,

    而且串行流中组合型函数在并行执行中  (str1, str2) -> "-----"  没起到任何作用,不会调用

    第三个参数(str1, str2) -> "-----"就是所谓的组合器 combiner,这里因为是串行流,所以组合器  combiner 不会被调用,可以直接返回 null。但 combiner 本身不能为 null,否则会抛空指针异常

    串行流写法(第三个参数不起任何作用占位,返回null也行):

    1. String reduce = Stream.of(1, 2, 3, 4, 5).
    2. reduce("拼接字符串-", (str, v) -> str + v, (str1, str2) -> "-----");
    3. // 拼接字符串-12345

    串行流和并行流对比: parallel()表示并行执行

    1. //串行流,只是在当前数据集合 基础上增加1 ,第三个参数 Integer::sum 占位的,不生效
    2. Integer reduce = Arrays.asList(1, 2, 3).stream().reduce(1, Integer::sum, Integer::sum);
    3. System.err.println(reduce);
    4. //7
    5. /*
    6. 串行流说明:
    7. 1+1=2
    8. 2=2
    9. 3=3
    10. 7
    11. */
    12. //并行流,集合中每个在在多线程都去扩大1在做相加计算 ,第三个参数 Integer::sum 生效
    13. Integer reduce1 = Arrays.asList(1, 2, 3).stream().parallel().reduce(1, Integer::sum, Integer::sum);
    14. System.err.println(reduce1);
    15. //9
    16. /*
    17. 并行流说明:
    18. 1+1=2
    19. 2+1=3
    20. 3+1=4
    21. 9
    22. */

    并行内部计算调用:

    1. List integers = Arrays.asList(1, 2, 3, 4);
    2. Integer reduce = integers.stream().parallel()
    3. .reduce(1, (a, b) -> {
    4. int c = a + b;
    5. String name = Thread.currentThread().getName();
    6. System.out.printf("[内部线程调用1111]:%s,%d+%d=%d%n", name, a, b, c);
    7. return c;
    8. }, (a, b) -> {
    9. int c = a + b;
    10. String name = Thread.currentThread().getName();
    11. System.out.printf("[内部线程调用22222]:%s,%d+%d=%d%n", name, a, b, c);
    12. return c;
    13. });
    14. System.err.println(reduce);
    15. [内部线程调用1111]:main,1+3=4
    16. [内部线程调用1111]:ForkJoinPool.commonPool-worker-9,1+2=3
    17. [内部线程调用1111]:ForkJoinPool.commonPool-worker-2,1+4=5
    18. [内部线程调用1111]:ForkJoinPool.commonPool-worker-11,1+1=2
    19. [内部线程调用22222]:ForkJoinPool.commonPool-worker-2,4+5=9
    20. [内部线程调用22222]:ForkJoinPool.commonPool-worker-11,2+3=5
    21. [内部线程调用22222]:ForkJoinPool.commonPool-worker-11,5+9=14

     collect()的使用:

    1. Map count = Stream.of("hello", "world", "hello", "me", "hello", "yukina", "hello", "happy", "world")
    2. .parallel().collect(() -> new HashMap<>(),
    3. (acc, x) -> {
    4. if (!acc.containsKey(x))
    5. acc.put(x, 0);
    6. acc.compute(x, (k, v) -> v + 1);
    7. }, (a, b) -> {
    8. // combine 时必须把第二个值合并到第一个值
    9. b.forEach((kb, vb) -> {
    10. if (!a.containsKey(kb))
    11. a.put(kb, 0);
    12. a.compute(kb, (ka, va) -> va + vb);
    13. });
    14. });
    15. // {yukina=1, world=2, happy=1, me=1, hello=4}

  • 相关阅读:
    brew安装nvm报nvm command not found解决方案
    自定义filter与interceptor
    cesium01-vue中创建一个三维地球和相关的控件属性注释
    摆动序列【贪心4】
    雷达SAR成像仿真的应用(Matlab代码实现)
    猿创征文|Hadoop大数据技术
    潘多拉 IOT 开发板学习(HAL 库)—— 实验1 跑马灯(RGB)实验(学习笔记)
    Oracle控制文件control file(1)控制文件概述
    h5下载文件,无兼容问题~
    A fuzzy spectral clustering algorithm for hyperspectral image
  • 原文地址:https://blog.csdn.net/qq_38567039/article/details/126469212