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

Collectors.reducing() docs do not match implementation

XMLWordPrintable

      FULL PRODUCT VERSION :
      java version "1.8.0_161"
      Java(TM) SE Runtime Environment (build 1.8.0_161-b12)
      Java HotSpot(TM) 64-Bit Server VM (build 25.161-b12, mixed mode)

      A DESCRIPTION OF THE PROBLEM :
      The doc for Collectors.reducing() (available at https://docs.oracle.com/javase/8/docs/api/java/util/stream/Collectors.html) contain following example:


           Comparator<Person> byHeight = Comparator.comparing(Person::getHeight);
           Map<City, Person> tallestByCity
               = people.stream().collect(groupingBy(Person::getCity, reducing(BinaryOperator.maxBy(byHeight))));


      This sample is incorrect and does not compile.

      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      Try to compile the code sample below which includes the example given in Java docs.

      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      Sample program compiles (and does nothing.)
      ACTUAL -
      Compilation error:

      Main.java:25: error: incompatible types: inference variable R has incompatible bounds
                      = people.stream().collect(groupingBy(Person::getCity, reducing(BinaryOperator.maxBy(byHeight))));
                                               ^
          equality constraints: Map<Main.City,Optional<Main.Person>>
          upper bounds: Map<Main.City,Main.Person>,Object
        where R,A,T are type-variables:
          R extends Object declared in method <R,A>collect(Collector<? super T,A,R>)
          A extends Object declared in method <R,A>collect(Collector<? super T,A,R>)
          T extends Object declared in interface Stream
      1 error


      REPRODUCIBILITY :
      This bug can be reproduced always.

      ---------- BEGIN SOURCE ----------
      import java.util.Collections;
      import java.util.Comparator;
      import java.util.List;
      import java.util.Map;
      import java.util.function.BinaryOperator;

      import static java.util.stream.Collectors.groupingBy;
      import static java.util.stream.Collectors.reducing;

      public class Main {
          public class City {
              public String Name;
          }

          public class Person {
              public double getHeight() { return 0; }
              public City getCity() { return null; }
          }

          public static void main(String[] args) {
              List<Person> people = Collections.emptyList();

              Comparator<Person> byHeight = Comparator.comparing(Person::getHeight);
              Map<City, Person> tallestByCity
                      = people.stream().collect(groupingBy(Person::getCity, reducing(BinaryOperator.maxBy(byHeight))));
          }
      }
      ---------- END SOURCE ----------

      CUSTOMER SUBMITTED WORKAROUND :
      Replace Map<City, Person> with Map<City, Optional<Person>>

            psonal Pallavi Sonal (Inactive)
            webbuggrp Webbug Group
            Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

              Created:
              Updated:
              Resolved: