我想创建一个有序地图。我使用下面的代码创建了一个地图,首先我检查了这个对象并将此对象添加到列表中。但是当我尝试检查第二个对象时,它会给出ClassCastException。
java.lang.ClassCastException: java.lang.String cannot be cast to myapplication.Student
这是我的代码;
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);
}
我的Student.java类;
public class Student {
private String name;
private String number;
//const, getters and setters.
}
答案 0 :(得分:1)
在TreeMap
中,Comparator
是比较键而不是值。第一个get
和put
成功,因为地图是空的,不需要调用比较器。但第二个get
要求比较器将密钥与现有密钥进行比较。您的输入密钥为String
类型,而比较器将其处理为Student
类型。然后抛出ClassCastException
。
将地图声明为:
Map<String, Student> students = new TreeMap<String, Student>();
然后它会起作用。请注意,您不需要为Comparetor
密钥类型提供String
,因为String
已经Comparable
。
答案 1 :(得分:0)
您没有告诉我们您如何填充Map
。所以我的一般建议是使用泛型:
Map<String, Student> students = new TreeMap<>(...);
然后不需要施法。
答案 2 :(得分:0)
避免在集合中使用原始类型。在这种情况下,您不确定实际进入您的集合的内容(如Map,List等)。因此,您需要在从Map
检索易受{{1}影响的元素时添加强制转换。因为你不确定要检索的对象。
尝试使用这样的泛型:
ClassCastException
答案 3 :(得分:0)
Student student2= (Student) students.get("42131");
我觉得第一次执行代码块时,没有与键“42131”关联的值,因此它将返回null。您试图使用Student
类进行投射。
Map students = new TreeMap(...);
此通用映射将接受任何类型的Object键,值对。因此,您必须使用泛型来使类型安全。
喜欢
Map<String, Student> students = new TreeMap<>(...);
此学生地图对于字符串类型的键和学生类型的值是类型安全的。
你得到的异常只是因为你在这个键上添加了一些字符串。
答案 4 :(得分:0)
我找到了另一种方法,只需扩展TreeMap
并覆盖compare
方法。它看起来像这样:
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());
}
}
你可以像这样使用它:
final Map<String, Student> students = new StudentMap<>();