主函数为:
int code = 0;
Person person = null;
Map personMap = new HashMap();
Map codeMap = new HashMap();
for(int i = 0; i<10000; i++)
{
person = new Person();
code = person.hashCode();
personMap.put(person, "");
codeMap.put(code, "");
}
System.out.println("personMap size : " + personMap.size() +
"\ncodeMap size : " + codeMap.size());
Person类为:
class Person{}
输出为:
personMap size : 10000
codeMap size : 9998
为什么personMap的大小为10000,而codeMap的大小为9998,以我的理解应该都是9998
codeMap: 键是person.hashCode(),如果两个person的hashCode相同,那么放到codeMap中两个person的键值是相同,后一个覆盖前一个。
personMap: 键是person本身,即使两个person算处理的hashCode相同,但是由于判断键值此时判断键值是否相同调用的是equals方法(需要看在你的Person中是否覆盖了equals方法),此时即使两个person的hashCode相同,由于equals返回的不同,两个person放到HashMap时键值也可能不同。从你的结果看: 就是有两个Person对,他们hashCode相同,但是键值不等。
要彻底了解这个问题需要了解HashMap的实现,参考:
http://www.ibm.com/developerworks/cn/java/j-lo-hash/?ca=drs-tp4608
请提供Person的源码!
因为Person类hashcode方法返回的hashcode并不是唯一的,有重复的,而在HashMap中是不允许有重复的键的。
我们再来看一下HashMap类的put方法的源码中的验证重复key的一段。我在判断逻辑加上了注释
[code="java"]
for (Entry e = table[i]; e != null; e = e.next) {
Object k;
/* 不同Person对象,有可能出现重复的hashcode值,但是不同的Person对象p1==p2是绝对不可能为true的, 所以((k = e.key) == key || key.equals(k))为false,所以personMap的size为10000,而codeMap的size为<=10000
*/
if (e.hash == hash && ((k = e.key) == key || key.equals(k))) {
V oldValue = e.value;
e.value = value;
e.recordAccess(this);
return oldValue;
}
}
[/code]
是不是你hashcode或者equals重写的有问题。
发下源码。
还有,就是为啥你认为都是9998啊?