Win a copy of TensorFlow 2.0 in Action this week in the Artificial Intelligence and Machine Learning forum!
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Liutauras Vilda
  • Paul Clapham
  • Bear Bibeault
  • Jeanne Boyarsky
Sheriffs:
  • Ron McLeod
  • Tim Cooke
  • Devaka Cooray
Saloon Keepers:
  • Tim Moores
  • Tim Holloway
  • Jj Roberts
  • Stephan van Hulst
  • Carey Brown
Bartenders:
  • salvin francis
  • Scott Selikoff
  • fred rosenberger

ClassCastException

 
Ranch Hand
Posts: 127
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
The following code attempts to implement a Comparator, but I cannot see why it is throwing a ClassCastException at (third line from bottom) :
String empName1 = emp1.getEmpName () ; java.lang.Integer
Thank you.

 
Marshal
Posts: 70684
288
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Are you still using Java1.4 or earlier? If not, please go find out about the complicated subject of Generics. That will produce compiler errors that you are using the wrong types, rather than runtime Exceptions. Your code, unchanged, can be compiled like this, in which case it produces about 8 warnings:

javac -Xlint CompClass.java

There are 3 classes which should be parameterised:
  • empMap should be declared as Map<Integer, String> and instantiated as new TreeMap<Integer, String>.
  • empNameMap which you are using as Map<Integer, String> and should be instantiated as TreeMap<Integer, String>.
  • EmpNameComparator which should be declared as implementing Comparable<EmpClass> and the compare method would take EmpClass as type for both its parameter.
  • You might be able to declare both Maps as SortedMap or NavigableMap with the same <> instead.

    You are passing Integer, String to both Maps, but if you look in the API for TreeMap you find that the Comparator operates on the left-hand parameter in put, the Key. So the Comparator is actually operating on Integers not EmpClasses. In fact you don't appear to use any EmpClass objects in your main method at all. The Comparator is actually redundant; you are using the same procedure as in the first Map. What happens there is that the Map can use any Object which implements the Comparable<T> interface as a Key; Integer implements Comparable<Integer> so it will work nicely. It is only when it finds a Comparator requiring EmpClasses and you present it with a second Integer that it has problems. It only has problems when the second pair is "put" in the Map because it never tries to compare the first with anything!

    By the way: You can shorten your equals method toYou ought also to override the hashCode() method to take empNo into account. It seems strange that you are not using empName in the equals() method. Using instanceof in an equals method can produce wrong results if presented with a subclass of EmpClass.
     
    author
    Posts: 23887
    142
    jQuery Eclipse IDE Firefox Browser VI Editor C++ Chrome Java Linux Windows
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator

    The following code attempts to implement a Comparator, but I cannot see why it is throwing a ClassCastException at (third line from bottom) :



    It is actually being thrown earlier -- about two lines earlier... here...



    If you look at how you are using the comparator...



    You will see that you are using Integer objects as keys. So, the objects being passed to the comparator are Integer objects. So, when you cast the Integer object to an EmpClass object, the class cast exception is thrown.

    Henry
     
    Graeme Byers
    Ranch Hand
    Posts: 127
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Yes. I deliberately used 1.4 compiling with -source (code maintenance).
    I don't like short circuits - terse = obfuscated. I have even worked in (non Java) sites which would not allow the returns where I have put them (disguised goto) and insist on a single return at end of method.
    My basic mistake was choosing the wrong Collection - using a Map rather than putting EmpClass objects into a List.

    Is the code (like my own) that now one would write using generics in the SCJP Java 5 exam ?
     
    Campbell Ritchie
    Marshal
    Posts: 70684
    288
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    I don't care about the exam, but this is how you would do it in real life; the same answer will do nicely for the exam.

    Originally posted by myself:
    There are 3 classes which should be parameterised:

  • empMap should be declared as Map<Integer, String> and instantiated as new TreeMap<Integer, String>.
  • empNameMap which you are using as Map<Integer, String> and should be instantiated as TreeMap<Integer, String>.
  • EmpNameComparator which should be declared as implementing Comparable<EmpClass> and the compare method would take EmpClass as type for both its parameter.
  • You might be able to declare both Maps as SortedMap or NavigableMap with the same <> instead.

    Remember this parameterised version will only work in Java5 or Java6 and I haven't changed the Comparator.
     
    Campbell Ritchie
    Marshal
    Posts: 70684
    288
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    If you replace the 2nd Map with List it would be List<EmpClass> someList = new XYZList<EmpClass>(); and you might not need a Comparator since EmpClass already implements Comparable. This should of course read Comparable<EmpClass> and the parameter to the compareTo method should read EmpClass other.

    For the type of List, have a look at the Java Tutorials and find List implementations; the most popular type is ArrayList.
    If you use the appropriate class you may get the collection pre-sorted. Using a Set<EmpClass> and a TreeSet implementation might sort out your problem. More details in the same link, only look for set implementations. Remember if you use a Set to declare it as Set<EmpClass>.
    [ September 21, 2008: Message edited by: Campbell Ritchie ]
     
    A sonic boom would certainly ruin a giant souffle. But this tiny ad would protect it:
    Building a Better World in your Backyard by Paul Wheaton and Shawn Klassen-Koop
    https://coderanch.com/wiki/718759/books/Building-World-Backyard-Paul-Wheaton
    reply
      Bookmark Topic Watch Topic
    • New Topic