gpt4 book ai didi

java - 使用 Streams API 收集器平均 BigDecimals

转载 作者:行者123 更新时间:2023-12-02 01:42:22 28 4
gpt4 key购买 nike

当前的方法基于双倍类型的产品奖励。

public Map<String, BigDecimal> averageProductPriceInCategory() {

return shopping.entrySet()
.stream()
.flatMap(e -> e.getValue().keySet().stream())
.collect(Collectors.groupingBy(Product::getCategory,
Collectors.averagingDouble(Product::getPrize)));
}

购物基本上是一张 map :Map<Client, Map<Product,Integer>> ,

  • 外键代表客户端
  • 内部 key 代表产品。产品类成员是名称、类别、价格(以前为 double 类型) - 希望将提供的代码重构为使用价格作为 BigDecimal 类型的代码
  • 内部映射值(整数)代表属于特定客户的指定产品的数量

以下代码片段只能用于计算属于指定类别的产品的总奖金。不确定如何使用 BigDecimals 计算类别的平均产品奖

Map<String, BigDecimal> totalProductPriceInEachCategory = shopping.entrySet().stream()
.flatMap(e -> e.getValue().keySet().stream())
.collect(Collectors.groupingBy(Product::getCategory,
Collectors.mapping(Product::getPrize,
Collectors.reducing(BigDecimal.ZERO, BigDecimal::add))));

最佳答案

看看如何 Collectors.averagingDouble Collectors.averagingInt 已实现。

public static <T> Collector<T, ?, Double>
averagingInt(ToIntFunction<? super T> mapper) {
return new CollectorImpl<>(
() -> new long[2],
(a, t) -> { a[0] += mapper.applyAsInt(t); a[1]++; },
(a, b) -> { a[0] += b[0]; a[1] += b[1]; return a; },
a -> (a[1] == 0) ? 0.0d : (double) a[0] / a[1], CH_NOID);
}

本质上,您需要一个可变的累积类型来保存 BigDecimal这是产品价格的总和,以及 int这是经过加工的一些产品。有了这个,问题就归结为编写一个简单的 Collector<Product, AccumulationType, BigDecimal> .

我简化了一个示例并删除了 getter/setter 和全参数构造函数。而不是嵌套类 ProductPriceSummary ,您可以对 2 个元素使用任何可变持有者类。

class AverageProductPriceCollector implements Collector<Product, AverageProductPriceCollector.ProductPriceSummary, BigDecimal> {

static class ProductPriceSummary {

private BigDecimal sum = BigDecimal.ZERO;
private int n;

}

@Override
public Supplier<ProductPriceSummary> supplier() {
return ProductPriceSummary::new;
}

@Override
public BiConsumer<ProductPriceSummary, Product> accumulator() {
return (a, p) -> {
// if getPrize() still returns double
// a.sum = a.sum.add(BigDecimal.valueOf(p.getPrize()));

a.sum = a.sum.add(p.getPrize());
a.n += 1;
};
}

@Override
public BinaryOperator<ProductPriceSummary> combiner() {
return (a, b) -> {
ProductPriceSummary s = new ProductPriceSummary();
s.sum = a.sum.add(b.sum);
s.n = a.n + b.n;

return s;
};
}

@Override
public Function<ProductPriceSummary, BigDecimal> finisher() {
return s -> s.n == 0 ?
BigDecimal.ZERO :
s.sum.divide(BigDecimal.valueOf(s.n), RoundingMode.CEILING);
}

@Override
public Set<Characteristics> characteristics() {
return Collections.emptySet();
}

}

关于java - 使用 Streams API 收集器平均 BigDecimals,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54278847/

28 4 0