Reputation: 5236
I want to create a sorted Map. I created a map with below code and first I checked this object and add this object to list. But when I try check second object it gives ClassCastException.
java.lang.ClassCastException: java.lang.String cannot be cast to myapplication.Student
Here is my code;
Map students = new TreeMap(new Comparator<Student>() {
@Override
public int compare(Student s1, Student s2) {
if(s1.getName() == null || s2.getName() == null){
return -1;
}
return s1.getName().compareTo(s2.getName());
}
});
Student student = (Student) students.get("23123");
if (student == null) {
student= new Student("321312", "sfsfsfs");
students.put("23123", student);
}
Student student2 = (Student) students.get("42131");//this line throws exception
if (student2 == null) {
student2 = new Student("421321", "dgdfs");
students.put("42131", student2);
}
My Student.java class;
public class Student {
private String name;
private String number;
//const, getters and setters.
}
Upvotes: 0
Views: 225
Reputation: 2830
I found another approach, just extend TreeMap
and override compare
method. It looks like this:
class StudentMap<K extends String, T extends Student>
extends TreeMap<String, Student> implements Comparator<String> {
@Override
public int compare(String key1, String key2) {
if (key1 == null || key2 == null) {
return -1;
}
return this.get(key1).getName().compareTo(this.get(key2).getName());
}
}
And you can use it like this:
final Map<String, Student> students = new StudentMap<>();
Upvotes: 0
Reputation: 3605
In TreeMap
the Comparator
is to compare the key rather than the value. The first get
and put
succeeded because the map is empty, and don't need to invoke your comparator. But the second get
requires the comparator to compare the key with the existing key. Your input key is String
type while the comparator process it as Student
type. Then a ClassCastException
is thrown.
Declare your map as:
Map<String, Student> students = new TreeMap<String, Student>();
then it will work. Note that you don't need to provide a Comparetor
for String
key type because String
is already Comparable
.
Upvotes: 1
Reputation: 41200
Student student2= (Student) students.get("42131");
I feel at first time when the block of code will execute there would be no value associated with the key "42131" so it'll return null. Which you try to cast with Student
class.
Map students = new TreeMap(...);
This generic map will accept any type of Object key,value pair. So you must use generic to make type-safe.
like
Map<String, Student> students = new TreeMap<>(...);
This students map is type safe to string type of key and Student type of value.
And Exception you are getting just because of you have added some string against that key.
Upvotes: 0
Reputation: 7804
Avoid using raw types in collections. In such cases you are not sure what is actually going into your collection (like Map, List etc.) As a result, you need to add a cast while retrieving elements from the Map
which is vulnerable to ClassCastException
as you are not sure about the object being retrieved.
Try using generics like this:
Map<String, Student> students = new TreeMap<String, Student>();
Upvotes: 0
Reputation:
You don't show us how you populate the Map
. So my general advice is to use Generics:
Map<String, Student> students = new TreeMap<>(...);
Then casting is not necessary.
Upvotes: 0