java - Java HashMap 和我自己滚动的关键对象的问题

标签 java hashmap

因此,我尝试使用 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,就好像我从未将键添加到映射中一样。但是,奇怪的是,如果我使用下面的代码迭代 map (其中 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() 是相同的这些。如果 newKeyfoundKeyhashCode() 相同,并且 foundKey.equals(newKey) 返回 true, HashMap.get(key) 不应该返回一个值而 containsKey() 返回 true 吗?我在这里做错了什么?

最佳答案

您没有重写Object.equals - 由于参数类型,您重载它。您的诊断代码调用您的重载,但 map 代码不会(因为它不知道)。

您需要一个签名为的方法

public boolean equals(Object other)

如果您使用@Override 注释,并且无法正确覆盖某些内容,则会收到错误消息。

您需要首先检查 other 是否是 RouteHeadSignPair 的实例,然后进行转换。如果将 RouteHeadSignPair 类设为最终类,则无需担心它是否是完全相同的类等。

请注意,顺便说一下,如果您同时使用 route headSign 哈希值来生成您的哈希代码,则会发生不必要的冲突。哈希码,它可以帮助您的 map 查找更加高效。 (如果有多个实例具有相同的路线但不同的车头标志,则如果 map 在查找键时不必检查所有实例的相等性,这会很有用。)

关于java - Java HashMap 和我自己滚动的关键对象的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12104975/

相关文章:

java - 如何使用另一个类或函数中的 HashMap?

java - 使用 while 循环向日期添加天数

Java堆空间: Hashmap, ArrayList

Java将两个不同大小的List合并为HashMap

hashmap - 是否可以使用 HashSet 作为 HashMap 的键?

java - Java 中的二维 HashMap (以及一般情况下)

java - 如何创建 Maven 可分发

java - 计算java中多个文件/文档中的词频

java - 将自定义主题应用于 ChoiceBox 时 JavaFX 出错

java - 静态方法继承和多态