@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;
}