java中的地图问题
我有一个包含 X 个元素的哈希图
我需要将此地图移至另一张地图
这就是我的代码的样子
Map originMap = initialize();
Map destMap = new Hashmap ();
int originMapSize = originMap.size();
Set<Map.Entry<K, V>> entries = originMap.entrySet();
for (Map.Entry<K, Y> mapEntry : entries) {
K key = mapEntry.getKey();
V value = mapEntry.getValue();
destMap.put (key,value);
}
// Shouldnt this be equal to originMapSize ????
int destMapSize = destMap.size();
我观察到的是 - originMapSize 不等于 destMapSize
似乎当我们将元素放入 destMap 时,某些元素被覆盖
我们已经覆盖了 hashCode 和 equals 方法 - 它是可疑的实施。
但是,如果 originMap 允许添加元素,为什么 destinationMap 不添加新元素并覆盖现有元素?
I have a Hashmap which has X number of elements
I need to move this map into another map
This is what my code looks like
Map originMap = initialize();
Map destMap = new Hashmap ();
int originMapSize = originMap.size();
Set<Map.Entry<K, V>> entries = originMap.entrySet();
for (Map.Entry<K, Y> mapEntry : entries) {
K key = mapEntry.getKey();
V value = mapEntry.getValue();
destMap.put (key,value);
}
// Shouldnt this be equal to originMapSize ????
int destMapSize = destMap.size();
What I am observing is - originMapSize is NOT equal to the destMapSize
It seems when we put the elements in the destMap, some of the elements are being overridden
We have overrridden the hashCode and equals method- and it is a suspicious implementation.
However, if the originMap allowed the elements to be added, why would the destinationMap not add a new elements and override an existing element instead ?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
如果
equals
方法不对称,则可能会发生这种情况。假设有两个键 a 和 b,使得:a.hashCode() == b.hashCode()
a.equals(b)
返回 falseb。 equals(a)
返回 true然后假设
HashMap
实现通过对具有相同值的每个现有键调用existingKey.equals(newKey)
来搜索现有键哈希码作为新的 钥匙。现在假设我们最初按照 { a, b } 的顺序添加它们。
第一个键 (
a
) 显然没有任何问题。第二个键 (b
) 插入最终调用a.equals(b)
- 这是错误的,所以我们得到两个键。现在构建第二个
HashMap
,我们最终可能会以 { b, a } 的顺序获取条目。这次我们首先添加
b
,这很好......但是当我们插入第二个键 (a
) 时,我们最终会调用b.equals(a)
,它返回 true,因此我们覆盖该条目。这可能不是正在发生的事情,但它可以解释一些事情 - 并显示不对称
equals
方法的危险。编辑:这是一个简短但完整的程序,演示了这种情况。 (
a
和b
的确切细节可能不同,但不对称性是相同的。)我机器上的输出:
您可能无法以这种方式获得输出 - 它取决于:
equals
的调用方式(candidateKey.equals(newKey)
或反之亦然)它甚至可能以不同的方式工作不同的运行。
This could happen if the
equals
method was asymmetric. Suppose there are two keys a and b such that:a.hashCode() == b.hashCode()
a.equals(b)
returns falseb.equals(a)
returns trueThen suppose that the
HashMap
implementation searches for an existing key by callingexistingKey.equals(newKey)
for each existing key with the same hash code as the new key.Now suppose we originally add them in the order { a, b }.
The first key (
a
) obviously goes in with no problems. The second key (b
) insertion ends up callinga.equals(b)
- which is false, so we get two keys.Now building the second
HashMap
, we may end up getting the entries in the order { b, a }.This time we add
b
first, which is fine... but when we insert the second key (a
) we end up callingb.equals(a)
, which returns true, so we overwrite the entry.That may not be what's going on, but it could explain things - and shows the dangers of an asymmetric
equals
method.EDIT: Here's a short but complete program demonstrating this situation. (The exact details of
a
andb
may not be the same, but the asymmetry is.)Output on my machine:
You may not get the output that way round - it depends on:
equals
is called (candidateKey.equals(newKey)
or vice versa)It may even work differently on different runs.
这些值应该相等,但问题是您正在迭代不同的 Map 对象。
不等于
Those values should be equal, but the problem is you are iterating over a different Map object.
is not the same as
我怀疑添加到第一个哈希映射的元素顺序与添加到第二个哈希映射的元素顺序不同。这与粗略的 hashCode 方法相结合,导致重复项添加到第一个方法中。
尝试更改 hashCode 以始终返回相同的值,看看问题是否消失。
I suspect the order of the elements being added to the first hashmap is not the same as the order added to the second. This combined with the sketchy hashCode method is causing duplicates to be added to the first.
Try changing hashCode to always return the same value to see if your problem goes away.
为什么不使用 destMap.putAll(originMap) ?
Why don't you use destMap.putAll(originMap) ?
Map 有一个 putAll 方法。尝试这样的事情:
Map has a putAll method. Try something like this:
这取决于第一个 HashMap 是如何初始化的。此外,每次将对象添加到 HashMap 中时,一旦它通过 75% 的负载因子,它就会分配默认大小的两倍来容纳新值。地图的默认大小通常为 16:当您超过 75% 的负载系数时,它会放大到 32。
It depends of how the first HashMap is initialized. Also everytime you add an object into the HashMap , once it passes 75% load factor, it allocates twice the default size to accomodate new values. Maps usually have default size = 16: when you pass the 75% load factor it enlarges to 32.