我有一个包含 X 个元素的 HashMap
我需要将此 map 移至另一张 map
这就是我的代码的样子
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 不添加新元素并覆盖现有元素?
最佳答案
如果 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
的具体细节可能不同,但不对称性是相同的。)
import java.util.*;
public class Test {
private final String name;
public Test(String name)
{
this.name = name;
}
public static void main(String[] args)
{
Map<Test, String> firstMap = new HashMap<Test, String>();
Test a = new Test("a");
Test b = new Test("b");
firstMap.put(b, "b");
firstMap.put(a, "a");
Map<Test, String> secondMap = new HashMap<Test, String>();
for (Map.Entry<Test, String> entry : firstMap.entrySet())
{
System.out.println("Adding " + entry.getKey().name);
secondMap.put(entry.getKey(), entry.getValue());
}
System.out.println(secondMap.size());
}
@Override public int hashCode()
{
return 0;
}
@Override public boolean equals(Object other)
{
return this.name.equals("b");
}
}
我的机器上的输出:
Adding a
Adding b
1
您可能无法以这种方式获得输出 - 这取决于:
- 调用
equals
的方式(candidateKey.equals(newKey)
或反之亦然) - 从集合中返回条目的顺序
它甚至可能在不同的运行中以不同的方式工作。
关于java - java中的 map 问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6962477/