Java HashMap的关键问题

时间:2013-11-25 19:28:58

标签: java serialization hashmap

我目前正在制作一个自定义序列化程序作为项目的一部分,在这里我也需要序列化引用,这意味着如果两个字段在序列化之前引用同一个项目,它们也应该在反序列化之后。

为此,我使用HashMap,将每个对象映射到一个ID,我可以将其用作序列化的每个对象的属性,同时跟踪已经序列化的对象。我偶然发现了一些问题。

似乎java HashMap只检查键上的相等性,而不是它们是否是相同的引用。例如,在下文中,变量b最终为真:

HashMap<Object, Integer> map = new HashMap<Object, Integer>();
LinkedList<Object> ll1 = new LinkedList<Object>();
LinkedList<Object> ll2 = new LinkedList<Object>();
map.put(ll1, 5);
boolean b = map.containsKey(ll2);

有时候结果根本没有意义。在这里,b也是如此:

HashMap<Object, Integer> map = new HashMap<Object, Integer>();
LinkedList<Object> ll1 = new LinkedList<Object>();
Stack<Object> stack = new Stack<Object>();
map.put(ll1, 5);
boolean b = map.containsKey(stack);

我想要的是ContainsKey方法,不仅要调用equals方法,还要使用'==' - 运算符检查引用是否相同。我可以这样做而无需查看整个密钥集吗?

提前致谢

1 个答案:

答案 0 :(得分:5)

Map接口的常规合同是,如果两个键都为null,或者它们不为null且a.equals(b),则认为它们是相等的。除非密钥类的==方法的实现执行此操作,否则它不会使用equals进行比较。

LinkedListStack个对象相同的原因是因为它们都实现了List接口,List.equals的定义是两个列表相等具有相同的大小,并以相同的顺序包含相同的对象。因为它们都是空的,所以它们是“平等的”。

我相信你正在寻找IdentityHashMap。它故意违反Map接口的合同,仅使用==,而不是Object.equals()来比较对象。同样,对于哈希码,它使用System.identityHashCode而不是任何被覆盖的Object.hashCode()