数据结构

hm的数据结构是数组加链表,插入数据的话,先对数据计算一个哈希值,然后用这个哈希值去对数组的大小减1来取模,算出来的数就是存在数组里的位置,如果这个位置已经有数据了,这就是哈希碰撞问题,hm会用equls方法对这个数据的值和数组里的值进行比较,如果这个数据已经做了链表,就挨个比较,只有equls结果全为false,才会进行插入,1.8之前呢就是直接用一个链表来保存这种碰撞的数据,jdk1.8做了优化,当链表长度超过8的时候就会升级为红黑树,时间复杂度为O(logn),这个就是hm的数据结构的情况。

寻址算法优化

jdk还对hashmap的寻址算法进行了优化,先看1.8求hash值得源码

这里用哈希值和它自己右移16位的值进行异或运算的原因是,因为数组大小前16位一般都是0,这样hash和数组大小进行寻址计算的时候前16位结果都是0,相当于前16位没有参与运算,这样会增大hash冲突的概率,这里做一下异或处理就可以让hash前16位也参与寻址运算,减小冲突概率。jdk1.8使用(n-1)&hash计算出数组的一个位置来代替之前的hash%(n-1),因为与运算与取模的结果一致,但是前者性能比后者强。

扩容机制

hashmap的容量默认是16

/*** The default initial capacity - MUST be a power of two.*/static final int DEFAULT_INITIAL_CAPACITY = 1 << 4; // aka 16

hashmap定义了一个加载因子,它的默认值是0.75

/*** The load factor used when none specified in constructor.*/static final float DEFAULT_LOAD_FACTOR = 0.75f;

当HashMap中元素数超过容量*加载因子时,HashMap会进行扩容。扩容的方法是创建一个新table,大小和原来一样,再合并起来,这样扩容之后大小变为两倍。

1.8以前采用的是头插法来扩容,这样在多个线程同时进行插入,触发扩容机制,就有可能形成环状节点,导致死循环。

1.8之后的扩容方式是创建一个新table,长度是原来的两倍,然后循环把原来的元素放入新table中,这里会重新对每个hash寻址,称作rehash,它计算的结果是要么和之前一样,要么等于之前的值加上旧数组的长度。

线程安全

前面提到了hashmap会有线程安全问题,解决线程安全的问题一般有三种,用Synchronized或者Reentrantlock加锁,还可以采用ConcurrentHashMap。

ConcurrentHashMap

ConcurrentHashMap是一种线程安全的hashmap,它的内部采用分段锁来实现,在jdk1.7采用的segment继承了ReentrantLock实现加锁的功能,一个segment里面有一个小的hashmap,而在1.8中采用的synchronized+CAS保证线程安全,没有使用分段锁。

一般会继续追问并发的一些知识点,比如Synchronized的原理,CAS,AQS

java基础之HashMap刨根问底相关推荐

  1. 【Java基础】HashMap原理详解

    [Java基础]HashMap原理详解 HashMap的实现 1. 数组 2.线性链表 3.红黑树 3.1概述 3.2性质 4.HashMap扩容死锁 5. BATJ一线大厂技术栈 HashMap的实 ...

  2. java中 hashmap中小数,java基础知识--HashMap中对 h(length-1)的理解

    1.HashMap 数组下标计算方式: (h 是k的hashcode值:length是数组长度,HashMap数组默认长度是16) 2.&是什么意思? &在 java 中做与运算,&a ...

  3. Java基础:HashMap的用法

    数组中出现次数超过一半的数字 数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字.例如输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}.由于数字2在数组中出现了5次,超过数组长度 ...

  4. java基础之 hashmap

    Hashmap是一种非常常用的.应用广泛的数据类型,最近研究到相关的内容,就正好复习一下.网上关于hashmap的文章很多,但到底是自己学习的总结,就发出来跟大家一起分享,一起讨论. 1.hashma ...

  5. 【Java基础】HashMap原理及常见面试题目

    HashMap是Java中最常用的类之一,使用它的时候,有很多小的细节需要大家注意.下面通过他的原理和一些面试题目进行讲解. Java7底层实现 java7中用 HashMap底层算法使用了数组加链表 ...

  6. 【Java基础】HashMap扩容 | CopyOnWriteArrayList 的底层原理 | 字节码 | Java 异常体系

    1. HashMap的扩容机制 JDK 1.7 扩容是针对数组进行扩容,链表是不需要进行扩容的.扩容时先生成原来数组两倍大小的新数组,在把原来老数组上的链表上的元素转移过去.具体在转移链表中元素的步骤 ...

  7. 【Java基础】HashMap底层数据结构及其原理

    1.简单了解一下HashMap HashMap 就是以 Key-Value 键值对的方式进行数据存储的一种数据结构,它在 JDK 1.7 和 JDK 1.8 中底层数据结构是有些不一样的.简单来说,J ...

  8. java基础篇 - HashMap 理解Hash碰撞

    HashMap是大家都在用,面试的时候也经常会被考的考点,在这篇文章中说下HashMap的hash碰撞和减轻碰撞的优化. 1.什么是hash碰撞 在解释Hash碰撞之前先说一下hashmap的存储结构 ...

  9. java基础之HashMap源码分析

    目录 1. HashMap原理分析 1.1. HashMap继承体系 1.2.Node数据结构分析 1.3.底层储存结构 1.3.1.put方法分析 1.4.hash碰撞 1.4.1.key值的唯一性 ...

最新文章

  1. mysql clomn_mysql 备份脚本
  2. mp4格式解析、分割
  3. java gc原理_Java内存管理以及GC工作原理
  4. java 调用父类的变量_java创建子类对象设置并调用父类的变量操作
  5. 【直播回放】新手如何入门并学习自然语言处理
  6. ABAP 对字符串公式进行计算
  7. BZOJ 4386 Luogu P3597 [POI2015]Wycieczki (矩阵乘法)
  8. 音视频封装格式、编码格式知识
  9. linux裸分区如何区分,Linux 裸设备基础知识
  10. bzoj2958: 序列染色3269: 序列染色
  11. Atitit oil painting article list sumup s55 C:\Users\Administrator\Desktop\油画技术资料包\Atitit Atitit 图像
  12. C#学生管理系统源代码
  13. clone git 修改保存路径_SEO优化知识一般需要了解什么代码_学云网
  14. ubuntu创建“新建文本文档”的快捷方式
  15. 微信Log日志分析——初步探索
  16. 第17章 其他数据库日志【4.日志与备份篇】【MySQL高级】
  17. Spring Security基于数据库认证用户登录
  18. 文件上传/JS/MIME/黑名单/白名单/htaccess/00截断详解篇[代码审计]
  19. Win7开启无线热点AP
  20. jira 切换 语言_JIRA中的标记语言的语法参考

热门文章

  1. python将一组数zscore归一化
  2. Python3|Opencv——dst参数的含义和使用
  3. 【新书推荐】崛起的超级智能:互联网大脑如何影响科技未来
  4. 什么是ASR、TTS?
  5. 三元催化器 - 汽车熄火后底盘金属砰砰响 / 啪啪啪 / 哒哒哒的声响 / 异响
  6. 为什么short类型取值范围为-32768~32767
  7. 高等数学——讲透求极限两大方法,夹逼法与换元法
  8. 数据库结构比对,再初始数据比对方法
  9. ceph(ceph是什么意思)
  10. python网络爬虫与信息提取北京理工大学ppt_Python网络爬虫与信息提取