面试集锦(十二)hashMap

HashMap原理与优化

hashmap

底层是基于数组+链表实现的,真正存放数据的是entry<k,v>的数组

hashmap如何解决碰撞问题

当不同的对象发生碰撞时,HashMap通过单链表来解决,将新元素加入<链表>表头(头插法),通过next指向原有的元素。单链表在Java中的实现就是对象的引用(复合)。

put方法

  1. 判断当前数组是否需要初始化
  2. 如果key为空,则put一个空值进去
  3. 根据key算出hashcode
  4. 根据hashcode定位所在的桶(链表)
  5. 如果桶是链表要遍历里面的hashcode和key和传入的key是否相等,相等则覆盖,并返回原来的值
  6. 如果桶是空的,说明当前位置没有数据,则新增一个entry对象写入当前位置

get方法

  1. 根据key来算出hashcode,然后定位到具体的桶中
  2. 判断该位置是否是链表
  3. 不是链表就根据key,key的hashcode是否相等来返回值
  4. 如果是链表则需要遍历知道key及hashcode相等时候返回值
  5. 啥都没有就返回null

jdk1.8做的优化

对大链表进行了优化,超过阈值后将链表修改为红黑树后查询效率大大增加(当链表较长时转为将链表红黑树),未优化之前是o(n),优化后是o(log n)

会出现的问题

jdk没有对它进行任何的同步操作,所以会出现并发访问的问题,甚至会出现死循环导致系统不可用

解决办法

concurrenHashMap(guava中的cache采用的就是这个)

concurrentHashMap

原理:concurrenthashmap采用了分段锁技术,其中segment继承于reentrantlock。每当一个线程占用锁访问一个segment时,不会影响到其他的segment

jdk1.7和1.8的不同

1.7采用了分段锁,1.8取消了分段锁,改用CAS + synchronized来保证并发安全性

1.8之后在数据结构上做了改动,超过阈值后采用红黑树保证了查询效率,甚至取消了reentrantlock(可重入锁),改成synchronized


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值