版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/zouheliang/article/details/80534905
大家都指导hashmap在存储的时候都是先计算key的hashcode,来决定存储的位置,然后再将value存在对应的数组联表中Entry .这里我就不细说了,
https://blog.csdn.net/basycia/article/details/52081111
https://blog.csdn.net/hsk256/article/details/49363271都可以参考,特别是第二篇里面提到链表是为了存储同一个hashcode的,这里我不太赞同这种表达,明明是取模运算下来决定是哪个数组下标,怎么能说是为了 管理相同hashcode呢,不过这也引发了我的思考,如果两个hashcode相同的key会有什么效果呢,不多说,直接上代码:
public class DjlOVE {
private String name;
private String sex;
public DjlOVE(String name)
{
this.setName(name);
}
@Override
public int hashCode()
{
return getName().hashCode();
}
public String getSex()
{
return sex;
}
public void setSex( String sex )
{
this.sex = sex;
}
public String getName()
{
return name;
}
public void setName( String name )
{
this.name = name;
}
}
此对象重载了hashcode,保证name相同时候的hashcode是相同的。
public class T {
public static void main( String[] args )
{
Map<Object ,DjlOVE> djmap=new HashMap<>();
DjlOVE djlOVE = new DjlOVE("aaa");
DjlOVE djlOVE2 = new DjlOVE("aaa");
DjlOVE djlOVE3 = new DjlOVE("aaa");
DjlOVE djlOVE4 = new DjlOVE("aaa");
System.out.println(djlOVE.hashCode());
System.out.println(djlOVE2.hashCode());
System.out.println(djlOVE3.hashCode());
System.out.println(djlOVE4.hashCode());
djmap.put(djlOVE, djlOVE);
djmap.put(djlOVE2, djlOVE2);
djmap.put(djlOVE3, djlOVE3);
djmap.put(djlOVE4, djlOVE4);
System.out.println("map size"+djmap.size());
DjlOVE djlOVE5 = djmap.get(djlOVE2);
System.out.println(djlOVE5.getName());
System.out.println(djlOVE5.hashCode());
}
}
结果:
96321
9632196321
96321
map size4
aaa
96321
所有对象的hashcode是一样的,但是map中确存了四个hashcode相同的对象,所以hashcode并不是唯一决定对象是否是同一对象的条件。我们都知道如果key相同是会覆盖,那么这里的相同是值equals,而不是单单值hashcode。我们在实验一把,将equals也重写了,看是否还是会有四个对象在map中。怎讲如下代码到对象类中。
public boolean equals(Object obj)
{
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
DjlOVE other = (DjlOVE) obj;
if (name != other.name)
{ return false; }
else
return true;
}
测试结果如下:
96321
96321
96321
96321
map size1
aaa
96321
大家看到了吧,map的size变成1了,说明equals 才是决定key是否一致的关键,而我们重新equals都要重写hashcode,所有的牵牵扯扯大家可以看看map的put源码
public Object put(Object key, Object value)
{
key = convertKey(key);
int hashCode = hash(key);
int index = hashIndex(hashCode, data.length);
for(HashEntry entry = data[index]; entry != null; entry = entry.next)
if(entry.hashCode == hashCode && isEqualKey(key, entry.key))
{
Object oldValue = entry.getValue();
updateEntry(entry, value);
return oldValue;
}
addMapping(index, hashCode, key, value);
return null;
}