本节用于记录Java HashMap底层数据结构、方法实现原理等,基于JDK 1.8。

# 底层数据结构

Java hashMap 是采用哈希表结构的(数组+链表 /jdk8后加入红黑树)实现,结合了数组和链表的优点,

1,数组优点:可以快速通过数组下标对数组元素操作,效率极高

2,链表优点:插入或删除元素不需要移动元素,只需要修改链表的引用,效率极高

hashMap图示如下:

hashMap内部使用数组储存数据,每个元素都是一个Node<k,v>

每个node 包含了hash,key,value,next 其中next表示下一个节点。

hashMap通过hash方法计算key的哈希码,然后通过公式计算key的下标。当数组中的下标存放一致时,数据将以链表的方式储存(hash冲突,hash碰撞)

我们知道,在链表中查找数据必须从第一个元素开始一层一层往下找,直到找到为止,时间复杂度为O(N),所以当链表长度越来越长时,HashMap的效率越来越低。

为了解决这个问题,JDK1.8开始采用数组+链表+红黑树的结构来实现HashMap。当链表中的元素超过8个(TREEIFY_THRESHOLD)并且数组长度大于64(MIN_TREEIFY_CAPACITY)时,会将链表转换为红黑树

HashMap包含几个重要的变量:

// 数组默认的初始化长度16
static final int DEFAULT_INITIAL_CAPACITY = 1 << 4; // 数组最大容量,2的30次幂,即1073741824
static final int MAXIMUM_CAPACITY = 1 << 30; // 默认加载因子值
static final float DEFAULT_LOAD_FACTOR = 0.75f; // 链表转换为红黑树的长度阈值
static final int TREEIFY_THRESHOLD = 8; // 红黑树转换为链表的长度阈值
static final int UNTREEIFY_THRESHOLD = 6; // 链表转换为红黑树时,数组容量必须大于等于64
static final int MIN_TREEIFY_CAPACITY = 64; // HashMap里键值对个数
transient int size; // 扩容阈值,计算方法为 数组容量*加载因子
int threshold; // HashMap使用数组存放数据,数组元素类型为Node<K,V>
transient Node<K,V>[] table; // 加载因子
final float loadFactor; // 用于快速失败,由于HashMap非线程安全,在对HashMap进行迭代时,如果期间其他线程的参与导致HashMap的结构发生变化了(比如put,remove等操作),直接抛出ConcurrentModificationException异常
transient int modCount;

  

最新文章

  1. spring Date JPA的主要编程接口
  2. 从零开始,教你用Webpack构建React基础工程
  3. Git远程操作
  4. 如何用ZBrush快速雕刻LOL中的Lissandra
  5. dede数据库类使用方法$dsql【转】
  6. 《HTML5与CSS3基础教程》学习笔记 ——One Day
  7. get的四种请求形式
  8. Xamarin Mono Android Ios 安装、破解(4.12)
  9. 10秒视频转局部GIF动画
  10. 转:Linux 内核中的 cdev_alloc和cdev_add
  11. 【Java每日一题】20170110
  12. [js高手之路]node js系列课程-创建简易web服务器与文件读写
  13. Udacity并行计算课程笔记-The GPU Hardware and Parallel Communication Patterns
  14. equals方法和==的区别--用实例简单说明
  15. 手机网页制作教程META标签你知道多少?【转+加】
  16. 演练:调试 Windows 窗体
  17. .net core 2.0+superui +Dapper.SimpleCRUD+mysql+NLog
  18. CodeForces912E 折半+二分+双指针
  19. ensembl数据库的使用方法
  20. JVM 发生OOM的四种情况

热门文章

  1. 9、IDEA回退Git版本
  2. 2022年7月10 第四组 周鹏 CSS的基本认识
  3. [python]《Python编程快速上手:让繁琐工作自动化》学习笔记4
  4. [编程基础] C++多线程入门10-packaged_task示例
  5. ansible离线安装k8s v1.25版本
  6. .Net开发的系统安装或更新时如何避免覆盖用户自定义的配置
  7. 全志V3S 调试串口更改或关闭
  8. 分布式拒绝服务攻击(DDoS)和僵尸网络(Botnet)
  9. 【Dubbo3终极特性】「流量治理体系」一文教你如何通过Dubbo-Admin实现动态进行流量隔离机制
  10. 一种面向业务配置基于JSF广播定时生效的工具