src/share/classes/java/util/stream/Collectors.java

Print this page




 490     /**
 491      * Returns a {@code Collector} that produces the sum of a double-valued
 492      * function applied to the input elements.  If no elements are present,
 493      * the result is 0.
 494      *
 495      * <p>The sum returned can vary depending upon the order in which
 496      * values are recorded, due to accumulated rounding error in
 497      * addition of values of differing magnitudes. Values sorted by increasing
 498      * absolute magnitude tend to yield more accurate results.  If any recorded
 499      * value is a {@code NaN} or the sum is at any point a {@code NaN} then the
 500      * sum will be {@code NaN}.
 501      *
 502      * @param <T> the type of the input elements
 503      * @param mapper a function extracting the property to be summed
 504      * @return a {@code Collector} that produces the sum of a derived property
 505      */
 506     public static <T> Collector<T, ?, Double>
 507     summingDouble(ToDoubleFunction<? super T> mapper) {
 508         /*
 509          * In the arrays allocated for the collect operation, index 0
 510          * holds the high-order bits of the running sum and index 1
 511          * holds the low-order bits of the sum computed via
 512          * compensated summation.


 513          */
 514         return new CollectorImpl<>(
 515                 () -> new double[2],
 516                 (a, t) -> { sumWithCompensation(a, mapper.applyAsDouble(t)); },
 517                 (a, b) -> { sumWithCompensation(a, b[0]); return sumWithCompensation(a, b[1]); },
 518                 // Better error bounds to add both terms as the final sum
 519                 a -> a[0] + a[1],


 520                 CH_NOID);
 521     }
 522 
 523     /**
 524      * Incorporate a new double value using Kahan summation /
 525      * compensation summation.
 526      *
 527      * High-order bits of the sum are in intermediateSum[0], low-order
 528      * bits of the sum are in intermediateSum[1], any additional
 529      * elements are application-specific.
 530      *
 531      * @param intermediateSum the high-order and low-order words of the intermediate sum
 532      * @param value the name value to be included in the running sum
 533      */
 534     static double[] sumWithCompensation(double[] intermediateSum, double value) {
 535         double tmp = value - intermediateSum[1];
 536         double sum = intermediateSum[0];
 537         double velvel = sum + tmp; // Little wolf of rounding error
 538         intermediateSum[1] = (velvel - sum) - tmp;
 539         intermediateSum[0] = velvel;
 540         return intermediateSum;
 541     }
 542 














 543 
 544     /**
 545      * Returns a {@code Collector} that produces the arithmetic mean of an integer-valued
 546      * function applied to the input elements.  If no elements are present,
 547      * the result is 0.
 548      *
 549      * @param <T> the type of the input elements
 550      * @param mapper a function extracting the property to be summed
 551      * @return a {@code Collector} that produces the sum of a derived property
 552      */
 553     public static <T> Collector<T, ?, Double>
 554     averagingInt(ToIntFunction<? super T> mapper) {
 555         return new CollectorImpl<>(
 556                 () -> new long[2],
 557                 (a, t) -> { a[0] += mapper.applyAsInt(t); a[1]++; },
 558                 (a, b) -> { a[0] += b[0]; a[1] += b[1]; return a; },
 559                 a -> (a[1] == 0) ? 0.0d : (double) a[0] / a[1], CH_NOID);
 560     }
 561 
 562     /**


 591      *
 592      * @implNote The {@code double} format can represent all
 593      * consecutive integers in the range -2<sup>53</sup> to
 594      * 2<sup>53</sup>. If the pipeline has more than 2<sup>53</sup>
 595      * values, the divisor in the average computation will saturate at
 596      * 2<sup>53</sup>, leading to additional numerical errors.
 597      *
 598      * @param <T> the type of the input elements
 599      * @param mapper a function extracting the property to be summed
 600      * @return a {@code Collector} that produces the sum of a derived property
 601      */
 602     public static <T> Collector<T, ?, Double>
 603     averagingDouble(ToDoubleFunction<? super T> mapper) {
 604         /*
 605          * In the arrays allocated for the collect operation, index 0
 606          * holds the high-order bits of the running sum, index 1 holds
 607          * the low-order bits of the sum computed via compensated
 608          * summation, and index 2 holds the number of values seen.
 609          */
 610         return new CollectorImpl<>(
 611                 () -> new double[3],
 612                 (a, t) -> { sumWithCompensation(a, mapper.applyAsDouble(t)); a[2]++; },
 613                 (a, b) -> { sumWithCompensation(a, b[0]); sumWithCompensation(a, b[1]); a[2] += b[2]; return a; },
 614                 // Better error bounds to add both terms as the final sum to compute average
 615                 a -> (a[2] == 0) ? 0.0d : ((a[0] + a[1]) / a[2]),
 616                 CH_NOID);
 617     }
 618 
 619     /**
 620      * Returns a {@code Collector} which performs a reduction of its
 621      * input elements under a specified {@code BinaryOperator} using the
 622      * provided identity.
 623      *
 624      * @apiNote
 625      * The {@code reducing()} collectors are most useful when used in a
 626      * multi-level reduction, downstream of {@code groupingBy} or
 627      * {@code partitioningBy}.  To perform a simple reduction on a stream,
 628      * use {@link Stream#reduce(Object, BinaryOperator)}} instead.
 629      *
 630      * @param <T> element type for the input and output of the reduction
 631      * @param identity the identity value for the reduction (also, the value
 632      *                 that is returned when there are no input elements)
 633      * @param op a {@code BinaryOperator<T>} used to reduce the input elements
 634      * @return a {@code Collector} which implements the reduction operation
 635      *




 490     /**
 491      * Returns a {@code Collector} that produces the sum of a double-valued
 492      * function applied to the input elements.  If no elements are present,
 493      * the result is 0.
 494      *
 495      * <p>The sum returned can vary depending upon the order in which
 496      * values are recorded, due to accumulated rounding error in
 497      * addition of values of differing magnitudes. Values sorted by increasing
 498      * absolute magnitude tend to yield more accurate results.  If any recorded
 499      * value is a {@code NaN} or the sum is at any point a {@code NaN} then the
 500      * sum will be {@code NaN}.
 501      *
 502      * @param <T> the type of the input elements
 503      * @param mapper a function extracting the property to be summed
 504      * @return a {@code Collector} that produces the sum of a derived property
 505      */
 506     public static <T> Collector<T, ?, Double>
 507     summingDouble(ToDoubleFunction<? super T> mapper) {
 508         /*
 509          * In the arrays allocated for the collect operation, index 0
 510          * holds the high-order bits of the running sum, index 1 holds
 511          * the low-order bits of the sum computed via compensated
 512          * summation, and index 2 holds the simple sum used to compute
 513          * the proper result if the stream contains infinite values of
 514          * the same sign.
 515          */
 516         return new CollectorImpl<>(
 517                 () -> new double[3],
 518                 (a, t) -> { sumWithCompensation(a, mapper.applyAsDouble(t));
 519                             a[2] += mapper.applyAsDouble(t);},
 520                 (a, b) -> { sumWithCompensation(a, b[0]);
 521                             a[2] += b[2];
 522                             return sumWithCompensation(a, b[1]); },
 523                 a -> computeFinalSum(a),
 524                 CH_NOID);
 525     }
 526 
 527     /**
 528      * Incorporate a new double value using Kahan summation /
 529      * compensation summation.
 530      *
 531      * High-order bits of the sum are in intermediateSum[0], low-order
 532      * bits of the sum are in intermediateSum[1], any additional
 533      * elements are application-specific.
 534      *
 535      * @param intermediateSum the high-order and low-order words of the intermediate sum
 536      * @param value the name value to be included in the running sum
 537      */
 538     static double[] sumWithCompensation(double[] intermediateSum, double value) {
 539         double tmp = value - intermediateSum[1];
 540         double sum = intermediateSum[0];
 541         double velvel = sum + tmp; // Little wolf of rounding error
 542         intermediateSum[1] = (velvel - sum) - tmp;
 543         intermediateSum[0] = velvel;
 544         return intermediateSum;
 545     }
 546 
 547     /**
 548      * If the compensated sum is spuriously NaN from accumulating one
 549      * or more same-signed infinite values, return the
 550      * correctly-signed infinity stored in the simple sum.
 551      */
 552     static double computeFinalSum(double[] summands) {
 553         // Better error bounds to add both terms as the final sum
 554         double tmp = summands[0] + summands[1];
 555         double simpleSum = summands[summands.length - 1];
 556         if (Double.isNaN(tmp) && Double.isInfinite(simpleSum))
 557             return simpleSum;
 558         else
 559             return tmp;
 560     }
 561 
 562     /**
 563      * Returns a {@code Collector} that produces the arithmetic mean of an integer-valued
 564      * function applied to the input elements.  If no elements are present,
 565      * the result is 0.
 566      *
 567      * @param <T> the type of the input elements
 568      * @param mapper a function extracting the property to be summed
 569      * @return a {@code Collector} that produces the sum of a derived property
 570      */
 571     public static <T> Collector<T, ?, Double>
 572     averagingInt(ToIntFunction<? super T> mapper) {
 573         return new CollectorImpl<>(
 574                 () -> new long[2],
 575                 (a, t) -> { a[0] += mapper.applyAsInt(t); a[1]++; },
 576                 (a, b) -> { a[0] += b[0]; a[1] += b[1]; return a; },
 577                 a -> (a[1] == 0) ? 0.0d : (double) a[0] / a[1], CH_NOID);
 578     }
 579 
 580     /**


 609      *
 610      * @implNote The {@code double} format can represent all
 611      * consecutive integers in the range -2<sup>53</sup> to
 612      * 2<sup>53</sup>. If the pipeline has more than 2<sup>53</sup>
 613      * values, the divisor in the average computation will saturate at
 614      * 2<sup>53</sup>, leading to additional numerical errors.
 615      *
 616      * @param <T> the type of the input elements
 617      * @param mapper a function extracting the property to be summed
 618      * @return a {@code Collector} that produces the sum of a derived property
 619      */
 620     public static <T> Collector<T, ?, Double>
 621     averagingDouble(ToDoubleFunction<? super T> mapper) {
 622         /*
 623          * In the arrays allocated for the collect operation, index 0
 624          * holds the high-order bits of the running sum, index 1 holds
 625          * the low-order bits of the sum computed via compensated
 626          * summation, and index 2 holds the number of values seen.
 627          */
 628         return new CollectorImpl<>(
 629                 () -> new double[4],
 630                 (a, t) -> { sumWithCompensation(a, mapper.applyAsDouble(t)); a[2]++; a[3]+= mapper.applyAsDouble(t);},
 631                 a -> (a[2] == 0) ? 0.0d : (computeFinalSum(a) / a[2]),


 632                 CH_NOID);
 633     }
 634 
 635     /**
 636      * Returns a {@code Collector} which performs a reduction of its
 637      * input elements under a specified {@code BinaryOperator} using the
 638      * provided identity.
 639      *
 640      * @apiNote
 641      * The {@code reducing()} collectors are most useful when used in a
 642      * multi-level reduction, downstream of {@code groupingBy} or
 643      * {@code partitioningBy}.  To perform a simple reduction on a stream,
 644      * use {@link Stream#reduce(Object, BinaryOperator)}} instead.
 645      *
 646      * @param <T> element type for the input and output of the reduction
 647      * @param identity the identity value for the reduction (also, the value
 648      *                 that is returned when there are no input elements)
 649      * @param op a {@code BinaryOperator<T>} used to reduce the input elements
 650      * @return a {@code Collector} which implements the reduction operation
 651      *