簡體   English   中英

由於“ hashCode()”,HashMap.get()無法返回正確的值

[英]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返回正確的敵人列表。 (我將確保不能添加兩個相同的路徑)。

現在我的問題是:

你有建議嗎

  1. 使用一些外部庫生成哈希
  2. 我寫了自己的計算哈希的實現,或者
  3. 其他的東西

請注意,我寧願避免將HashMap更改為其他類型的地圖,如果這樣做甚至可以幫助解決問題。

您絕對需要實現與equals一致的hashCode IDE經常在生成hashCodeequals做得不錯。 還考慮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()的一般協定所要求的任何兩個list1list2 list1.hashCode()==list2.hashCode() Object.hashCode()

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM