繁体   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