488 } 489 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 return new CollectorImpl<>( 509 () -> new double[1], 510 (a, t) -> { a[0] += mapper.applyAsDouble(t); }, 511 (a, b) -> { a[0] += b[0]; return a; }, 512 a -> a[0], CH_NOID); 513 } 514 515 /** 516 * Returns a {@code Collector} that produces the arithmetic mean of an integer-valued 517 * function applied to the input elements. If no elements are present, 518 * the result is 0. 519 * 520 * @param <T> the type of the input elements 521 * @param mapper a function extracting the property to be summed 522 * @return a {@code Collector} that produces the sum of a derived property 523 */ 524 public static <T> Collector<T, ?, Double> 525 averagingInt(ToIntFunction<? super T> mapper) { 526 return new CollectorImpl<>( 527 () -> new long[2], 528 (a, t) -> { a[0] += mapper.applyAsInt(t); a[1]++; }, 529 (a, b) -> { a[0] += b[0]; a[1] += b[1]; return a; }, 530 a -> (a[1] == 0) ? 0.0d : (double) a[0] / a[1], CH_NOID); 531 } 532 533 /** 534 * Returns a {@code Collector} that produces the arithmetic mean of a long-valued 535 * function applied to the input elements. If no elements are present, 543 averagingLong(ToLongFunction<? super T> mapper) { 544 return new CollectorImpl<>( 545 () -> new long[2], 546 (a, t) -> { a[0] += mapper.applyAsLong(t); a[1]++; }, 547 (a, b) -> { a[0] += b[0]; a[1] += b[1]; return a; }, 548 a -> (a[1] == 0) ? 0.0d : (double) a[0] / a[1], CH_NOID); 549 } 550 551 /** 552 * Returns a {@code Collector} that produces the arithmetic mean of a double-valued 553 * function applied to the input elements. If no elements are present, 554 * the result is 0. 555 * 556 * <p>The average returned can vary depending upon the order in which 557 * values are recorded, due to accumulated rounding error in 558 * addition of values of differing magnitudes. Values sorted by increasing 559 * absolute magnitude tend to yield more accurate results. If any recorded 560 * value is a {@code NaN} or the sum is at any point a {@code NaN} then the 561 * average will be {@code NaN}. 562 * 563 * @param <T> the type of the input elements 564 * @param mapper a function extracting the property to be summed 565 * @return a {@code Collector} that produces the sum of a derived property 566 */ 567 public static <T> Collector<T, ?, Double> 568 averagingDouble(ToDoubleFunction<? super T> mapper) { 569 return new CollectorImpl<>( 570 () -> new double[2], 571 (a, t) -> { a[0] += mapper.applyAsDouble(t); a[1]++; }, 572 (a, b) -> { a[0] += b[0]; a[1] += b[1]; return a; }, 573 a -> (a[1] == 0) ? 0.0d : a[0] / a[1], CH_NOID); 574 } 575 576 /** 577 * Returns a {@code Collector} which performs a reduction of its 578 * input elements under a specified {@code BinaryOperator} using the 579 * provided identity. 580 * 581 * @apiNote 582 * The {@code reducing()} collectors are most useful when used in a 583 * multi-level reduction, downstream of {@code groupingBy} or 584 * {@code partitioningBy}. To perform a simple reduction on a stream, 585 * use {@link Stream#reduce(Object, BinaryOperator)}} instead. 586 * 587 * @param <T> element type for the input and output of the reduction 588 * @param identity the identity value for the reduction (also, the value 589 * that is returned when there are no input elements) 590 * @param op a {@code BinaryOperator<T>} used to reduce the input elements 591 * @return a {@code Collector} which implements the reduction operation 592 * 593 * @see #reducing(BinaryOperator) | 488 } 489 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 /** 563 * Returns a {@code Collector} that produces the arithmetic mean of a long-valued 564 * function applied to the input elements. If no elements are present, 572 averagingLong(ToLongFunction<? super T> mapper) { 573 return new CollectorImpl<>( 574 () -> new long[2], 575 (a, t) -> { a[0] += mapper.applyAsLong(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 /** 581 * Returns a {@code Collector} that produces the arithmetic mean of a double-valued 582 * function applied to the input elements. If no elements are present, 583 * the result is 0. 584 * 585 * <p>The average returned can vary depending upon the order in which 586 * values are recorded, due to accumulated rounding error in 587 * addition of values of differing magnitudes. Values sorted by increasing 588 * absolute magnitude tend to yield more accurate results. If any recorded 589 * value is a {@code NaN} or the sum is at any point a {@code NaN} then the 590 * average will be {@code NaN}. 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 * 636 * @see #reducing(BinaryOperator) |