[英]Can we use object as a key in hashmap in Java?
如何使用 object 作為 hashmap 中的密鑰。 如果您使用 object 作為鍵,您是否需要覆蓋該 object 的等於和哈希碼方法?
一個簡單的經驗法則是使用不可變對象作為HashMap
鍵。
因為:
如果它是可變的,那么hashcode()
值或equals()
條件可能會更改,並且您將永遠無法從HashMap
檢索鍵。
更准確地說,用於計算equals()
和hashcode()
類字段應該是不可變的!
現在,假設您創建了自己的類:
equals()
hashcode()
(再次,牢記不變性) 請記住,如果兩個對象是equal()
,那么它們的hashcode()
應該相等!
hashCode() -HashMap 提供用於存儲的 put(key, value) 和用於從 HashMap 檢索值的 get(key) 方法。 當 put() 方法用於存儲 (Key, Value) 對時,HashMap 實現調用 Key 對象上的 hashcode 來計算用於查找存儲 Entry 對象的存儲桶的哈希值。 當 get() 方法用於檢索值時,再次使用鍵對象來計算哈希,然后使用該哈希來查找存儲該特定鍵的存儲桶。
equals() - equals() 方法用於比較對象的相等性。 如果使用 HashMap 鍵對象進行比較,同樣使用 equals() 方法 Map 知道如何處理散列沖突(散列沖突意味着多個鍵具有相同的散列值,因此分配到同一個桶。在這種情況下,對象是存儲在鏈表中,請參閱圖以獲得更清晰的信息。其中 hashCode 方法有助於找到存儲該鍵的存儲桶,equals 方法有助於找到正確的鍵,因為單個存儲桶中可能存儲了多個鍵值對.
您可以在HashMap
使用任何對象,只要它具有正確定義的hashCode
和equals
方法——這些絕對是至關重要的,因為散列機制取決於它們。
是的,您應該覆蓋 equals 和 hashcode,以便代碼正常運行,否則您將無法獲得已插入地圖的鍵的值。
例如
map.put(new Object() , "value") ;
當你想獲得那個價值時,
map.get(new Object()) ; // 這將始終返回 null
因為使用 new Object() - 將生成新的哈希碼並且它不會指向保存值的預期桶號,並且如果最終桶號變得相同 - 它將無法匹配哈希碼甚至等於所以它總是返回 NULL 。
您的問題的答案是肯定的,自定義類的對象可以用作 HashMap 中的鍵。 但是為了不失敗地從映射中取回值對象,需要遵循某些准則。
1)Custom class should follow the
between hashCode() and equals().
1)Custom class should follow the
約定between hashCode() and equals().
合同規定:
If two objects are equal according to the equals(Object) method, then calling
the hashCode method on each of the two objects must produce the same integer result.
這可以通過在自定義類中實現 hashcode() 和 equals() 來完成。
2) Make custom class immutable.
提示:使用final,刪除setter,使用deep copy來設置字段
Yes, we can use any object as key in a Map in java but we need to override the equals() and hashCode() methods of that object class. 請參考下面的示例,其中我將一對 class 的 object 存儲為 hashMap 中的鍵,其值類型為 Z9018DC81AE51244B 中的字符串。 我已經覆蓋了 Pair class 的 hashCode() 和 equals() 方法。 因此,具有相同 Pair(x,y) 值的 Pair class 的不同對象將僅被視為一個 object。
import java.util.*;
import java.util.Map.Entry;
class App { // Case-sensitive
private class Pair {
private int x, y;
public Pair(int x, int y) {
this.x = x;
this.y = y;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + x;
result = prime * result + y;
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Pair other = (Pair) obj;
if (x != other.x)
return false;
if (y != other.y)
return false;
return true;
}
}
public static void main(String[] args) {
App obj = new App();
obj.show();
}
private void show() {
Map<Pair, String> map = new HashMap<>();
Pair obj1 = new Pair(10, 20);
Pair obj2 = new Pair(40, 50);
Pair obj3 = new Pair(10, 20);
// We can see that obj1 and obj3 have same values. So, we want to store these
// objects
// as one .To achieve
// that,
// we have overridden equals() and hashCode() methods of Pair class.
map.put(obj1, "First");
map.put(obj2, "Second");
map.put(obj3, "Third");
System.out.printf("Size of Map is :%d \n", map.size());
for (Entry<App.Pair, String> p : map.entrySet()) {
Pair pair = p.getKey();
System.out.printf("Map key-value pair is (%d,%d)->%s \n", pair.x, pair.y, p.getValue());
}
// output -
// Size of Map is :2
// Map key-value pair is (10,20)->Third
// Map key-value pair is (40,50)->Second
}
}
package com.java.demo.map;
import java.util.HashMap;
public class TestMutableKey
{
public static void main(String[] args)
{
//Create a HashMap with mutable key
HashMap<Account, String> map = new HashMap<Account, String>();
//Create key 1
Account a1 = new Account(1);
a1.setHolderName("A_ONE");
//Create key 2
Account a2 = new Account(2);
a2.setHolderName("A_TWO");
//Put mutable key and value in map
map.put(a1, a1.getHolderName());
map.put(a2, a2.getHolderName());
//Change the keys state so hash map should be calculated again
a1.setHolderName("Defaulter");
a2.setHolderName("Bankrupt");
//Success !! We are able to get back the values
System.out.println(map.get(a1)); //Prints A_ONE
System.out.println(map.get(a2)); //Prints A_TWO
//Try with newly created key with same account number
Account a3 = new Account(1);
a3.setHolderName("A_THREE");
//Success !! We are still able to get back the value for account number 1
System.out.println(map.get(a3)); //Prints A_ONE
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.