gpt4 book ai didi

java - BigDecimal 汇总统计

转载 作者:行者123 更新时间:2023-12-04 13:18:26 24 4
gpt4 key购买 nike

我有一个 BigDecimals 列表。

List<BigDecimal> amounts = new ArrayList<>()

我如何使用 Java 8 流获取上述列表的汇总统计数据,而不会丢失 BigDecimal 最多 3-4 个小数位的精度?

最佳答案

我创建了一个 BigDecimal this answer 的通用汇总统计收集器的特化,这允许将其扩展为也支持求和,因此也计算平均值:

/**
* Like {@code DoubleSummaryStatistics}, {@code IntSummaryStatistics}, and
* {@code LongSummaryStatistics}, but for {@link BigDecimal}.
*/
public class BigDecimalSummaryStatistics implements Consumer<BigDecimal> {

public static Collector<BigDecimal,?,BigDecimalSummaryStatistics> statistics() {
return Collector.of(BigDecimalSummaryStatistics::new,
BigDecimalSummaryStatistics::accept, BigDecimalSummaryStatistics::merge);
}
private BigDecimal sum = BigDecimal.ZERO, min, max;
private long count;

public void accept(BigDecimal t) {
if(count == 0) {
Objects.requireNonNull(t);
count = 1;
sum = t;
min = t;
max = t;
}
else {
sum = sum.add(t);
if(min.compareTo(t) > 0) min = t;
if(max.compareTo(t) < 0) max = t;
count++;
}
}
public BigDecimalSummaryStatistics merge(BigDecimalSummaryStatistics s) {
if(s.count > 0) {
if(count == 0) {
count = s.count;
sum = s.sum;
min = s.min;
max = s.max;
}
else {
sum = sum.add(s.sum);
if(min.compareTo(s.min) > 0) min = s.min;
if(max.compareTo(s.max) < 0) max = s.max;
count += s.count;
}
}
return this;
}

public long getCount() {
return count;
}

public BigDecimal getSum()
{
return sum;
}

public BigDecimal getAverage(MathContext mc)
{
return count < 2? sum: sum.divide(BigDecimal.valueOf(count), mc);
}

public BigDecimal getMin() {
return min;
}

public BigDecimal getMax() {
return max;
}

@Override
public String toString() {
return count == 0? "empty": (count+" elements between "+min+" and "+max+", sum="+sum);
}
}

它可以类似于 DoubleSummaryStatistics 使用对方,如
BigDecimalSummaryStatistics bds = list.stream().collect(BigDecimalSummaryStatistics.statistics());

作为一个完整的例子:
List<BigDecimal> list = Arrays.asList(BigDecimal.ZERO, BigDecimal.valueOf(-2), BigDecimal.ONE);
BigDecimalSummaryStatistics bds = list.stream().collect(BigDecimalSummaryStatistics.statistics());
System.out.println(bds);
System.out.println("average: "+bds.getAverage(MathContext.DECIMAL128));

3 elements between -2 and 1, sum=-1
average: -0.3333333333333333333333333333333333

关于java - BigDecimal 汇总统计,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51645432/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com