Why am getting a ClassCastException at (Person p2 = (Person) o2;) in overridden compare method . :(
Actually Instead of Person Object the values in compare overridden method is coming as "Jim" and "Jack" (Key values). So the Cast Cast Exception . But Why is it coming with keys not values i,e the Person object , Why is it only applied for keys . Are there any other way to sort it based on values .
Please correct me if am wrong
1) We can Pass the comparator object in the TreeMap which will sort it accordingly.?
2) Always the Sorting is performed over Keys . ?
3) How can we sort a Map over its values without using anymore collection object (Is it possible) and why is not supported by default ?
public class HashTableExamples {
/**
* @param args
*/
public static void main(String[] args) {
SortedMap persorSorted = new TreeMap(new Comparator() {
@Override
public int compare(Object o1, Object o2) {
Person p2 = (Person) o2;
return 2;
}
});
Person p = new Person(10);
Person p1 = new Person(20);
persorSorted.put("Jim", p);
persorSorted.put("Jack", p1);
Iterator sortedit = persorSorted.entrySet().iterator();
while (sortedit.hasNext()) {
Map.Entry pairs = (Map.Entry) sortedit.next();
Person pw = (Person) pairs.getValue();
System.out.println("From SortedMap : " + pw.getAge());
}
}
public static class Person {
Person(int agevalue) {
this.age = agevalue;
}
private int age;
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
Yes, TreeMap always sorts on keys.
As to why it's not "supported by default" -- it's because there doesn't exist a data structure in general that supports it efficiently. It's not supported efficiently in any programming language, because the point of a Map is to be able to look things up by their key, and sorting by values means you can't organize the data in a way that makes it efficient to look things up by keys.
If you must sort a Map's entries by value, you can use something like this:
List<Map.Entry<Foo, Bar>> entryList =
new ArrayList<Map.Entry<Foo, Bar>>(map.entrySet());
Collections.sort(entryList, new Comparator<Map.Entry<Foo, Bar>>() {
public int compare(Map.Entry<Foo, Bar> entry1, Map.Entry<Foo, Bar> entry2) {
return entry1.getValue().compareTo(entry2.getValue());
}
});
Alternately, if you like, you can use an alternate comparator to compare the values if you don't control the implementation of the value type.
If you look at the documentation for TreeMap you'll see it says:
Constructs a new, empty tree map, ordered according to the given comparator. All keys inserted into the map must be mutually comparable by the given comparator: comparator.compare(k1, k2) must not throw a ClassCastException for any keys k1 and k2 in the map. If the user attempts to put a key into the map that violates this constraint, the put(Object key, Object value) call will throw a ClassCastException.
The main point here is that it's comparing keys, but you're casting the key (ie: a String) into a Person.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With