8-归约与汇总
归约与汇总
归约(reduce):将Stream流中元素转化成一个值
汇总(collect):将Stream流中元素转换成一个容器
接口方法
1 /** 2 *第一个参数表示初始值 3 *第二个参数表示计算逻辑 4 *第三个参数表示合并逻辑 5 */ 6 <U> U reduce(U identity, 7 BiFunction<U, ? super T, U> accumulator, 8 BinaryOperator<U> combiner);
1 /** 2 *第一个参数表示初始值 3 *第二个参数表示计算逻辑 4 *第三个参数表示合并逻辑 5 */ 6 <R> R collect(Supplier<R> supplier, 7 BiConsumer<R, ? super T> accumulator, 8 BiConsumer<R, R> combiner);
代码示例
1 import com.alibaba.fastjson.JSON; 2 import com.google.common.collect.Lists; 3 import lombok.AllArgsConstructor; 4 import lombok.Data; 5 import org.junit.Test; 6 7 import java.util.HashMap; 8 import java.util.List; 9 10 /** 11 * @description: 归约与汇总操作 12 */ 13 public class ReduceAndCollectTest { 14 15 @Test 16 public void reduceTest() { 17 /** 18 * 订单对象 19 */ 20 @Data 21 @AllArgsConstructor 22 class Order { 23 /** 24 * 订单编号 25 */ 26 private Integer id; 27 /** 28 * 商品数量 29 */ 30 private Integer productCount; 31 /** 32 * 消费总金额 33 */ 34 private Double totalAmount; 35 } 36 37 /** 38 * 准备数据 39 */ 40 List<Order> list = Lists.newArrayList(); 41 list.add(new Order(1, 2, 25.12)); 42 list.add(new Order(2, 5, 257.23)); 43 list.add(new Order(3, 3, 23332.12)); 44 45 /** 46 * 以前的方式: 47 * 1. 计算商品数量 48 * 2. 计算消费的总金额 49 */ 50 51 /** 52 * 汇总商品数量和总金额 53 */ 54 Order order = list.stream() 55 .parallel() 56 .reduce( 57 //初始化的值 58 new Order(0, 0, 0.0), 59 //Stream中两个元素计算逻辑 60 (Order order1, Order order2) -> { 61 System.out.println("执行 计算逻辑 方法"); 62 int productCount = order1.getProductCount() + order2.getProductCount(); 63 double totalAmount = order1.getTotalAmount() + order2.getTotalAmount(); 64 return new Order(0, productCount, totalAmount); 65 }, 66 //并行情况下,多个并行结果如何合并 67 (Order order1, Order order2) -> { 68 System.out.println("执行 并行 方法"); 69 int productCount = order1.getProductCount() + order2.getProductCount(); 70 double totalAmount = order1.getTotalAmount() + order2.getTotalAmount(); 71 return new Order(0, productCount, totalAmount); 72 }); 73 System.out.println(JSON.toJSONString(order, true)); 74 } 75 76 @Test 77 public void collectTest(){ 78 /** 79 * 订单对象 80 */ 81 @Data 82 @AllArgsConstructor 83 class Order { 84 /** 85 * 订单编号 86 */ 87 private Integer id; 88 /** 89 * 用户账号 90 */ 91 private String account; 92 /** 93 * 商品数量 94 */ 95 private Integer productCount; 96 /** 97 * 消费总金额 98 */ 99 private Double totalAmount; 100 } 101 102 /** 103 * 准备数据 104 */ 105 List<Order> list = Lists.newArrayList(); 106 list.add(new Order(1, "xiaoming", 2, 25.12)); 107 list.add(new Order(2, "xiaoming", 5, 257.23)); 108 list.add(new Order(3, "xiaoting", 3, 23332.12)); 109 110 /** 111 * Map<用户账号,订单(数量和金额)> 112 */ 113 114 HashMap<String, Order> hashMap = list.stream() 115 .parallel() 116 .collect( 117 () -> { 118 System.out.println("执行 初始化容器 操作!!!"); 119 return new HashMap<String, Order>(); 120 }, 121 (HashMap<String, Order> map, Order newOrder) -> { 122 System.out.println("执行 新元素添加到容器操作 操作!!!"); 123 /** 124 * 新元素的acount已经在map存在了 125 * 不存在 126 */ 127 String acount = newOrder.getAccount(); 128 if (map.containsKey(acount)) { 129 Order order = map.get(acount); 130 order.setProductCount( 131 newOrder.getProductCount() 132 + order.getProductCount()); 133 } else { 134 map.put(acount, newOrder); 135 } 136 }, 137 (HashMap<String, Order> map1, HashMap<String, Order> map2) -> { 138 System.out.println("执行 并行结果合并 操作!!!"); 139 map2.forEach((key, value) -> { 140 map1.merge(key, value, (order1, order2) -> { 141 //TODO 注意:一定要用map1做合并,因为最后collect返回的是map1 142 return new Order(0, key, 143 order1.getProductCount() 144 + order2.getProductCount(), 145 order1.getTotalAmount() 146 + order2.getTotalAmount()); 147 }); 148 }); 149 }); 150 System.out.println(JSON.toJSONString(hashMap, true)); 151 } 152 }

浙公网安备 33010602011771号