Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8151123

Collectors.summingDouble/averagingDouble unnecessarily call mapper twice

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Fixed
    • Icon: P4 P4
    • 9
    • 9
    • core-libs
    • None

      Current implementation of Collectors.averagingDouble calls the supplied mapper twice per accumulated element:

      (a, t) -> { sumWithCompensation(a, mapper.applyAsDouble(t)); a[2]++; a[3]+= mapper.applyAsDouble(t);},

      Similarly Collectors.summingDouble:

      (a, t) -> { sumWithCompensation(a, mapper.applyAsDouble(t));
                 a[2] += mapper.applyAsDouble(t);},

      As mapper is a user-supplied function, it's not guaranteed to be a simple getter. Actually it could be computationally intensive. For example, the following code could be used to find average distance of the set of points from the given central point:

        static class Point {
          int x, y;

          Point(int x, int y) { this.x = x;this.y = y; }

          double distance(Point p) {
            return Math.hypot(x - p.x, y - p.y);
          }
        }

        public double averageDistance(Point center, List<Point> list) {
          return list.stream().collect(Collectors.averagingDouble(center::distance));
        }

      Calling the mapper twice is absolutely unnecessary and may affect the performance when mapper is non-trivial.

            tvaleev Tagir Valeev
            tvaleev Tagir Valeev
            Votes:
            0 Vote for this issue
            Watchers:
            3 Start watching this issue

              Created:
              Updated:
              Resolved: