深入理解HashMap

关于HashCode的作用:
1、hashCode的存在主要是用于查找的快捷性,如:Hashtable,HashMap等,hashCode是用来散列存储结构中确定对象的存储地址的;
2、如果两个对象相同,就是适用于equals(java.lang.Object)方法,那么两个对象的hashCode一定要相同

一、HashMap的实现原理
在这里插入图片描述
从上图当中可以看出,HashMap底层就是一个数组结构,数组中的每一项又是一个链表。当新建一个HashMap的时候,就会初始化一个数组

HashMap是通过键值对,即Key-Value当作一个整体,然后利用Entry对象当作一个整体。HashMap底层采用一个Entry[]数组来保存所有的key-value对

1、HashMap的存储方式
运用到数据结构的散列知识,其中还运用到了关于equals方法和hashcode之间的关系

transient Entry[] table;
static class Entry<K,V> implements Map.Entry<K,V>{
          final K key;
          V value;
          final int hash;
          Entry<K,V>next;
 ....
}

可以看出在新建一个hashmap的时候,就会初始化一个数组,其中Entry就是数组中的元素,它持有一个指向下一个元素的引用,构成了链表,也就是相当于一个链表数组。
逻辑关系是:首先先计算元素的键值散列的位置,即根据元素该key的hashCode()返回值决定该链表(Entry)的存储位置:如果两个Entry的key的hashCode()返回值相同,那它们的存储位置相同。如果两个Entry的key通过equals比较返回true,新添加的Entry的value将覆盖集合中原有的Entry的value,但是key不会覆盖。如果两个Entry的key通过equals返回的是false,那么新添加的Entry将与原有的Entry形成Entry链,新添加的位于Entry的头部

2、HashMap的resize
当HashMap中的元素越来越多的时候,碰撞的几率也就越来越高(因为数组的长度是固定的),所以为了提高查询的效率,就要对hashmap的数组进行扩容,数组扩容这个操作也会出现在ArrayList中,所以这是一个通用的操作
问题:hashmap什么时候进行扩容呢?
答案:当hashmap中的元素个数超过数组大小loadFactor(即0.75)时就会进行扩容,也就是说,默认情况下,数组大小为16,那么当hashmap元素个数超过12的时候,就把数组的大小扩展为216 = 32,即扩大一倍,然后重新计算每个元素在数组中的位置,而这是一个非常消耗内存的操作。
所以如果我们已经预知hashmap中元素的个数,那么预设元素的个数能够有效的提高hashmap的性能。
举例:我们有1000个元素new HashMap(1000),但是理论上说new HashMap(1024)更适合,即使是1000,hashmap也会自动设置为1024,但是这也不是最适合的,因为0.75 * 1000 < 1000,也就是说为了让0.75 * size > 1000 ,我们必须设置为new HashMap(2048)才最合适,避免了resize的问题。

参考文章:

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值