• Post Reply Bookmark Topic Watch Topic
  • New Topic

ClasscastException in Collections.sort()  RSS feed

 
Yash Sharma
Ranch Hand
Posts: 61
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I have a property file with values such as follows:
Question (1)

I have to sort the list on the values, which are all strings (but may contain numbers too). When I use the following code it works fine when I sort of keySet() of Properties but throws a ClassCastException when I sort on entrySet(). Starnge because all the values in my list (atleast currently) are Strings.

What could be wrong?
Question (2)
If I have unicode values in this property files in various languages (however only one language per file) in "/u" format will the sorting still be done ok?
Thanks for your time.
[ December 22, 2003: Message edited by: Yash Sharma ]
 
Jim Yingst
Wanderer
Sheriff
Posts: 18671
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
If you look at the API for entrySet(), you will see you get a Set of Map.Entry objects - not Strings. Map.Entry doesn't implement Comparable, which is probably why you get a cast exception here when you try to sort. I'd recommend creating a Comparator which compares two Map.Entry objects by comparing the values (which are Strings in this case).

BTW, it's a bit confusing to have list of entries called "keyList"; I changed the name in my code to entryList.
[ December 22, 2003: Message edited by: Jim Yingst ]
 
Jim Yingst
Wanderer
Sheriff
Posts: 18671
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Question (2)
If I have unicode values in this property files in various languages (however only one language per file) in "/u" format will the sorting still be done ok?

Well, the /uXXXX will be translated into the char it represents as soon as the Properties is loaded, so that's not an issue. However if you're using other languages than English, sorting can be more complex. String's compareTo() method implements a "natural order" which simply sorts according to Unicode value of each letter. However the Unicode order isn't always what makes sense in the language you're dealing with. (Particularly for the asian languages in the CJK grouping, where some of their characters are in one of the CJK common areas, and others are in a block specifically for that language. In fact even in English, you may not like the natural sort. E.g. if you want to ignore case and have "Adam" come between "ace" and "and" - String doesn't do that by default.
I believe you need to use a Collator here - an object which knows how to sort strings according to a particular set of rules. You can create a Collaor and have your Comparator call the Collator to compare the two values, rather than the compareTo() used above. See the Java Tutorial on comparing strings with internationalization for more info.
 
Yash Sharma
Ranch Hand
Posts: 61
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thanks a lot Jim.
Originally posted by Jim Yingst:
it's a bit confusing to have list of entries called "keyList"

Oops that's a typo. As I was playing with the code snippet forgot to change the name.
Also perhaps we need to cast the entry objects:

Sadly, I am still getting the same error
[ December 22, 2003: Message edited by: Yash Sharma ]
 
Jim Yingst
Wanderer
Sheriff
Posts: 18671
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Also perhaps we need to cast the entry objects:
Oops, yes, I forgot that.
Sadly, I am still getting the same error
From what line, exactly? The stack trace should have a line number which tells you exactly which line is the problem.
If there are several things going on in that line and you're not sure which is the problem, split the line into several separate lines to see which is really the cause:

If there's a ClassCastException, it either comes from one of the two lines above, or it comes from the sort() method which expects that the elements will implement Comparable. So look at the stack trace and figure out which it is; this will be very helpful to know.
 
Yash Sharma
Ranch Hand
Posts: 61
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thanks again! Let me reproduce the method I have made. I am getting the error (java.lang.ClassCastException: java.util.Hashtable$Entry) at the line sb.append((String) entryList.get(i));

The comparator class is as below:

Looking forward to your reply.
[ December 24, 2003: Message edited by: Yash Sharma ]
 
John Smith
Ranch Hand
Posts: 2937
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I am getting the error (java.lang.ClassCastException: java.util.Hashtable$Entry) at the line sb.append((String) entryList.get(i));
You still have the same problem that Jim pointed out to you. Your entryList contains a list of Map.Entry instances. In your code, you attempt to retreive these instances and cast them to String. Since the instances of Map.Entry are not Strings, you get the corresponding ClassCastException. The fix is simple, and Jim has already provided it, -- call the getValue() method on your Map.Entry instance and then cast it to String.
 
Yash Sharma
Ranch Hand
Posts: 61
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi,
I rectified the code exactly as per suggestions, shown below:

However I am getting the same error at the indicated line:

I am just helpless and fail to understand why the error occurs. Will the new year bring me any solution
 
Jim Yingst
Wanderer
Sheriff
Posts: 18671
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Try replacing

with
 
Yash Sharma
Ranch Hand
Posts: 61
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thanks a lot Jim! That was a lesson learnt iteratively The entryList.get() method was returning a Hashtable Entry object which could not be cast into a String. Here is what will set the code right:

However a new problem has cropped up which I hope I woul be able to tackle. The entryList.get(i).getString() returns a string of the form key=value as shown below in a sample result. So perhaps I would need some String manipulations to perform.

I wish Ranchers a very happy new year 2004
[ December 31, 2003: Message edited by: Yash Sharma ]
 
Yash Sharma
Ranch Hand
Posts: 61
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
And the solution to the above stated problem is perhaps doing the following:

What I am worried about is performance here now. The client applications will ask this code to fetch say first 10 records, then next 10 and so on. They might also ask for all property values that start with, say A. If I have so many manipulations running inside a loop I am sure performance would be detrimental.
[ December 31, 2003: Message edited by: Yash Sharma ]
 
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!