因此,我正在尝试使用a HashMap将自己Object的String值映射到一个值。我的对象在下面(为简洁起见删除了一些代码)
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()); } }
我通过从文本文件加载数据将一堆这些对象映射为字符串。稍后,基于(独立)用户输入,我尝试HashMap使用RouteHeadsignPairObject 查询。containsKey()返回false,而get()返回null,就好像我从未将密钥添加到映射中一样。但是,奇怪的是,如果我使用迭代在地图上下面的代码(其中newKey是RouteHeadsignPair从用户输入制造)
RouteHeadsignPair
newKey
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()相同newKey,foundKey并且foundKey.equals(newKey)返回true,则不应该HashMap.get(key)返回值并containsKey()返回true?我在这里做错了什么?
equals()
hashCode()
foundKey
foundKey.equals(newKey)
HashMap.get(key)
containsKey()
您并没有覆盖Object.equals- 由于参数类型,您正在 重载 它。您的 诊断 代码将调用您的重载,但映射代码则不会(因为它不知道)。
Object.equals
您需要一个签名为
public boolean equals(Object other)
如果您使用@Override注释,则如果无法正确覆盖某些内容,则会收到错误消息。
@Override
您需要检查是否other是RouteHeadSignPairfirst,然后是cast 的实例。如果您将RouteHeadSignPair班级定为最终班级,则无需担心班级是否完全相同,等等。
other
RouteHeadSignPair
请注意,您的哈希码将不必要的碰撞,顺便说一句-如果你同时使用route 与 该headSign哈希来生成散列码,它可以帮助你的地图查找更有效率。(如果有多个实例具有相同的路线但头部符号不同,则在查找键时地图不必检查所有实例是否相等时很有用。)
route
headSign