[英]HashMap.get() doesn't return the proper value, thanks to “hashCode()”
我目前正在使用地圖編輯器來開發TD游戲。 現在很明顯,您可以保存和加載這些地圖(至少應該能夠)。 問題是:有時我在HashMap
上調用.get()
。 不幸的是,應該相同的鍵(在邏輯上)不是相同的對象(就引用而言),並且,根據我之前的google研究,覆蓋它們的.equals
方法是不夠的,因為它們仍然返回不同的值.hashCode()
散列(我驗證了它們確實返回不同的散列,而.equals
確實返回true)。
(附帶說明,這很令人困惑,因為HashMap.get(key)
的javadoc僅聲明它們必須相等)
更具體地說, HashMap
包含我的Path
類的實例作為鍵,並且應返回對應的敵人列表(=值)。
Path
簡短版本(無吸氣劑等):
public class Path
{
private List<Tile> tiles = new ArrayList<>();
@Override
public boolean equals(Object obj) {
//code comparing the two paths
}
@Override
public int hashCode() {
//what I still need to implement. ATM, it returns super.hashCode()
}
}
public class Tile
{
private int x;
private int y;
//constructor
//overrides equals
//getters & some convenience methods
}
現在,如果兩個路徑相等,我希望它們返回相同的哈希碼,以便HashMap
返回正確的敵人列表。 (我將確保不能添加兩個相同的路徑)。
現在我的問題是:
你有建議嗎
?
請注意,我寧願避免將HashMap
更改為其他類型的地圖,如果這樣做甚至可以幫助解決問題。
您絕對需要實現與equals
一致的hashCode
。 IDE經常在生成hashCode
和equals
做得不錯。 還考慮Objects.equals(...)
和Objects.hash(...)
。
關於在HashMap
使用Path
作為鍵的一種警告。 您必須使該類不變,以使其可靠地工作。 或至少確保密鑰的hashCode
不變。 否則,即使使用相同或相等的密鑰,也可能無法取回數據。
List
有一個有用的方法,該方法也方便地稱為list.hashCode()
。 這將計算列表中所有元素的hashCode。 因此,您還必須實現Tile
的hashCode,它可能包含一些原始字段或類似的字段。
例如
@Override
public int hashCode() {
return tiles != null ? tiles.hashCode() : 0;
}
在這里查看文檔
int hashCode()
返回此列表的哈希碼值。 列表的哈希碼定義為以下計算的結果:
int hashCode = 1;
for (E e : list)
hashCode = 31*hashCode + (e==null ? 0 : e.hashCode());
這可以確保
list1.equals(list2)
隱含了Object.hashCode()
的一般協定所要求的任何兩個list1
和list2
list1.hashCode()==list2.hashCode()
Object.hashCode()
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.