Map 原理测试

大家都指导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

96321
96321
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;
    }











  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值