Java中简单易懂的HashMap面试题(面试必备)

   日期:2020-05-30     浏览:100    评论:0    
核心提示:这篇文章仅限小编个人的理解,小编不是Java方向的,只是对Java有很高的学习兴趣如果有什么不对的地方还望大佬指点HashMap的底层是数组+链表,(很多人应该都知道了)JDK1.7的是数组+链表(1.7只是一个例子,以前的话也是这样后面就以1.7为例子了)首先是一个数组,然后数组的类型是链表元素是头插法JDK1.8的是数组+链表 或者 数组+红黑树首先是一个数组,然后数组的类型是链表在链表的元素大于8的时候,会变成红黑树在红黑树的元素小于6的时候会变成链表元素进行尾插HaspM.java

这篇文章仅限小编个人的理解,小编不是Java方向的,只是对Java有很高的学习兴趣
如果有什么不对的地方还望大佬指点

HashMap的底层是数组+链表,(很多人应该都知道了)
JDK1.7的是数组+链表
(1.7只是一个例子,以前的话也是这样后面就以1.7为例子了)
首先是一个数组,然后数组的类型是链表
元素是头插法
JDK1.8的是数组+链表 或者 数组+红黑树
首先是一个数组,然后数组的类型是链表
在链表的元素大于8的时候,会变成红黑树
在红黑树的元素小于6的时候会变成链表
元素进行尾插

HaspMap的数组默认大小为16
数组也叫做Hash桶
(貌似听说这个值和阿里巴巴Java开发手册好像有点关系)

HashMap元素的下标是
HashCode(元素) & (数组的长度-1)

HashMap的扩容 Resize

扩容的话,这里有一个值叫做loadFactor(阈值),默认值为0.75;
当数组的 元素数量>数组大小(默认16)* loadFactor(默认0.75)
就会触发扩容,扩容是二倍扩容的 (默认是16扩容后就是32)
这时原来每个元素的下标也会改变的(因为数组的长度变了)
然后就要把每个元素重新分配下标,重新加入链表或者红黑树

HashMap线程不安全
在put的时候,Resize(扩容)会造成数据的覆盖
JDK1.7 因为是头插法,可能会造成循环链表
JDK1.8 是尾插法

使用HashMap怎么才能让他线程安全
使用ConcurrentHashMap,
JDK1.7的是分段数组,有Segment锁(继承于ReentrantLock)加速一小段保证并发
JDK1.8 是和HashMap一样了,数组+链表(或者红黑树)
Synchronized(锁)and CAS(compare and swap)
(JVM在1.6对Synchronize的优化很好)
CAS通俗易懂,比较并替换
(CAS是一种无锁算法,CAS有3个操作数,内存值V,旧的预期值A,要修改的新值B。当且仅当预期值A和内存值V相同时,将内存值V修改为B,否则什么都不做)
(无锁化的修改值的操作,他可以大大降低锁代理的性能消耗。这个算法的基本思想就是不断地去比较当前内存中的变量值与你指定的 一个变量值是否相等,如果相等,则接受你指定的修改的值,否则拒绝你的操作。因为当前线程中的值已经不是最新的值,你的修改很可能会覆盖掉其他线程修改的结果。这一点与乐观锁,SVN的思想是比较类似的)

使用HashTable(基本是废弃的)
HashTable就是把HashMap套上了一个Synchronized

Collections.synchronizedMap()包装
使用synchronized 加上,但是这个是对某个Hash桶(数组的某个值)加锁,并不是整个map加锁,在锁定的时候别的线程也可以进行访问

小编暂时就了解这个多了,有什么遗漏的还望大佬评论

 
打赏
 本文转载自:网络 
所有权利归属于原作者,如文章来源标示错误或侵犯了您的权利请联系微信13520258486
更多>最近资讯中心
更多>最新资讯中心
更多>相关资讯中心
0相关评论

推荐图文
推荐资讯中心
点击排行
最新信息
新手指南
采购商服务
供应商服务
交易安全
关注我们
手机网站:
新浪微博:
微信关注:

13520258486

周一至周五 9:00-18:00
(其他时间联系在线客服)

24小时在线客服