1.HashMap简介

HashMap基于哈希表的Map接口实现,是以key-value存储形式存在。(除了不同步和允许使用 null 之外,HashMap 类与 Hashtable 大致相同。)
HashMap 的实现不是同步的,这意味着它不是线程安全的。它的key、value都可以为null。此外,HashMap中的映射不是有序的。在 JDK1.8 中,HashMap 是由 数组+链表+红黑树构成,新增了红黑树作为底层数据结构,结构变得复杂了,但是效率也变的更高效。

HashMap基于哈希思想,实现对数据的读写。当我们将键值对传递给put()方法时,它调用键对象的hashCode()方法来计算hashcode,然后找到bucket位置来存储值对象。当获取对象时,通过键对象的equals()方法找到正确的键值对,然后返回值对象。HashMap使用链表来解决碰撞问题,当发生碰撞时,对象将会储存在链表的下一个节点中。HashMap在每个链表节点中储存键值对对象。当两个不同的键对象的hashcode相同时,它们会储存在同一个bucket位置的链表中,可通过键对象的equals()方法来找到键值对。如果链表大小超过阈值(TREEIFY_THRESHOLD,8),链表就会被改造为树形结构。

1.2 HashMap数据结构

在 JDK1.8 中,HashMap 是由 数组+链表+红黑树构成,新增了红黑树作为底层数据结构,结构变得复杂了,但是效率也变的更高效。当一个值中要存储到Map的时候会根据Key的值来计算出他的

hash,通过哈希来确认到数组的位置,如果发生哈希碰撞就以链表的形式存储 在Object源码分析中解释过,但是这样如果链表过长来的话,HashMap会把这个链表转换成红黑树来存储。

HashMap的存储结构

2.类结构

我们来看一下类结构

在阅读源码的时候一直有个问题很困惑就是HashMap已经继承了AbstractMap而AbstractMap类实现了Map接口,那为什么HashMap还要在实现Map接口呢?同样在ArrayList中LinkedList中都是这种结构。

据 java 集合框架的创始人Josh Bloch描述,这样的写法是一个失误。在java集合框架中,类似这样的写法很多,最开始写java集合框架的时候,他认为这样写,在某些地方可能是有价值的,直到他意识到错了。显然的,JDK的维护者,后来不认为这个小小的失误值得去修改,所以就这样存在下来了。

  • Cloneable 空接口,表示可以克隆

  • Serializable 序列化

  • AbstractMap 提供Map实现接口

3.属性

初始化容量(必须是二的n次幂)

集合最大容量(必须是二的幂)

负载因子,默认的0.75

当链表的值超过8则会转红黑树(1.8新增)

当链表的值小于6则会从红黑树转回链表

当Map里面的数量超过这个值时,表中的桶才能进行树形化 ,否则桶内元素太多时会扩容,而不是树形化 为了避免进行扩容、树形化选择的冲突,这个值不能小于 4 * TREEIFY_THRESHOLD

table用来初始化(必须是二的n次幂)

用来存放缓存

HashMap中存储的数量

用来记录HashMap的修改次数

用来调整大小下一个容量的值计算方式为(容量*负载因子)

哈希表的加载因子

重点属性

  • table在JDK1.8中我们了解到HashMap是由数组加链表加红黑树来组成的结构其中table就是HashMap中的数组

  • size为HashMap中K-V的实时数量

  • loadFactor加载因子,是用来衡量 HashMap 满的程度,计算HashMap的实时加载因子的方法为:size/capacity,而不是占用桶的数量去除以capacity。capacity 是桶的数量,也就是 table 的长度length。

  • threshold计算公式:capacity * loadFactor。这个值是当前已占用数组长度的最大值。过这个数目就重新resize(扩容),扩容后的 HashMap 容量是之前容量的两倍

4.构造方法

4.1 HashMap()

构造一个空的 HashMap ,默认初始容量(16)和默认负载因子(0.75)。

4.2 HashMap(int initialCapacity)

构造一个空的 HashMap具有指定的初始容量和默认负载因子(0.75)。

4.3 HashMap(int initialCapacity, float loadFactor)

构造一个空的 HashMap具有指定的初始容量和负载因子。我们来分析一下。

最后调用了tableSizeFor

转载于:https://www.cnblogs.com/slfeng/p/11193858.html

