• Post Reply Bookmark Topic Watch Topic
  • New Topic

ClassCastException  RSS feed

 
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: 56610
172
  • 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
    Sheriff
    Posts: 23295
    125
    C++ Chrome Eclipse IDE Firefox Browser Java jQuery Linux VI Editor 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: 56610
    172
    • 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: 56610
    172
    • 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 ]
     
    • Post Reply Bookmark Topic Watch Topic
    • New Topic
    Boost this thread!