簡體   English   中英

Java HashMap和關鍵對象的問題我自己推出了

[英]Issues with Java HashMap and key Object I rolled myself

所以,我正在嘗試使用HashMap將我自己的Object映射到String值。 我的目標如下(為簡潔起見刪除了一些代碼)

public class RouteHeadsignPair {
    String route;
    String headsign;

    public RouteHeadsignPair(String n_route, String n_headsign) {
        route = n_route.toLowerCase();
        headsign = n_headsign.toLowerCase();
    }

    public String getRoute () {
        return route;
    }

    public String getHeadsign() {
        return headsign;
    }

    public boolean equals(RouteHeadsignPair other) {
        return(other.getRoute().equals(route) && other.getHeadsign().equals(headsign));
    }

    public int hashCode() {
        return(route.hashCode());
    }
}

我通過從文本文件加載數據將一堆這些對象映射到字符串。 稍后,基於(獨立的)用戶輸入,我嘗試使用RouteHeadsignPair對象查詢HashMap containsKey()返回false,get()返回null,就好像我從未將鍵添加到地圖中一樣。 但是,奇怪的是,如果我使用下面的代碼迭代地圖(其中newKey是由用戶輸入構成的RouteHeadsignPair

RouteHeadsignPair foundKey = null;
Iterator<RouteHeadsignPair> keysInMap = routeHeadsignToStopIdMap.keySet().iterator();
while(keysInMap.hasNext()) {
    RouteHeadsignPair currKey = keysInMap.next();

    if(currKey.equals(newKey)) {
        System.err.println("Did find a key with an equals() == true!");
        foundKey = currKey;
    }
}

System.err.println("Value in map? " + routeHeadsignToStopIdMap.containsKey(newKey)  + "( hashcode = " + newKey.hashCode() + 
        ", equals = " + newKey.equals(foundKey) + ")");
System.err.println("foundKey in map? " + routeHeadsignToStopIdMap.containsKey(foundKey)  + "( hashcode = " + foundKey.hashCode() + 
        ", equals = " + foundKey.equals(newKey) + ")" );

我得到以下輸出

Did find a key with an equals() == true!

接着

Value in map? false( hashcode = 1695, equals = true)
foundKey in map? true( hashcode = 1695, equals = true)

因此,如果我遍歷鍵並查找返回equals()鍵,我會找到一個,而hashCode()對於這兩個鍵都是相同的。 如果hashCode()是相同的newKeyfoundKeyfoundKey.equals(newKey)返回true,不應該HashMap.get(key)返回一個值和containsKey()返回true? 我在這做錯了什么?

您沒有覆蓋Object.equals - 由於參數類型,您正在重載它。 您的診斷代碼會調用您的重載,但地圖代碼不會(因為它不知道它)。

你需要一個簽名為的方法

public boolean equals(Object other)

如果使用@Override注釋,如果未能正確覆蓋某些內容,則會出現錯誤。

您需要先檢查other是否是RouteHeadSignPair的實例,然后再進行RouteHeadSignPair 如果你使RouteHeadSignPair類成為最終版,那么你不必擔心它是否是完全相同的類等。

請注意,順便說一句,您的哈希碼會不必要地發生沖突 - 如果您同時使用route headSign哈希來生成哈希碼,則可能有助於您的地圖查找更有效。 (如果有多個實例具有相同的路徑但是頭部符號不同,則在查找密鑰時,如果地圖不必檢查所有路由的相等性,則會很有用。)

暫無
暫無

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

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