Collectors.summingDouble() 是用于计算双精度浮点数总和的收集器,返回 Double 类型的求和结果。
基本用法
java
// 1. 基本用法 - 计算Double列表的总和
List<Double> prices = Arrays.asList(19.99, 29.99, 39.99, 49.99);
Double total = prices.stream()
.collect(Collectors.summingDouble(n -> n));
System.out.println("Total price: " + total); // 139.96
System.out.printf("Formatted: %.2f%n", total); // 139.96
// 2. 方法引用简化写法
Double total2 = prices.stream()
.collect(Collectors.summingDouble(Double::doubleValue));
// 3. 从DoubleStream直接使用
double doubleStreamSum = DoubleStream.of(19.99, 29.99, 39.99, 49.99)
.sum();
System.out.println("DoubleStream sum: " + doubleStreamSum); // 139.96核心特性
1. 浮点数精度处理
java
public class PrecisionHandling {
public static void main(String[] args) {
// 浮点数相加可能有精度问题
List<Double> values = Arrays.asList(0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1);
Double sum = values.stream()
.collect(Collectors.summingDouble(n -> n));
System.out.println("Sum of ten 0.1s: " + sum); // 理论上应该是1.0
System.out.println("Is exactly 1.0? " + (sum == 1.0)); // 可能为false
System.out.printf("Formatted: %.15f%n", sum); // 查看实际值
// 对于精确计算,使用BigDecimal
BigDecimal exactSum = values.stream()
.map(BigDecimal::valueOf)
.reduce(BigDecimal.ZERO, BigDecimal::add);
System.out.println("Exact sum (BigDecimal): " + exactSum); // 1.0
// Kahan求和算法减少误差
double[] numbers = {0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1};
double kahanSum = kahanSum(numbers);
System.out.println("Kahan sum: " + kahanSum); // 更接近1.0
}
// Kahan求和算法实现
private static double kahanSum(double[] numbers) {
double sum = 0.0;
double c = 0.0; // 补偿误差
for (double num : numbers) {
double y = num - c;
double t = sum + y;
c = (t - sum) - y;
sum = t;
}
return sum;
}
}2. 特殊值处理
java
public class SpecialValueHandling {
public static void main(String[] args) {
// 处理特殊浮点数值
List<Double> specialValues = Arrays.asList(
1.5,
Double.POSITIVE_INFINITY,
2.5,
Double.NaN,
3.5,
Double.NEGATIVE_INFINITY
);
// ❌ 包含特殊值会导致异常或错误结果
try {
Double badSum = specialValues.stream()
.collect(Collectors.summingDouble(n -> n));
System.out.println("Bad sum: " + badSum);
} catch (Exception e) {
System.out.println("Exception: " + e.getMessage());
}
// ✅ 过滤特殊值
Double filteredSum = specialValues.stream()
.filter(n -> Double.isFinite(n)) // 过滤无穷大和NaN
.collect(Collectors.summingDouble(n -> n));
System.out.println("Filtered sum: " + filteredSum); // 7.5 (1.5+2.5+3.5)
// ✅ 处理无穷大
Double sumWithInfinity = specialValues.stream()
.map(n -> {
if (Double.isInfinite(n)) {
return n == Double.POSITIVE_INFINITY ? 1e10 : -1e10;
} else if (Double.isNaN(n)) {
return 0.0;
}
return n;
})
.collect(Collectors.summingDouble(n -> n));
System.out.println("Processed sum: " + sumWithInfinity);
// 检查结果是否有效
Double result = filteredSum;
if (Double.isNaN(result)) {
System.out.println("Result is NaN!");
} else if (Double.isInfinite(result)) {
System.out.println("Result is infinite!");
} else {
System.out.println("Result is finite: " + result);
}
}
}
朔风