所以,我正在尝试使用a 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());
}
}
Run Code Online (Sandbox Code Playgroud)
我通过从文本文件加载数据将一堆这些对象映射到字符串.稍后,基于(独立的)用户输入,我尝试查询HashMap使用RouteHeadsignPairObject.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) + ")" );
Run Code Online (Sandbox Code Playgroud)
我为代码格式化道歉,已经很晚了,我变得暴躁了
我得到以下输出
Did find a key with an equals() == true!
Run Code Online (Sandbox Code Playgroud)
然后
Value in map? false( hashcode = 1695, equals = true)
foundKey in map? true( hashcode = 1695, equals = true)
Run Code Online (Sandbox Code Playgroud)
因此,如果我遍历键并查找返回的键equals(),我会找到一个,hashCode()这两个都是相同的.如果hashCode()是相同的newKey,并foundKey和foundKey.equals(newKey)返回true,不应该HashMap.get(key)返回值,containsKey()返回true?我在这做错了什么?
你没有覆盖Object.equals- 由于参数类型,你正在重载它.您的诊断代码会调用您的重载,但地图代码不会(因为它不知道它).
你需要一个签名为的方法
public boolean equals(Object other)
Run Code Online (Sandbox Code Playgroud)
如果您使用@Override注释,如果您未能正确覆盖某些内容,则会收到错误.
您需要检查是否other是第一个实例RouteHeadSignPair,然后是强制转换.如果你让RouteHeadSignPair课程成为最终,你不必担心它是否完全相同,等等.
请注意,您的哈希码将不必要的碰撞,顺便说一句-如果你同时使用route 与该headSign哈希来生成散列码,它可以帮助你的地图查找更有效率.(如果有多个实例具有相同的路径但是头部符号不同,则在查找密钥时,如果地图不必检查所有路由的相等性,则会很有用.)
| 归档时间: |
|
| 查看次数: |
950 次 |
| 最近记录: |