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

Collections.binarySearch() throws ClassCastException with Comparator.comparing()

    XMLWordPrintable

Details

    Description

      ADDITIONAL SYSTEM INFORMATION :
      Tested on Java 11.0.19 and 17.0.7

      A DESCRIPTION OF THE PROBLEM :
      Collections.binarySearch() throws exception when:
      - searching a List with no generic type
      - element being searched for is a different type than the elements in the List

      The Javadoc for binarySearch() says it will throw a ClassCastException " if the list contains elements that are not mutually comparable using the specified comparator, or the search key is not mutually comparable with the elements of the list using this comparator." I believe the elements are mutually comparable each other with the provided Comparator.



      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      Execute this code:



      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      "1" to be printed to System.out()
      ACTUAL -
      Exception occurred:

      Exception in thread "main" java.lang.ClassCastException: class java.lang.Integer cannot be cast to class java.lang.String (java.lang.Integer and java.lang.String are in module java.base of loader 'bootstrap')
      at java.base/java.util.Comparator.lambda$comparing$77a9974f$1(Comparator.java:469)
      at java.base/java.util.Collections.indexedBinarySearch(Collections.java:336)
      at java.base/java.util.Collections.binarySearch(Collections.java:324)
      at Scratch.main(scratch_3.java:8)

      ---------- BEGIN SOURCE ----------
      import java.util.Collections;
      import java.util.Comparator;
      import java.util.List;

      class Scratch {
          public static void main(String[] args) {
              List list = List.of(1, 2, 3);
              int index = Collections.binarySearch(list, "2", Comparator.comparing(Object::toString));
              System.out.println(index);
          }
      }
      ---------- END SOURCE ----------

      CUSTOMER SUBMITTED WORKAROUND :
      Typecast any of the three parameters on the call to binarySearch(), like this:

      int index = Collections.binarySearch((List<?>)list, "2", Comparator.comparing(Object::toString));

      - or -

      int index = Collections.binarySearch(list, (Object)"2", Comparator.comparing(Object::toString));

      - or -

      int index = Collections.binarySearch(list, "2", (Comparator)Comparator.comparing(Object::toString));

      FREQUENCY : always


      Attachments

        Activity

          People

            smarks Stuart Marks
            webbuggrp Webbug Group
            Votes:
            0 Vote for this issue
            Watchers:
            3 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved: