HashMap的常见问题
关于HashMap的一些常见的问题,自己总结一下:
首选HashMap在jdk1.7和jdk1.8里面的实现是不同的,在jdk1.7中HashMap的底层实现是通过数组+链表的形式实现的,在jdk1.8中HashMap的底层是通过数组+链表+红黑树来实现的。
Question1: 数组链表是怎么切换的(1.7)?
答:在put的时候采用hash(key)&(len-1)来计算数据存放的index,以此存放元素。当出现哈希冲突的时候,因为有限的数组长度,遭遇哈希冲突,此时就可以使用链表来存储哈希值相同但是值不同的对象。
Question2:Entry节点如何插入链表(1.7)?
答: Entry节点插入链表是使用头插法来实现的,主要的实现是通过其CreateEntry来实现的,Entry的构造方法中可以协助头插的顺利进行,使用头插法是考虑到热点数据的问题,当时的想法是最近插入的元素,最近也可能被使用,头插入的实现可以缩短链表查找元素的时间。
Question3:jdk1.8以后为什么改用尾插入?
答:根据initialCapacity*LoadFactoor=capacity以后,如果插入的元素容量达到了capacity,此时会进行扩容,扩容操作按照源码中的写法,主要有两步:1.扩容一个新的Entry,容量为原来的两倍。2.进行Rehash操作,将原来的数据复制到新的Entry中。(1.7)如果是头插入的话,当多线程处理的时候,此时如果存在a->b->c链表,当我们rehash以后,有可能变为b->a,然而其他的线程处理完之后,结果可能会造成b->a->b,造成loop成环。一旦寻找数据会造成死循环。
而1.8以后改成尾插入以后,源码中使用了一个高位来识别之前的数据和插入的新数据,保持了之前的顺序,解决了1.7中可能造成成环的问题。具体的实现是扩容只有最高位会多出一个1,如果之前的数据一旦e & oldCapacity = 0,表明是原来的数据,保持就好,如果是为1,表明是即将插入的新数据,此时保持插入高位,这样就避免了成环的问题。
Question4:为什么要进行Rehash操作?
答: 因为此时的长度遍历按照index=hashcode & (len - 1)的计算,此时的规则变了,所以需要进行rehash操作。
Question5:HashMap为什么不是线程安全?
答:在jdk1.7中即使不出现死循环,由于put操作未加锁,我们也不能确保对于多个线程同时执行put操作时,上一秒修改完的put的值,下一秒get是否是修改后的值,容易被其他线程的值所覆盖,线程安全无法保证(1.7&1.8都是如此)
Question6:为啥源码的容量初始化大小为16?
答:在源码中有个方法叫做tableSizeFor(),这个方法是为了将当前的容量扩容到一个距离当前容量的2的整次方幂。阿里巴巴手册上也建议使用HashMap需要设置一个初始化的容量值,一般来说是设置为16,为什么是16而不是8或者4,因为4或者8容易导致hashMap扩容,影响性能。只要输入的HashCode分布是相对均匀的,那么hash算法就是均匀的,所以给16主要也是为了实现均匀分布。
Question7:为啥重写equals方法的同时需要重写hashCode方法?使用HashMap举例子说明?
答: 首先,equals方法继承了Object的equals方法,比较的对于值对象比较的是两个对象的值是否相等,对于引用对象比较的是两个对象的内存地址是否相等。上面也说到HashMap是通过hash(key)&(len-1)去寻找index的,index相同就形成链表存储数据,但是假如一个index中存储了object1、object2对象,他们的hash值相同,此时如果我们get数据object2,get(key)此时将会有两个值,你怎么能确保获取到的是object2而不是object1,此时就需要使用equals来比较对象的key是否相同,这样才可以获取到对的对象。实质上在底层get方法的实现是通过getNode(hash(key),key)来实现的,前面的是hash值,后面的是equals对比的对象。
Question8:HashMap线程不安全不适合多线程,那用什么可以替代?
答:可以使用HashTable或者ConcurrentHashMap来替代HashMap,但是HashTable仅仅是使用synchronized来实现同步锁,从而使得线程安全,但是并发度不高。所以一般使用ConcurrentHashMap来替代
Question9:为什么在1.8中当链表长度为8时转换为红黑树,数据长度为6时转化为链表?
答: 首先从时间复杂度方面来分析的话,当长度为6时查找的平均长度为6/2=3,(底层会判断偏后还是偏前,以此来从后或者从前遍历),而红黑数log6=2.6,如果为8的时候,此时8/2=4,而log8为3,至于具体这样选,是一种空间和时间的权衡。
HashMap的常见问题的更多相关文章
- HashMap实现原理及常见问题
1.简介 HashMap是基于哈希表的Map接口的实现,用来存放键值对(Entry<Key,Value>),并提供可选的映射操作.使用put(Key,Value)存储对象到HashMap中 ...
- hashMap常见问题
[解析hashMap的源码实现] 点击进入hashMap的源码实现 0.谈谈对hashMap的理解? 从底层结构.存取.扩容.冲突.实现原理.源码等方面说明. 1.你知道哪些常用的Map集合 ...
- HashMap底层实现原理及面试常见问题
HashMap底层源码分析 1.HashMap底层采用的存储结构 1.在JDK1.7及之前采用的存储结构是数组+链表 2.到了JDK1.8之后采用的是数组+链表+红黑树 2.HashMap实现的原理 ...
- (转)Java集合框架:HashMap
来源:朱小厮 链接:http://blog.csdn.net/u013256816/article/details/50912762 Java集合框架概述 Java集合框架无论是在工作.学习.面试中都 ...
- JAVA hashmap知识整理
HashMap和Hashtable的比较是Java面试中的常见问题,用来考验程序员是否能够正确使用集合类以及是否可以随机应变使用多种思路解决问题.HashMap的工作原理.ArrayList与Vect ...
- [Java集合] 彻底搞懂HashMap,HashTable,ConcurrentHashMap之关联.
注: 今天看到的一篇讲hashMap,hashTable,concurrentHashMap很透彻的一篇文章, 感谢原作者的分享. 原文地址: http://blog.csdn.net/zhanger ...
- Android WebView常见问题及解决方案汇总
Android WebView常见问题解决方案汇总: 就目前而言,如何应对版本的频繁更新呢,又如何灵活多变地展示我们的界面呢,这又涉及到了web app与native app之间孰优孰劣的争论. 于是 ...
- HashMap总结
最近朋友推荐的一个很好的工作,又是面了2轮没通过,已经是好几次朋友内推没过了,觉得挺对不住朋友的.面试反馈有一方面是有些方面理解思考的还不够,平时也是项目进度比较紧,有些方面赶进度时没有理解清楚的后面 ...
- Maven使用常见问题整理
Maven使用常见问题整理 1.更新eclipse的classpath加入新依赖 1.在dependencyManagement里面加入包括版本在内的依赖信息,如: <dependenc ...
随机推荐
- 单元测试JUnit案例
被测试模块 package packagedemo; public class Largest { public int minimal(int [] array1) { int index = 0 ...
- Spring 框架常用语法进行总结
Spring 框架常用语法进行总结: spring框架的二大主要的功能就是IOC和AOP. IOC: 控制反转(依赖注入) AOP: 面向切面编程 学习spring最好的方法就是去看官网,里面有详细的 ...
- java笔试面试第一天
好久未曾启用我的博客,最近来上海找工作,想将笔试面试的过程做个记录,毕竟有总结才有提高嘛.今天算是笔试面试正式开始第一天吧,以下就是我的笔试总结(没有原题了,只有知识点): 笔试题1:java sta ...
- 三石之道之Ansible自动化运维工具部署
centos6默认python版本为2.6 centos7默认python版本为2.7 ansible需要最低python2.7的支持 总结:centos6要部署ansible工具,需要先升级pyth ...
- 本地Git连接GitLab(服务器)远程仓库
1.简介 远程仓库是指托管在网络上的项目仓库,现在互联网上有很多项目托管平台,比如github.gitlab等.为了不公开自己项目代码,可以在自己的服务器上搭建自己的项目仓库,最常见的是搭建GitLa ...
- thinkphp 6.0 在 initialize 中重定向无效
thinkphp 6.0 在 initialize 中重定向无效 改用 header() 函数 实例: // header('location:/index.php/模块/控制器/方法'); head ...
- nyoj 655-光棍的yy (python, 未A)
655-光棍的yy 内存限制:64MB 时间限制:1000ms 特判: No 通过数:4 提交数:7 难度:2 题目描述: yy经常遇见一个奇怪的事情,每当他看时间的时候总会看见11:11,这个很纠结 ...
- 【前端知识体系-CSS相关】CSS特效实现之Transition和Transform对比
CSS效果 1.使用div绘制图形(三角形)? <!DOCTYPE html> <html lang="en"> <head> <meta ...
- PHP产生不重复随机数的5个方法总结
无论是Web应用,还是WAP或者移动应用,随机数都有其用武之地.在最近接触的几个小项目中,我也经常需要和随机数或者随机数组打交道,所以,对于PHP如何产生不重复随机数常用的几种方法小结一下 无论是We ...
- 构思一个在windows下仿objc基于动画层ui编程的ui引擎
用c/c++编程有些年了,十个指头可以数齐,在涉入iOS objc开发后,有种无比舒服的感觉,尤其在UI开发上. 在QuartzCore.framework下动画和透明窗口等许多效果的事都变得那么方便 ...