从具有id的Treemap获取对象会引发异常

时间:2014-02-10 08:50:49

标签: java map

我想创建一个有序地图。我使用下面的代码创建了一个地图,首先我检查了这个对象并将此对象添加到列表中。但是当我尝试检查第二个对象时,它会给出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.

}

5 个答案:

答案 0 :(得分:1)

TreeMap中,Comparator是比较键而不是值。第一个getput成功,因为地图是空的,不需要调用比较器。但第二个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<>();