[英]Custom object as Map key
正如我已經讀到的,如果自定義對象需要成為map的鍵,則需要覆蓋hashcode和equals方法,但是在我的情況下,它的工作原理並不被覆蓋。 有人可以告訴我出什么問題了嗎?
Map<Student,Integer> map = new HashMap<>();
Student s1=new Student(1,"A");
Student s2=new Student(2,"B");
Student s3=new Student(3,"C");
map.put(s1,1);
map.put(s2,2);
map.put(s1,3);
for(Student s:map.keySet()) {
System.out.println(map.get(s) + "->" + s.id + " " +s.name);
}
正確的輸出:
3-> 1安
2-> 2 B
它是equals
方法的特性之一:具有自反性。 意思就是
x.equals(x) == true
一個對象總是等於自己。 在這種情況下,您將繼續使用equals
方法的默認實現。
map.put(s1,1);
map.put(s1,3);
並且因為默認實現是自反的
s1.equals(s1) == true
值1
替換為3
但是,如果執行以下操作,結果將有所不同
map.put(new Student(1,"A"),3);
s1.equals(new Student(1,"A"));
您將需要覆蓋hashCode
和equals
使其正常工作。
如果沒有覆蓋的hashCode或equals方法,則Java將比較對象引用。 因此, s1
引用與s1
引用相同,因此可以將s1
關聯值替換為另一個值。
如果創建一個具有與s1
相同的屬性值的新Student
對象,然后嘗試將其插入到地圖中,則將有兩個不同的對。
內置的hashCode()
和equals()
可以正常工作。 它們在HashMap
要求的方式上是一致的(即:如果hashCode()
不相同,則equals()
將始終返回false
)。 這是因為每個對象實例將僅equal()
其自身。
但是,這通常不是您想要的。 具體而言,在不覆蓋這些方法的情況下,兩個具有相同字段的Student
實例將不被視為相等。 因此,這將打印出三行而不是一行:
Map<Student,Integer> map = new HashMap<>();
Student s1=new Student(1,"A");
Student s2=new Student(1,"A");
Student s3=new Student(1,"A");
map.put(s1,1);
map.put(s2,2);
map.put(s3,3);
for(Student s:map.keySet()) {
System.out.println(map.get(s) + "->" + s.id + " " +s.name);
}
(注意:從技術上講,這完全是正確的,但不一定是大多數閱讀您的代碼的人都會期望的。)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.