Stream之collect汇总的使用

在这里插入图片描述

@Test
    public void collectTest(){

        @Data
        @AllArgsConstructor
        class Order{
            private Integer id;
            private String account;
            private Integer productCount;
            private Double totalAmount;
        }

        List<Order> list = new ArrayList<>();
        list.add(new Order(1, "gyp", 2, 25.12));
        list.add(new Order(2, "gyp",5, 257.23));
        list.add(new Order(3, "zhangsan",3, 23332.12));
        list.add(new Order(4, "zhangsan",3, 23332.12));

        /*
        需求:根据一批订单信息,计算每个用户的平均商品价格
        这要求要按照用户账号进行分类,Map<账号,订单>  其中订单代表【产品数量】和【总金额】  即Map< String , Order >
         */
        Map<String, Order> collect = list.stream()
        		.parallel() //有parallel()才会执行并发部分代码
                .collect(
                        //参数一:对存储初始化结果的容器进行定义
                        () -> {
                            return new HashMap<String, Order>();
                        },
                        //参数2:添加元素时候的执行逻辑
                        (HashMap<String, Order> map, Order newOrder) -> {
                            String account = newOrder.getAccount();
                            if (map.containsKey(account)) {
                                //账号已存在时怎么处理
                                Order order = map.get(account);
                                order.setProductCount(
                                        order.getProductCount()
                                                + newOrder.getProductCount());
                                order.setTotalAmount(
                                        order.getTotalAmount()
                                                + newOrder.getTotalAmount()
                                );
                            } else {
                                //账号不存在时怎么处理
                                map.put(account, newOrder);
                            }
                        },
                        //参数3:并发执行时的逻辑
                        (HashMap<String, Order> map1, HashMap<String, Order> map2) -> {

                            map2.forEach(
                                    (key2, value2) -> {
                                        map1.merge(key2, value2, (order1, order2) -> {

                                            return new Order(0, key2,
                                                    order1.getProductCount()
                                                            + order2.getProductCount(),
                                                    order1.getTotalAmount()
                                                            + order2.getTotalAmount());
                                        });
                                    });
                        });

        System.out.println(JSON.toJSONString(collect,true));
    }

map.merge方法是jdk1.8才有的,看下源码:
key:map中的键,value:使用者传入的值,remappingFunction:BiFunction函数接口(该接口接收两个值,执行自定义功能并返回最终值)。

当map中不存在指定的key时,便将传入的value设置为key的值,当key存在值时,执行一个方法——该方法接收key的旧值和传入的value,执行自定义的方法返回最终结果,并将最终结果设置为key的值。

V merge(K key, V value, BiFunction<? super V, ? super V, ? extends V> remappingFunction) {
        Objects.requireNonNull(remappingFunction);
        Objects.requireNonNull(value);
        V oldValue = get(key);
        V newValue = (oldValue == null) ? value :
                   remappingFunction.apply(oldValue, value);
        if(newValue == null) {
            remove(key);
        } else {
            put(key, newValue);
        }
        return newValue;
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值