您可以将自定义收集器用于此任务,以计算平方和。内置
DoubleSummaryStatistics收集器不跟踪它。专家组在此主题中对此进行了讨论,但最终未实现。计算平方和的困难在于对中间结果求平方时可能发生溢出。
static class DoubleStatistics extends DoubleSummaryStatistics { private double sumOfSquare = 0.0d; private double sumOfSquareCompensation; // Low order bits of sum private double simpleSumOfSquare; // Used to compute right sum for non-finite inputs @Override public void accept(double value) { super.accept(value); double squarevalue = value * value; simpleSumOfSquare += squarevalue; sumOfSquareWithCompensation(squarevalue); } public DoubleStatistics combine(DoubleStatistics other) { super.combine(other); simpleSumOfSquare += other.simpleSumOfSquare; sumOfSquareWithCompensation(other.sumOfSquare); sumOfSquareWithCompensation(other.sumOfSquareCompensation); return this; } private void sumOfSquareWithCompensation(double value) { double tmp = value - sumOfSquareCompensation; double velvel = sumOfSquare + tmp; // Little wolf of rounding error sumOfSquareCompensation = (velvel - sumOfSquare) - tmp; sumOfSquare = velvel; } public double getSumOfSquare() { double tmp = sumOfSquare + sumOfSquareCompensation; if (Double.isNaN(tmp) && Double.isInfinite(simpleSumOfSquare)) { return simpleSumOfSquare; } return tmp; } public final double getStandardDeviation() { return getCount() > 0 ? Math.sqrt((getSumOfSquare() / getCount()) - Math.pow(getAverage(), 2)) : 0.0d; }}
然后,您可以将此类用于
Map<String, Double> standardDeviationMap = list.stream() .collect(Collectors.groupingBy( e -> e.getCar(), Collectors.mapping( e -> e.getHigh() - e.getLow(), Collector.of( DoubleStatistics::new, DoubleStatistics::accept, DoubleStatistics::combine, d -> d.getStandardDeviation() ) ) ));
这会将输入列表收集到一个映射中,该映射中的值对应于
high - low同一键的标准偏差。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)