This week's book giveaways are in the Cloud and AI/ML forums.
We're giving away four copies each of Cloud Native Patterns and Natural Language Processing and have the authors on-line!
See this thread and this one for details.
Win a copy of Cloud Native PatternsE this week in the Cloud forum
or Natural Language Processing in the AI/ML 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
  • Devaka Cooray
  • Liutauras Vilda
  • Jeanne Boyarsky
  • Bear Bibeault
Sheriffs:
  • Paul Clapham
  • Knute Snortum
  • Rob Spoor
Saloon Keepers:
  • Tim Moores
  • Ron McLeod
  • Piet Souris
  • Stephan van Hulst
  • Carey Brown
Bartenders:
  • Tim Holloway
  • Frits Walraven
  • Ganesh Patekar

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: 65019
246
  • 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: 23834
    140
    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: 65019
    246
    • 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: 65019
    246
    • 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 ]
     
    Consider Paul's rocket mass heater.
    • Post Reply Bookmark Topic Watch Topic
    • New Topic
    Boost this thread!