It's not a secret anymore!
The moose likes Beginning Java and the fly likes ClassCastException Big Moose Saloon
  Search | Java FAQ | Recent Topics
Register / Login
JavaRanch » Java Forums » Java » Beginning Java
Reply Bookmark "ClassCastException" Watch "ClassCastException" New topic
Author

ClassCastException

Graeme Byers
Ranch Hand

Joined: Apr 16, 2004
Posts: 127
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.

Campbell Ritchie
Sheriff

Joined: Oct 13, 2005
Posts: 32712
    
    4
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.
    Henry Wong
    author
    Sheriff

    Joined: Sep 28, 2004
    Posts: 16695
        
      19

    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


    Books: Java Threads, 3rd Edition, Jini in a Nutshell, and Java Gems (contributor)
    Graeme Byers
    Ranch Hand

    Joined: Apr 16, 2004
    Posts: 127
    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
    Sheriff

    Joined: Oct 13, 2005
    Posts: 32712
        
        4
    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
    Sheriff

    Joined: Oct 13, 2005
    Posts: 32712
        
        4
    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 ]
     
    I agree. Here's the link: http://zeroturnaround.com/jrebel - it saves me about five hours per week
     
    subject: ClassCastException
     
    Similar Threads
    Sorting data list
    Sorting String List
    Sorting by 3 variables dynamically in arrayList
    Need Help:How to port HashMap<String-ColmnName, ArayList-ClumnData> to Datatable for multiple colmns
    sorting table columns