HashMap中以动态对象作为Key值时的Remove陷阱

在游戏服务器上控制角色的坐标点可以通过Point这个类来实现,地图模块则以HashMap来承载。此问题从简单来说,既HashMap以Point作为Key值时,用户往往会忽略其中一个细节照成后期的非编译Bug。

以下是示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
HashMap  <Point,String] hashMap = new HashMap<Point, String]();//把]换成>
Point A = new Point(2,2);
hashMap.put(A,"A");//将2,2点作为Key值存入HashMap
A.x = 1;//修改A点的x值
A.y = 1;//修改A点的y值
System.out.println(hashMap.get(A));//此时结果为Null 已经找不到了

//我们试着迭代一下
System.out.println(hashMap.size());//此处为1
for(Iterator<String] iterator = hashMap.values().iterator();iterator.hasNext();)
{
    iterator.next();
    iterator.remove();
}
System.out.println(hashMap.size());//此处依旧为1 即无法销毁


所以 使用Point作为HashMap的Key时大家要注意了 这个Point应当是Final态 即不可修改的 否则将发生在HashMap中无法找到对应Value也无法迭代删除的错误

当然其他以对象作为Key值时也应当注意
原因是hashMap的索引是通过Key的hashcode进行的 当用户人为修改对象的内部属性后会造成hashcode的变化 从而造成无法取得Value的错误

以上为本人Java游戏服务器开发中一些小小的总结
欢迎大家沟通交流指正 意在分享 与君共勉之

BeiTown
2012.11.05

本文链接:HashMap中以动态对象作为Key值时的Remove陷阱

转载声明:BeiTown原创,转载请注明来源:BeiTown's Coder 编码之源,谢谢


Tags: , , ,

2 Responses to HashMap中以动态对象作为Key值时的Remove陷阱

  1. FG911 说道:

    所以说哈希表还是用字符串或者数字做索引比较好

    • BeiTown 北呈 说道:

      嗯,确实,不过Point点对象方便游戏对象的坐标的寻址。想过用float或double型来标记,但是(1000,2000)
      标记成1000.2000 后面的000会被舍去,用String解析的话,存在一个转换效率的问题,有时间测测

发表评论

电子邮件地址不会被公开。 必填项已用 * 标注

*

您可以使用这些 HTML 标签和属性: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>