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之后是因为加入了红黑树使用尾插法,能够避免出现逆序且链表死循环的问题。
    死循环形成示意图:

  • 扩容后数据存储位置的计算方式也不一样:
    1. 在JDK1.7的时候是直接用hash值和需要扩容的二进制数进行&(这里就是为什么扩容的时候为啥一定必须是2的多少次幂的原因所在,因为如果只有2的n次幂的情况时最后一位二进制数才一定是1,这样能最大程度减少hash碰撞)(hash值 & length-1)
    2. 而在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原理分析,大厂面试题相关推荐

  1. Android面试题--HashMap原理分析

    目录 一.序言 二 .HashMap原理分析 二.HashMap和Hashtable区别? 一.序言 作为Android程序员,出去找工作面试,HashMap应该是最常被问到的一种数据类型.那它是怎么 ...

  2. HashMap原理分析

    HashMap 原理分析 文章目录 HashMap 原理分析 1.HashMap结构 2.散列哈希 3.容量table的计算 4.索引映射 5.put流程 6.扩容机制 HashMap 的原理在我们使 ...

  3. android安装教程!深入理解Flutter动画原理,大厂面试题汇总

    背景 知乎客户端中有一个自己维护的 Hybrid 框架,在此基础上开发了一些 Hybrid 页面,当需要前端或者客户端开发接口的时候,就涉及到联调的问题. 和一般的 前端 <=> 服务端, ...

  4. HashMap原理分析及性能优化

    文章目录 一.HashMap是什么 二.HashMap继承类对比分析 三.HashMap源码相关单词含义 四.HashMap如何确定哈希桶数组索引位置 五. HashMap 的 put 方法分析 六. ...

  5. 【Java】HashMap原理及相关面试题

    HashMap与Hashtable两个类都是通过Key-Value对存储的数据结构. 根据官方的说法,二者唯二的区别是HashMap线程不安全而Hashtable线程安全,并且HashMap允许nul ...

  6. C语言异或交换两个数的原理解析-大厂面试题:不使用第三变量交换两个数的值

    常用操作交换两个数的值 常用的交换两个数值的方法一般是采用第三个变量,这种方法简单易懂,用代码举例 int main() {//交换两个整形变量int a = 3;int b = 5;int c = ...

  7. 2022最全的BAT大厂面试题整理及分析

    又是一年的金三银四,又到了面试求职高峰期,最近有很多网友都在求大厂面试题.正好我之前电脑里面有这方面的整理,于是就发上来分享给大家. 这些题目是网友去百度.小米.乐视.美团.58.猎豹.360.新浪. ...

  8. 总结2022最全的BAT大厂面试题整理及分析

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-k1qxiskF-1660644075912)(https://upload-images.jianshu.io/uplo ...

  9. Hashmap 原理、源码、面试题(史上最全)

    文章很长,建议收藏起来慢慢读!疯狂创客圈总目录 语雀版 | 总目录 码云版| 总目录 博客园版 为您奉上珍贵的学习资源 : 免费赠送 :<尼恩Java面试宝典>持续更新+ 史上最全 + 面 ...

最新文章

  1. GIS栅格数据集学习
  2. Java实现冒泡排序及其优化
  3. C++指针地址内存,数据结构,文件操控
  4. 网站运维技术与实践之服务器监测常用命令
  5. 【BZOJ】 3238: [Ahoi2013]差异
  6. oracle的group by用法
  7. 从零搭建nginx服务器
  8. WebDev.WebServer.exe遇到问题需要关闭
  9. 图文详解 Windows 2003服务器集群安装(1)
  10. redis 删除key的命令_面试官问:Redis变慢了,你会怎么排查?
  11. deepsort报错 No module named ‘sklearn.utils.linear_assignment_‘ 问题解决
  12. php砸金蛋程序,简单的几句PHP生成美团3周年砸金蛋抽奖代码
  13. 微分销机制设计_免费快速搭建微信分销商城_OctShop源码
  14. Unity 下载 国际版 去壳版,有网就行,下载不下来你打我。
  15. 【MarkDown】基础语法
  16. 地理信息系统和计算机系统的区别,GIS与其他信息系统的区别
  17. html标签(段落标签,换行标签,文本格式化标签和局部标签)-小白学习中
  18. 机器学习笔记(3.1)
  19. DNSPod十问花生壳陈宇晔:远程办公领域的下一个“独角兽”?
  20. OpenDDS开发人员指南中文版3.23(1)简介

热门文章

  1. nohup+oracle,nohup命令
  2. Linux cp命令详解
  3. 如何学习使用 Axure?
  4. AI-X 之 Gchip5801
  5. 云队友丨什么能力可以让你的人生拥有“无限可能”?
  6. 「 Offer收割机之JVM」:生存还是毁灭
  7. LiveGBS国标GB/T28181视频流媒体平台接入海康大华宇视监控摄像头硬件NVR通道0无法获取视频通道时候如何处理
  8. 14-Javaweb-jdbc案例(简单的curd 分页)
  9. 用python编写一段代码,实现数据对调
  10. tiny4412 uboot 2020.10版本移植(四)——uboot修改支持sd卡、eMMC引导内核及其他一些杂项设置