HashMap原理分析,大厂面试题
HashMap的工作原理是什么?
HashMap内部是通过一个数组实现的,只是这个数组比较特殊,数组里存储的元素是一个Entry实体(在Java8中为Node),这个Entry实体主要包含Key、value以及一个指向自身的next指针。
static class Node<K,V> implements Map.Entry<K,V> {final int hash;final K key;V value;Node<K,V> next;
}//也就是说这个数组每个元素都是单向链表
HashMap是基于hashing实现的,当进行put操作时,根据传递的key值得到它的hashcode,然后再用这个hashcode与数组的长度进行模运算,得到一个int值,就是Entry要存储在数组的位置(下标);
当通过get方法获取指定的key的值时,会根据这个key算出它的hash值(数组下标),根据这个hash值获取数组下标对应的Entry,然后判断Entry里的key,hash值或者通过equals()比较是否与要找的相同,如果相同,返回value,否则遍历该链表(有可能只有一个Entry,此时直接返回null),直到找到为止,否则返回null。
HashMap之所以在每个数组元素存储的是一个链表,是为了解决hash冲突问题,当两个对象的hash值相等时,那么一个位置肯定是放不下两个值的,于是hashmap采用链表解决这冲突,hash值相等的两个元素会形成一个链表。在Java8中,如果一个位置中碰撞冲突的元素超过某个限制(默认是8),则使用红黑树来替换链表,从而提高速度。
HashMap的长度为什么是2的幂次方?
HashMap为了存取的高效,要尽量减小碰撞冲突,就是要尽量把数据分配均匀,每个链表长度大致相同,这个实现就是把数据存到哪个链表中的算法;这个算法实际就是取模,hash%length,计算机中直接求余效率不如位移运算,源码中做了优化hash%(length-1),而hash%length==hash&(length-1)的前提是:length是2的幂次方。
HashMap与Hashtable的区别是什么?
- Hashtable继承Dictionary类,而HashMap继承AbstratMap。Dictionary是任何可将键映射到相应值的类的抽象父类,而AbstratMap是基于Map接口的实现,它以最大限度地减少实现此接口所需的工作。
- HashMap与Hashtable都实现了Map接口。
- HashMap允许键和值是null,Hashtable不允许键或者值是null。
- 线程安全不同,Hashtable的几乎所有函数都是同步的,即它是线程安全的,支持多线程。而HashMap的函数则是非同步的,它不是线程安全的。若要在多线程中使用HashMap,需要我们额外的进行同步处理。
- 迭代器(Iterator)。HashMap的迭代器是fail-fast迭代器,而Hashtable的enumerator迭代器不是fail-fast的。所以当有其他线程(非迭代器方法)改变了HashMap的结构(增加或移除元素),将会抛出java.util.ConcurrentModificationException异常。
- 容量的初始值和增加方式不一样;HashMap的默认容量大小是16,增加容量时,每次将容量变为“原始容量*2”,当Map中元素总数超过Entry数组的75%,触发扩容操作,减少链表长度,元素分配更均匀。Hashtable默认容量大小是11,增加容量时,每次将容量变为“原始容量*2+1”。
- 添加key-value时的hash估值算法不同:HashMap添加元素时,使用自定义的哈希算法;而Hashtable没有自定义哈希算法,直接采用key的hashCode()。
- 速度,由于Hashtable是线程安全的也是synchronized,所以在单线程环境下它比HashMap要慢。如果你不需要同步,自需要单一线程,那么使用HashMap性能要好过Hashtable。
能否让HashMap同步?
可以通过语句;
Map m = Collections.synchronizeMap(hashMap);
HashMap、Hashtable、ConccurentHashMap三者的区别:
HashMap线程不安全,数组+链表+红黑树
Hashtable线程安全,锁住整个对象,数组+链表
ConccurentHashMap线程安全,CAS+同步锁,数组+链表+红黑树
HashMap的key,value均可为null,其他两个不行。
ConcurrentHashMap在JDK1.7和JDK1.8中的区别:
在JDK1.8主要设计上的改进有以下几点:
1、不采用segment而采用node,锁住node来实现减小锁粒度。
2、设计了MOVED状态 当resize的中过程中 线程2还在put数据,线程2会帮助resize。
3、使用3个CAS操作来确保node的一些操作的原子性,这种方式代替了锁。
4、sizeCtl的不同值来代表不同含义,起到了控制的作用。
5、采用synchronized而不是ReentrantLock。
ConcurrentHashMap具体知识,可以看:
https://www.jianshu.com/p/5dbaa6707017
为什么 HashMap 中 String、Integer 这样的包装类适合作为 key 键?
Hashmap的结构,1.7和1.8有哪些区别?
- JDK1.7用的是头插法,而JDK1.8及之后使用的都是尾插法,那么他们为什么要这样做呢?因为JDK1.7是用单链表进行的纵向延伸,当采用头插法时会容易出现逆序且环形链表死循环问题。但是在JDK1.8之后是因为加入了红黑树使用尾插法,能够避免出现逆序且链表死循环的问题。
死循环形成示意图:
- 扩容后数据存储位置的计算方式也不一样:
- 在JDK1.7的时候是直接用hash值和需要扩容的二进制数进行&(这里就是为什么扩容的时候为啥一定必须是2的多少次幂的原因所在,因为如果只有2的n次幂的情况时最后一位二进制数才一定是1,这样能最大程度减少hash碰撞)(hash值 & length-1)
- 而在JDK1.8的时候直接用了JDK1.7的时候计算的规律,也就是:扩容前的原始位置+扩容的大小值=JDK1.8的计算方式,而不再是JDK1.7的那种异或的方法。但是这种方式就相当于只需要判断Hash值的新增参与运算的位是0还是1就直接迅速计算出了扩容后的储存方式。
在计算hash值的时候,JDK1.7用了9次扰动处理=4次位运算+5次异或,而JDK1.8只用了2次扰动处理=1次位运算+1次异或。
扩容流程:
添加数据流程:
具体区别:
本文参考文章:https://www.jianshu.com/p/8324a34577a0?utm_source=oschina-app
我是pavel,一位憨憨傻傻的程序员,平时幽默又有才,专注于Java,go,微服务,云开发。不定时发送些腾讯程序员的工作/生活日常,请大家多多关注我的公众号!
HashMap原理分析,大厂面试题相关推荐
- Android面试题--HashMap原理分析
目录 一.序言 二 .HashMap原理分析 二.HashMap和Hashtable区别? 一.序言 作为Android程序员,出去找工作面试,HashMap应该是最常被问到的一种数据类型.那它是怎么 ...
- HashMap原理分析
HashMap 原理分析 文章目录 HashMap 原理分析 1.HashMap结构 2.散列哈希 3.容量table的计算 4.索引映射 5.put流程 6.扩容机制 HashMap 的原理在我们使 ...
- android安装教程!深入理解Flutter动画原理,大厂面试题汇总
背景 知乎客户端中有一个自己维护的 Hybrid 框架,在此基础上开发了一些 Hybrid 页面,当需要前端或者客户端开发接口的时候,就涉及到联调的问题. 和一般的 前端 <=> 服务端, ...
- HashMap原理分析及性能优化
文章目录 一.HashMap是什么 二.HashMap继承类对比分析 三.HashMap源码相关单词含义 四.HashMap如何确定哈希桶数组索引位置 五. HashMap 的 put 方法分析 六. ...
- 【Java】HashMap原理及相关面试题
HashMap与Hashtable两个类都是通过Key-Value对存储的数据结构. 根据官方的说法,二者唯二的区别是HashMap线程不安全而Hashtable线程安全,并且HashMap允许nul ...
- C语言异或交换两个数的原理解析-大厂面试题:不使用第三变量交换两个数的值
常用操作交换两个数的值 常用的交换两个数值的方法一般是采用第三个变量,这种方法简单易懂,用代码举例 int main() {//交换两个整形变量int a = 3;int b = 5;int c = ...
- 2022最全的BAT大厂面试题整理及分析
又是一年的金三银四,又到了面试求职高峰期,最近有很多网友都在求大厂面试题.正好我之前电脑里面有这方面的整理,于是就发上来分享给大家. 这些题目是网友去百度.小米.乐视.美团.58.猎豹.360.新浪. ...
- 总结2022最全的BAT大厂面试题整理及分析
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-k1qxiskF-1660644075912)(https://upload-images.jianshu.io/uplo ...
- Hashmap 原理、源码、面试题(史上最全)
文章很长,建议收藏起来慢慢读!疯狂创客圈总目录 语雀版 | 总目录 码云版| 总目录 博客园版 为您奉上珍贵的学习资源 : 免费赠送 :<尼恩Java面试宝典>持续更新+ 史上最全 + 面 ...
最新文章
- GIS栅格数据集学习
- Java实现冒泡排序及其优化
- C++指针地址内存,数据结构,文件操控
- 网站运维技术与实践之服务器监测常用命令
- 【BZOJ】 3238: [Ahoi2013]差异
- oracle的group by用法
- 从零搭建nginx服务器
- WebDev.WebServer.exe遇到问题需要关闭
- 图文详解 Windows 2003服务器集群安装(1)
- redis 删除key的命令_面试官问:Redis变慢了,你会怎么排查?
- deepsort报错 No module named ‘sklearn.utils.linear_assignment_‘ 问题解决
- php砸金蛋程序,简单的几句PHP生成美团3周年砸金蛋抽奖代码
- 微分销机制设计_免费快速搭建微信分销商城_OctShop源码
- Unity 下载 国际版 去壳版,有网就行,下载不下来你打我。
- 【MarkDown】基础语法
- 地理信息系统和计算机系统的区别,GIS与其他信息系统的区别
- html标签(段落标签,换行标签,文本格式化标签和局部标签)-小白学习中
- 机器学习笔记(3.1)
- DNSPod十问花生壳陈宇晔:远程办公领域的下一个“独角兽”?
- OpenDDS开发人员指南中文版3.23(1)简介
热门文章
- nohup+oracle,nohup命令
- Linux cp命令详解
- 如何学习使用 Axure?
- AI-X 之 Gchip5801
- 云队友丨什么能力可以让你的人生拥有“无限可能”?
- 「 Offer收割机之JVM」:生存还是毁灭
- LiveGBS国标GB/T28181视频流媒体平台接入海康大华宇视监控摄像头硬件NVR通道0无法获取视频通道时候如何处理
- 14-Javaweb-jdbc案例(简单的curd 分页)
- 用python编写一段代码,实现数据对调
- tiny4412 uboot 2020.10版本移植(四)——uboot修改支持sd卡、eMMC引导内核及其他一些杂项设置