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

Collectors.summingDouble/averagingDouble unnecessarily call mapper twice

    XMLWordPrintable

    Details

    • Type: Bug
    • Status: Resolved
    • Priority: P4
    • Resolution: Fixed
    • Affects Version/s: 9
    • Fix Version/s: 9
    • Component/s: core-libs
    • Labels:
      None

      Description

      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.

        Attachments

          Activity

            People

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

              Dates

              Created:
              Updated:
              Resolved: