简体   繁体   English

Java HashMap和关键对象的问题我自己推出了

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

So, I'm trying to use a HashMap to map my own Object to a String value. 所以,我正在尝试使用HashMap将我自己的Object映射到String值。 My object is below (with some code removed for brevity) 我的目标如下(为简洁起见删除了一些代码)

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());
    }
}

I'm mapping a bunch of these objects to Strings by loading data from a text file. 我通过从文本文件加载数据将一堆这些对象映射到字符串。 Later on, based on (independent) user input, I try to query the HashMap using a RouteHeadsignPair Object. 稍后,基于(独立的)用户输入,我尝试使用RouteHeadsignPair对象查询HashMap containsKey() returns false and get() returns null, as if I had never added the key into the map. containsKey()返回false,get()返回null,就好像我从未将键添加到地图中一样。 But, bizarrely, if I iterate over the map using the below code (where newKey is a RouteHeadsignPair made from user input) 但是,奇怪的是,如果我使用下面的代码迭代地图(其中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) + ")" );

I apologize for the code formatting, it's late and I'm getting cranky 我为代码格式化道歉,已经很晚了,我变得暴躁了

I get the following output 我得到以下输出

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

and then 接着

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

So, if I iterate over the keys and look for keys that return equals() , I do find one, and the hashCode() is the same for both of these. 因此,如果我遍历键并查找返回equals()键,我会找到一个,而hashCode()对于这两个键都是相同的。 If the hashCode() is the same for newKey and foundKey and foundKey.equals(newKey) returns true, shouldn't HashMap.get(key) return a value and containsKey() return true? 如果hashCode()是相同的newKeyfoundKeyfoundKey.equals(newKey)返回true,不应该HashMap.get(key)返回一个值和containsKey()返回true? What am I doing wrong here? 我在这做错了什么?

You're not overriding Object.equals - you're overloading it because of the parameter type. 您没有覆盖Object.equals - 由于参数类型,您正在重载它。 Your diagnostic code calls your overload, but the map code doesn't (as it doesn't know about it). 您的诊断代码会调用您的重载,但地图代码不会(因为它不知道它)。

You need a method with a signature of 你需要一个签名为的方法

public boolean equals(Object other)

If you use the @Override annotation you'll get an error if you fail to override something properly. 如果使用@Override注释,如果未能正确覆盖某些内容,则会出现错误。

You'll need to check whether other is an instance of RouteHeadSignPair first, then cast. 您需要先检查other是否是RouteHeadSignPair的实例,然后再进行RouteHeadSignPair If you make the RouteHeadSignPair class final, you won't need to worry about whether or not it's the exact same class, etc. 如果你使RouteHeadSignPair类成为最终版,那么你不必担心它是否是完全相同的类等。

Note that your hash codes will collide unnecessarily, by the way - if you use both the route and the headSign hashes to generate your hash code, it may help your map lookups to be more efficient. 请注意,顺便说一句,您的哈希码会不必要地发生冲突 - 如果您同时使用route headSign哈希来生成哈希码,则可能有助于您的地图查找更有效。 (If there are several instances with the same route but different head signs, it's useful if the map doesn't have to check for equality on all of them when looking up a key.) (如果有多个实例具有相同的路径但是头部符号不同,则在查找密钥时,如果地图不必检查所有路由的相等性,则会很有用。)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM