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

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

另外的几种:

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

 

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

    @Test
    public void testReduce() {
        Stream<Integer> stream = Arrays.stream(new Integer[]{1, 2, 3, 4, 5, 6, 7, 8});
        //求集合元素只和
        Integer result = stream.reduce(0, Integer::sum);
        System.out.println(result);

        stream = Arrays.stream(new Integer[]{1, 2, 3, 4, 5, 6, 7});
        //求和
        stream.reduce((i, j) -> i + j).ifPresent(System.out::println);

        stream = Arrays.stream(new Integer[]{1, 2, 3, 4, 5, 6, 7});
        //求最大值
        stream.reduce(Integer::max).ifPresent(System.out::println);

        stream = Arrays.stream(new Integer[]{1, 2, 3, 4, 5, 6, 7});
        //求最小值
        stream.reduce(Integer::min).ifPresent(System.out::println);

        stream = Arrays.stream(new Integer[]{1, 2, 3, 4, 5, 6, 7});
        //做逻辑
        stream.reduce((i, j) -> i > j ? j : i).ifPresent(System.out::println);

        stream = Arrays.stream(new Integer[]{1, 2, 3, 4, 5, 6, 7});

        //求逻辑求乘机
        int result2 = stream.filter(i -> i % 2 == 0).reduce(1, (i, j) -> i * j);

        Optional.of(result2).ifPresent(System.out::println);
    }

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

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

    /**
     * T reduce(T identity, BinaryOperator<T> accumulator);
     * identity:它允许用户提供一个循环计算的初始值。
     * accumulator:计算的累加器,
     */
    private static void testReduce() {
        //T reduce(T identity, BinaryOperator<T> accumulator);
        System.out.println("给定个初始值,求和");
        System.out.println(Stream.of(1, 2, 3, 4).reduce(100, (sum, item) -> sum + item));
        System.out.println(Stream.of(1, 2, 3, 4).reduce(100, Integer::sum));
        System.out.println("给定个初始值,求min");
        System.out.println(Stream.of(1, 2, 3, 4).reduce(100, (min, item) -> Math.min(min, item)));
        System.out.println(Stream.of(1, 2, 3, 4).reduce(100, Integer::min));
        System.out.println("给定个初始值,求max");
        System.out.println(Stream.of(1, 2, 3, 4).reduce(100, (max, item) -> Math.max(max, item)));
        System.out.println(Stream.of(1, 2, 3, 4).reduce(100, Integer::max));
 
        //Optional<T> reduce(BinaryOperator<T> accumulator);
        // 注意返回值,上面的返回是T,泛型,传进去啥类型,返回就是啥类型。
        // 下面的返回的则是Optional类型
        System.out.println("无初始值,求和");
        System.out.println(Stream.of(1, 2, 3, 4).reduce(Integer::sum).orElse(0));
        System.out.println("无初始值,求max");
        System.out.println(Stream.of(1, 2, 3, 4).reduce(Integer::max).orElse(0));
        System.out.println("无初始值,求min");
        System.out.println(Stream.of(1, 2, 3, 4).reduce(Integer::min).orElse(0));
 
    }

 进阶并行操作:

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

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

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

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

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

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

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

//串行流,只是在当前数据集合    基础上增加1 ,第三个参数 Integer::sum 占位的,不生效
Integer reduce = Arrays.asList(1, 2, 3).stream().reduce(1, Integer::sum, Integer::sum);
System.err.println(reduce);
//7
        /*
        串行流说明:
            1+1=2
            2=2
            3=3
                7
         */

//并行流,集合中每个在在多线程都去扩大1在做相加计算 ,第三个参数 Integer::sum 生效
Integer reduce1 = Arrays.asList(1, 2, 3).stream().parallel().reduce(1, Integer::sum, Integer::sum);
System.err.println(reduce1);
//9
        /*
        并行流说明:
            1+1=2
            2+1=3
            3+1=4
                9
         */

并行内部计算调用:

List<Integer> integers = Arrays.asList(1, 2, 3, 4);
        Integer reduce = integers.stream().parallel()
                .reduce(1, (a, b) -> {
                    int c = a + b;
                    String name = Thread.currentThread().getName();
                    System.out.printf("[内部线程调用1111]:%s,%d+%d=%d%n", name, a, b, c);
                    return c;
                }, (a, b) -> {
                    int c = a + b;
                    String name = Thread.currentThread().getName();
                    System.out.printf("[内部线程调用22222]:%s,%d+%d=%d%n", name, a, b, c);
                    return c;
                });
        System.err.println(reduce);


[内部线程调用1111]:main,1+3=4
[内部线程调用1111]:ForkJoinPool.commonPool-worker-9,1+2=3
[内部线程调用1111]:ForkJoinPool.commonPool-worker-2,1+4=5
[内部线程调用1111]:ForkJoinPool.commonPool-worker-11,1+1=2
[内部线程调用22222]:ForkJoinPool.commonPool-worker-2,4+5=9
[内部线程调用22222]:ForkJoinPool.commonPool-worker-11,2+3=5
[内部线程调用22222]:ForkJoinPool.commonPool-worker-11,5+9=14

 collect()的使用:

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

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值