2014-02-10 27 views
0

我想創建一個排序後的Map。我用下面的代碼創建了一個地圖,首先我檢查了這個對象並將這個對象添加到列表中。但是當我嘗試檢查第二個對象時,它會給出ClassCastException。從樹形結構中獲取對象並帶有id拋出異常

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. 

} 
+3

使用泛型:'地圖<字符串,學生>'。 – 2014-02-10 08:51:51

+1

Post Stacktrace詳細信息 –

+0

@LutzHorn我已經更改爲Map 但仍會拋出相同的異常。 – hellzone

回答

1

TreeMapComparator是比較鍵而不是值。第一個getput成功,因爲地圖是空的,不需要調用比較器。但第二個get需要比較器將密鑰與現有密鑰進行比較。您的輸入密鑰爲String類型,而比較器將其處理爲Student類型。然後拋出ClassCastException

聲明地圖爲:

Map<String, Student> students = new TreeMap<String, Student>(); 

那麼它會工作。請注意,您不需要爲String密鑰類型提供Comparetor,因爲String已經是Comparable

0

您不會告訴我們您如何填充Map。所以我的一般建議是使用泛型:

Map<String, Student> students = new TreeMap<>(...); 

然後鑄造是沒有必要的。

+0

這不是因爲數據填充或通用類型,而是比較器。 –

0

避免在集合中使用原始類型。在這種情況下,您不確定實際進入您收藏的內容(如地圖,列表等)。因此,您需要添加一個演員陣容,同時檢索易於使用ClassCastExceptionMap中的元素,因爲您不確定被檢索的對象。

嘗試使用泛型這樣的:

Map<String, Student> students = new TreeMap<String, Student>(); 
+0

Java 7擁有'<>'快捷鍵。 – 2014-02-10 08:55:43

0
Student student2= (Student) students.get("42131"); 

我覺得在第一次時的代碼塊將執行就沒有用鑰匙「42131」,所以它會返回null關聯值。你試圖用Student類來施放。

Map students = new TreeMap(...); 

此通用映射將接受任何類型的Object鍵值對。所以你必須使用泛型來使類型安全。

Map<String, Student> students = new TreeMap<>(...); 

這個學生的地圖是類型安全的字符串類型的值鍵和學生類型。

而你得到的異常只是因爲你添加了一些字符串反對該鍵。

+0

查看編輯的問題。你感覺不對。 – 2014-02-10 08:57:25

+1

投射null不會引發異常。 – Ioan

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<>();