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 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) | 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[2], 510 (a, t) -> { sumWithCompensation(a, mapper.applyAsDouble(t)); }, 511 (a, b) -> { sumWithCompensation(a, b[0]); return sumWithCompensation(a, b[1]); }, 512 a -> a[0], 513 CH_NOID); 514 } 515 516 /** 517 * Incorporate a new double value using Kahan summation / 518 * compensation summation. 519 * 520 * High-order bits of the sum are in intermediateSum[0], low-order 521 * bits of the sum are in intermediateSum[1], any additional 522 * elements are application-specific. 523 * 524 * @param intermediateSum the high-order and low-order words of the intermediate sum 525 * @param value the name value to be included in the running sum 526 */ 527 static double[] sumWithCompensation(double[] intermediateSum, double value) { 528 double tmp = value - intermediateSum[1]; 529 double sum = intermediateSum[0]; 530 double velvel = sum + tmp; // Little wolf of rounding error 531 intermediateSum[1] = (velvel - sum) - tmp; 532 intermediateSum[0] = velvel; 533 return intermediateSum; 534 } 535 536 537 /** 538 * Returns a {@code Collector} that produces the arithmetic mean of an integer-valued 539 * function applied to the input elements. If no elements are present, 540 * the result is 0. 541 * 542 * @param <T> the type of the input elements 543 * @param mapper a function extracting the property to be summed 544 * @return a {@code Collector} that produces the sum of a derived property 545 */ 546 public static <T> Collector<T, ?, Double> 547 averagingInt(ToIntFunction<? super T> mapper) { 548 return new CollectorImpl<>( 549 () -> new long[2], 550 (a, t) -> { a[0] += mapper.applyAsInt(t); a[1]++; }, 551 (a, b) -> { a[0] += b[0]; a[1] += b[1]; return a; }, 552 a -> (a[1] == 0) ? 0.0d : (double) a[0] / a[1], CH_NOID); 553 } 554 555 /** 556 * Returns a {@code Collector} that produces the arithmetic mean of a long-valued 572 573 /** 574 * Returns a {@code Collector} that produces the arithmetic mean of a double-valued 575 * function applied to the input elements. If no elements are present, 576 * the result is 0. 577 * 578 * <p>The average returned can vary depending upon the order in which 579 * values are recorded, due to accumulated rounding error in 580 * addition of values of differing magnitudes. Values sorted by increasing 581 * absolute magnitude tend to yield more accurate results. If any recorded 582 * value is a {@code NaN} or the sum is at any point a {@code NaN} then the 583 * average will be {@code NaN}. 584 * 585 * @param <T> the type of the input elements 586 * @param mapper a function extracting the property to be summed 587 * @return a {@code Collector} that produces the sum of a derived property 588 */ 589 public static <T> Collector<T, ?, Double> 590 averagingDouble(ToDoubleFunction<? super T> mapper) { 591 return new CollectorImpl<>( 592 () -> new double[3], 593 (a, t) -> { sumWithCompensation(a, mapper.applyAsDouble(t)); a[2]++; }, 594 (a, b) -> { sumWithCompensation(a, b[0]); sumWithCompensation(a, b[1]); a[2] += b[2]; return a; }, 595 a -> (a[2] == 0) ? 0.0d : (a[0] / a[2]), 596 CH_NOID); 597 } 598 599 /** 600 * Returns a {@code Collector} which performs a reduction of its 601 * input elements under a specified {@code BinaryOperator} using the 602 * provided identity. 603 * 604 * @apiNote 605 * The {@code reducing()} collectors are most useful when used in a 606 * multi-level reduction, downstream of {@code groupingBy} or 607 * {@code partitioningBy}. To perform a simple reduction on a stream, 608 * use {@link Stream#reduce(Object, BinaryOperator)}} instead. 609 * 610 * @param <T> element type for the input and output of the reduction 611 * @param identity the identity value for the reduction (also, the value 612 * that is returned when there are no input elements) 613 * @param op a {@code BinaryOperator<T>} used to reduce the input elements 614 * @return a {@code Collector} which implements the reduction operation 615 * 616 * @see #reducing(BinaryOperator) |