src/share/classes/java/util/stream/Collectors.java
Print this page
*** 505,524 ****
*/
public static <T> Collector<T, ?, Double>
summingDouble(ToDoubleFunction<? super T> mapper) {
/*
* In the arrays allocated for the collect operation, index 0
! * holds the high-order bits of the running sum and index 1
! * holds the low-order bits of the sum computed via
! * compensated summation.
*/
return new CollectorImpl<>(
! () -> new double[2],
! (a, t) -> { sumWithCompensation(a, mapper.applyAsDouble(t)); },
! (a, b) -> { sumWithCompensation(a, b[0]); return sumWithCompensation(a, b[1]); },
! // Better error bounds to add both terms as the final sum
! a -> a[0] + a[1],
CH_NOID);
}
/**
* Incorporate a new double value using Kahan summation /
--- 505,528 ----
*/
public static <T> Collector<T, ?, Double>
summingDouble(ToDoubleFunction<? super T> mapper) {
/*
* In the arrays allocated for the collect operation, index 0
! * holds the high-order bits of the running sum, index 1 holds
! * the low-order bits of the sum computed via compensated
! * summation, and index 2 holds the simple sum used to compute
! * the proper result if the stream contains infinite values of
! * the same sign.
*/
return new CollectorImpl<>(
! () -> new double[3],
! (a, t) -> { sumWithCompensation(a, mapper.applyAsDouble(t));
! a[2] += mapper.applyAsDouble(t);},
! (a, b) -> { sumWithCompensation(a, b[0]);
! a[2] += b[2];
! return sumWithCompensation(a, b[1]); },
! a -> computeFinalSum(a),
CH_NOID);
}
/**
* Incorporate a new double value using Kahan summation /
*** 538,547 ****
--- 542,565 ----
intermediateSum[1] = (velvel - sum) - tmp;
intermediateSum[0] = velvel;
return intermediateSum;
}
+ /**
+ * If the compensated sum is spuriously NaN from accumulating one
+ * or more same-signed infinite values, return the
+ * correctly-signed infinity stored in the simple sum.
+ */
+ static double computeFinalSum(double[] summands) {
+ // Better error bounds to add both terms as the final sum
+ double tmp = summands[0] + summands[1];
+ double simpleSum = summands[summands.length - 1];
+ if (Double.isNaN(tmp) && Double.isInfinite(simpleSum))
+ return simpleSum;
+ else
+ return tmp;
+ }
/**
* Returns a {@code Collector} that produces the arithmetic mean of an integer-valued
* function applied to the input elements. If no elements are present,
* the result is 0.
*** 606,620 ****
* holds the high-order bits of the running sum, index 1 holds
* the low-order bits of the sum computed via compensated
* summation, and index 2 holds the number of values seen.
*/
return new CollectorImpl<>(
! () -> new double[3],
! (a, t) -> { sumWithCompensation(a, mapper.applyAsDouble(t)); a[2]++; },
! (a, b) -> { sumWithCompensation(a, b[0]); sumWithCompensation(a, b[1]); a[2] += b[2]; return a; },
! // Better error bounds to add both terms as the final sum to compute average
! a -> (a[2] == 0) ? 0.0d : ((a[0] + a[1]) / a[2]),
CH_NOID);
}
/**
* Returns a {@code Collector} which performs a reduction of its
--- 624,637 ----
* holds the high-order bits of the running sum, index 1 holds
* the low-order bits of the sum computed via compensated
* summation, and index 2 holds the number of values seen.
*/
return new CollectorImpl<>(
! () -> new double[4],
! (a, t) -> { sumWithCompensation(a, mapper.applyAsDouble(t)); a[2]++; a[3]+= mapper.applyAsDouble(t);},
! (a, b) -> { sumWithCompensation(a, b[0]); sumWithCompensation(a, b[1]); a[2] += b[2]; a[3] += b[3]; return a; },
! a -> (a[2] == 0) ? 0.0d : (computeFinalSum(a) / a[2]),
CH_NOID);
}
/**
* Returns a {@code Collector} which performs a reduction of its