HashMap(摘)相关推荐

  1. HashMap 在并发下可能出现的问题分析!

    我们都知道,HashMap在并发环境下使用可能出现问题,但是具体表现,以及为什么出现并发问题,可能并不是所有人都了解 这篇文章记录一下HashMap在多线程环境下可能出现的问题以及如何避免. 在分析H ...

  2. 多线程下HashMap的死循环

    https://blog.csdn.net/dingjianmin/article/details/79780350 Java的HashMap是非线程安全的.多线程下应该用ConcurrentHash ...

  3. HashMap多线程并发问题分析

    2019独角兽企业重金招聘Python工程师标准>>> 并发问题的症状 多线程put后可能导致get死循环 从前我们的Java代码因为一些原因使用了HashMap这个东西,但是当时的 ...

  4. Java HashMap的死循环问题

    看到过很多CPU被100%的线上故障,并且这个事发生了很多次,原因是在Java语言在并发情况下使用HashMap造成Race Condition,从而导致死循环.这个事情我4.5年前也经历过,本来觉得 ...

  5. Java基础:详解HashMap在多线程下不安全

    今天想知道HashMap为什么在多线程下不安全,找了许多资料,终于理解了. 首先先了解一下HashMap: HashMap实现的原理是:数组+链表 HashMap的size大于等于(容量*加载因子)的 ...

  6. Java HashMap的死循环

    http://coolshell.cn/articles/9606.html 问题的症状 从前我们的Java代码因为一些原因使用了HashMap这个东西,但是当时的程序是单线程的,一切都没有问题.后来 ...

  7. 【集合之HashMap】HashMap实现原理及非线程安全原因

    要知道HashMap是什么,首先要搞清楚它的数据结构,在Java编程语言中,最基本的结构就是两种,一个是数组,另外一个是模拟指针(引用),所有的数据结构都可以用这两个基本结构来构造的,HashMap也 ...

  8. java温故笔记(二)java的数组HashMap、ConcurrentHashMap、ArrayList、LinkedList

    为什么80%的码农都做不了架构师?>>>    HashMap 摘要 HashMap是Java程序员使用频率最高的用于映射(键值对)处理的数据类型.随着JDK(Java Develo ...

  9. JDK源码分析(5)之 HashMap 相关

    HashMap作为我们最常用的数据类型,当然有必要了解一下他内部是实现细节.相比于 JDK7 在JDK8 中引入了红黑树以及hash计算等方面的优化,使得 JDK8 中的HashMap效率要高于以往的 ...

最新文章

  1. mybatis-plus入坑指南
  2. 条件随机场(conditional random fields) 及代码实现
  3. Bootstrap 栅格 样式 组件 插件
  4. 共克时艰:科技助力湖北地区银行业务线上转型
  5. 第十二章:二叉查找树(1)
  6. DatagramSocket总是发送UDP数据后无法接收数据
  7. 用shell编写一个三角形图案
  8. LOAM_velodyne学习(四)
  9. 使用Kotlin开发Android应用 - 环境搭建 (1)
  10. day01『NLP打卡营』实践课1:词向量应用演示
  11. Python开发【第五篇】迭代器、生成器、递归函数、二分法
  12. 【成长之路】【python】python基础2
  13. 可以掉落和滑动的星星
  14. linux是一个类似unix操作系统,3种与Linux类似的UNIX操作系统
  15. ros各级授权的区别
  16. 修改移动硬盘盘符(G盘--E盘)
  17. 135编辑器代码是html吗,不会代码,你也能做背景样式!!!
  18. 债券收益率预测模型_利率预测模型系列之一:简单的N-S模型运用
  19. java 去掉图片水印文字_Java实现图片水印工具类
  20. 关键词、词库、关键词词库

热门文章

  1. python_线程、进程和协程
  2. 感动要哭 撸了一个半小时的重载预算符高精
  3. HDU4267(2012年长春站)
  4. Swift学习字符串、数组、字典
  5. EditText 空指针问题
  6. USACO 3.3.2 Shopping Offers解题报告
  7. uni-app 组件传值
  8. 2 中间件的使用、异步action的创建
  9. ES6-6 - this指向、箭头函数基本形式、rest运算符
  10. P2685 [TJOI2012]桥