hashMap的底层原理

什么是hashMap

hashMap是一种集合,是Map的具体实现类。同事是一个用于存储key-value键值对的集合,每一个键值对也叫做Entry。

hashMap解决了什么问题

先上结论:解决了数组的增删慢的问题,解决了链表查询慢的问题。

解释:

        在hashMap之前有两大家族。

        1:数组

                特点:存储区间是连续的,占用内存严重,随机读取效率很高,因为带索引,并且数组是连续的。缺点:插入和删除效率太低,因为插入数据,这个位置后面的数据在内存中要往后移,且大小固定不适合动态扩展。

        2:链表

                特点:存储区间离散,占用内存宽松,插入删除速度块,扩展灵活。缺点:不能随机查找,每次都是从第一个遍历。

所以:哈希表就因此而诞生了,它实现了查询效率高,插入删除效率也高的功能点。而hashMap就是基于hash表实现的。

hashMap的底层实现原理

hashMap基于hashing(算列法或哈希法)原理,我们通过put()和get()方法存储和获取对象。

put():当我们将键值对传递给put()方法时,他的底层会调用key的hashcode()方法获得hash值,再通过hash算法将hash值转换成数组的下标,用于找到bucket位置来存储entry对象,如果下标位置没有任何元素,那就把当前对象添加到这个位置上,如果说下标对应的位置有元素,那就拿着key和链表上的每个节点的key进行equals,如果有相同的那就覆盖,没有相同的那就将这个新的节点添加到链表的末尾。

get():当我们获取对象时,先通过key的hashCode方法得到哈希值,并通过hash算法转换成数组的下标,并且获取bucket(桶)的位置,如果这个位置上什么都没有那就返回null,如果这个位置上有单向链表,那么就会拿着参数key和链表上的每个节点key比较,返回false那就是null,返回true那就 是我们要的value值。

hashMap和hashTable的的区别

1. hashMap是线程不安全的,hashTable是线程安全的

2. 由于hashTable线程安全 所以效率就比hashMap低

3. hashMap最多只允许一条记录的键为null,允许多条值为null,但是hashTable不可以

4. hashMap的默认初始化容量是16 hashTable是11 前者扩容2倍,后者扩容2倍+1

5. hashMap需要重新计算hash值,而hashTable直接使用对象的hashCode

无聊的知识点:       

1.随机增删,查询效率都很高的原因是?

增删是在链表上实现的,而查询只需要扫描部分,不需要全盘扫描

 2.为什么说JDK8以后哈希表不仅仅是用单向链表了。

        在JDK8以后,如果哈希表单向链表的元素超过8个,那么单向链表这种数据结构就会发生变化成红黑树结构,当红黑树上的节点数量小于6个,会重新把红黑树的结构转换成单向链表结构。目的就是优化查询效率。JDK8重写了resize()方法,将在多线程访问下头插法改为尾插法

 3.默认配置

hashMap的默认初始容量是16

默认加载因子:0.75f(当存储的数量 > hashMap的容量 * 负载因子)就会把hashMap原来的容量扩大到原来的二倍。

树化阈值:8(在添加元素时,当一个桶的存储元素的数量>8时,自动转换成红黑树)

链表阈值:6(在删除元素时,当一个桶的存储元素的数量<6时,自动转换成链表)

附:

        put方法流程图:

        get方法流程图:

        hashMap的扩容机制流程图:

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值