//使用示例1 计算总包费用 BigDecimal packFee = schemes.stream().collect(Collectors.collectingAndThen( SchemeDataUtilService.getContAmtDtoSupplier(DiscountScheme::getDiscountAmount), a -> a.getAmt().multiply(rate).divide(BigDecimal.valueOf(100), 4, BigDecimal.ROUND_DOWN))); //使用示例2 分组计算总金额 Collector<DiscountScheme, ?, Map<String, ContAmtDto>> discountSchemeMapCollector = Collectors.groupingBy(DiscountScheme::getPrdChannelCode, getContAmtDtoSupplier(DiscountScheme::getDiscountAmount) ); Map<String, ContAmtDto> collectAmt = schemes.stream().parallel().collect(discountSchemeMapCollector); /** * 计算T的BigDecimal类型总金额和size,汇总在ContAmtDto中 * @param converter 泛型实体的BigDecimal字段取值方法 * @param <T> 泛型实体 * @return ContAmtDto 汇总结果存储DTO */ public static <T> Collector<T, ContAmtDto, ContAmtDto> getContAmtDtoSupplier(Function<T,BigDecimal> converter) { return Collector.of(() -> new ContAmtDto(), (a, t) -> { if (null == a) { a = new ContAmtDto().setAmt(BigDecimal.ZERO).setCount(0); } a.setAmt(a.getAmt().add(Optional.of(converter.apply(t)).orElse(BigDecimal.ZERO))); a.setCount(a.getCount() + 1); }, (a, b) -> { a.setAmt(a.getAmt().add(b.getAmt())); a.setCount(a.getCount()+b.getCount()); return a; }, a -> a, Collector.Characteristics.UNORDERED); } /** * 以条数和金额汇总的DTO */ @Data @Accessors(chain = true) public class ContAmtDto { //须要设置初始值 private Integer count=0; //须要设置初始值 private BigDecimal amt=BigDecimal.ZERO; }