我目前正在制作一个自定义序列化程序,作为项目的一部分,这里我也需要序列化引用,这意味着如果两个字段在序列化之前引用同一个项目,那么在反序列化之后也应该引用。
为此,我使用了一个HashMap,将每个对象映射到一个ID,我可以将该ID用作每个序列化对象的属性,同时跟踪哪些对象已经被序列化。不过我偶然发现了一些问题。
java HashMap似乎只检查键上的相等性,而不检查它们是否是相同的引用。例如,在下面的例子中,变量b最终为true:
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方法,还使用"=="-运算符检查引用是否相同。我能做到这一点而不需要查看整个密钥集吗?
提前感谢
Map接口的一般约定是,如果两个键都为null,或者它们不为null且为a.equals(b)
,则认为它们相等。它不使用==
进行比较,除非键类的equals
方法实现可以这样做。
LinkedList
和Stack
对象相等的原因是它们都实现了List
接口,而List.equals
的定义是,如果两个列表具有相同的大小,并且按相同的顺序包含相同的对象,则它们是相等的。因为它们都是空的,所以它们是"相等的"。
我相信你在找IdentityHashMap
。只使用==
而不使用Object.equals()
来比较对象,这故意违反了Map接口的约定。同样,对于哈希代码,它使用System.identityHashCode
,而不是任何重写的Object.hashCode()
。