HashMap在面试中经常被问到,今天就对hashMap的底层源码进行分析和解释

1.HashMap底层采用的存储结构

1.在JDK1.7及之前采用的存储结构是数组+链表

我们知道链表的优点是适合增删,但是存储的数据很多时查找的效率会很低,因此针对查找效率低的问题,对HashMap的存储结构进行了改进。

2.到了JDK1.8之后采用的是数组+链表+红黑树

保留了JDK1.7增删效率高的优点,由于增加了红黑树查找效率也提高了。
(1)首先解释一下什么是红黑树:红黑树是一个自平衡二叉树,查找效率很高。红黑树有以下几个特点:
1)每个节点只有两种颜色:红色或黑色
2)根节点必为黑色
3)每个叶子节点都是黑色的空节点
4)从根节点到叶子节点,不能出现两个红色的节点
5)从任一节点出发,到它下边的子结点的路径包含黑色节点数相同。

2.HashMap实现的原理

HashMap基于hashing的原理,通过提供put()和get()方法来存储和获取对象。

1.put()方法。

当把键值对的值传递给put()方法时,会调用hashCode()方法来计算hashcode,然后找到bucket位置来存储。

2.get()方法。

当要获取对象时,通过键对象的equals方法找到正确的键值对,然后返回值。HashMap使用链表来解决碰撞问题,当发生碰撞了,对象将会储存在下一个节点中。

3.HashMap源码分析

1.默认的初始化容量为16(2的n次幂),最大容量为2^30
2.默认的加载因子0.75,乘以数组容量得到的值用来表示元素个数达到多少时需要扩容

*0.75的原因:
(1)若小于0.75,如0.5,则数组长度达到一半大小就扩容,空间使用率降低;
(2)若大于0.75,如0.8,则会增大hash冲突的概率,影响查询的效率。
3.当链表的长度超过8时,转化为红黑树。
4.当红黑树上的元素个数减少到6个时就退化为链表;
5.链表转化为红黑树,除了有阈值的限制,还有一个限制:数组容量至少达到64,才会树化,这是为了避免数组扩容和树化阈值之间的冲突。
6.HashMap的源码如下(来源于知乎):

public class HashMap<K,V> extends AbstractMap<K,V> implements Map<K,V>, Cloneable, Serializable {
// 序列号
private static final long serialVersionUID = 362498820763181265L; // 默认的初始容量是16
static final int DEFAULT_INITIAL_CAPACITY = 1 << 4; // 最大容量:2^30,超过仍按2^30来算
static final int MAXIMUM_CAPACITY = 1 << 30; // 默认的填充因子(负载因子/加载因子)
static final float DEFAULT_LOAD_FACTOR = 0.75f; // 当桶(bucket)上的结点数大于这个值时会转成红黑树
static final int TREEIFY_THRESHOLD = 8; // 当桶(bucket)上的结点数小于这个值时树转链表
static final int UNTREEIFY_THRESHOLD = 6; // 桶中结构转化为红黑树对应的table的最小大小
static final int MIN_TREEIFY_CAPACITY = 64; // 存储元素的数组,总是2的幂次倍
transient Node<k,v>[] table; // 下面会分析结构源码 // 存放具体元素的集
transient Set<map.entry<k,v>> entrySet; // 存放元素的个数,注意这个不等于数组的长度。
transient int size; // 每次扩容和更改map结构的计数器
transient int modCount; // 临界值 当实际大小(容量*填充因子)超过临界值时,会进行扩容
int threshold; // 加载因子
final float loadFactor;
}

原文章:https://blog.csdn.net/weixin_48929324/article/details/112100700

HashMap底层实现原理及面试常见问题的更多相关文章

  1. 【转载】HashMap底层实现原理及面试问题

    ①HashMap的工作原理 HashMap基于hashing原理,我们通过put()和get()方法储存和获取对象.当我们将键值对传递给put()方法时,它调用键对象的hashCode()方法来计算h ...

  2. HashMap底层实现原理及面试问题

    ①HashMap的工作原理 HashMap基于hashing原理,我们通过put()和get()方法储存和获取对象.当我们将键值对传递给put()方法时,它调用键对象的hashCode()方法来计算h ...

  3. Java面试必问之Hashmap底层实现原理(JDK1.7)

    1. 前言 Hashmap可以说是Java面试必问的,一般的面试题会问: Hashmap有哪些特性? Hashmap底层实现原理(get\put\resize) Hashmap怎么解决hash冲突? ...

  4. HashMap底层实现原理/HashMap与HashTable区别/HashMap与HashSet区别(转)

    HashMap底层实现原理/HashMap与HashTable区别/HashMap与HashSet区别 文章来源:http://www.cnblogs.com/beatIteWeNerverGiveU ...

  5. Java面试必问之Hashmap底层实现原理(JDK1.8)

    1. 前言 上一篇从源码方面了解了JDK1.7中Hashmap的实现原理,可以看到其源码相对还是比较简单的.本篇笔者和大家一起学习下JDK1.8下Hashmap的实现.JDK1.8中对Hashmap做 ...

  6. HashMap底层实现原理/HashMap与HashTable区别/HashMap与HashSet区别

    ①HashMap的工作原理 HashMap基于hashing原理,我们通过put()和get()方法储存和获取对象.当我们将键值对传递给put()方法时,它调用键对象的hashCode()方法来计算h ...

  7. Java中HashMap底层实现原理(JDK1.8)源码分析

    这几天学习了HashMap的底层实现,但是发现好几个版本的,代码不一,而且看了Android包的HashMap和JDK中的HashMap的也不是一样,原来他们没有指定JDK版本,很多文章都是旧版本JD ...

  8. (转)HashMap底层实现原理/HashMap与HashTable区别/HashMap与HashSet区别

    ①HashMap的工作原理 HashMap基于hashing原理,我们通过put()和get()方法储存和获取对象.当我们将键值对传递给put()方法时,它调用键对象的hashCode()方法来计算h ...

  9. HashMap底层实现原理(JDK1.8)源码分析

    ref:https://blog.csdn.net/tuke_tuke/article/details/51588156 http://www.cnblogs.com/xiaolovewei/p/79 ...

随机推荐

  1. 深入浅出带你玩转sqlilabs(二)

    MYSQL高权限注入 mysql跨库注入 详情请看上一篇:深入浅出带你玩转sqlilabs(一) mysql文件操作注入-sqlilabs less7 可能用到的函数: into outfile()函 ...

  2. 【微信小程序】--bindtap参数传递,配合wx.previewImage实现多张缩略图预览

    本文为原创随笔,纯属个人理解.如有错误,欢迎指出. 如需转载请注明出处 在微信小程序中预览图片分为 a.预览本地相册中的图片. b.预览某个wxml中的多张图片. 分析:实质其实是一样的.都是给wx. ...

  3. Java 给Word添加数字签名

    本文以Java程序代码为例,介绍如何给Word文档添加数字签名. 程序运行环境 IntedliJ IDEA JDK 1.8.0 Jar包:spire.doc.jar 4.5.1 Word文档:.doc ...

  4. 段间跳转之TSS段

    TR寄存器,TSS描述符,TSS段 TR寄存器与普通的段寄存器一样都有可见部分和不可见部分.TR的可见部分为16位为其段选择子,不可见部分是32位的TSS基地址和16位的大小. TSS描述符存在GDT ...

  5. Java_继承

    继承的格式 继承它描述的是两个类之间的关系,如果一个子类继承父类,那么子类可以使用父类非私有的成员. 1 public class 父类{ 2 //成员变量 3 //成员方法 4 } 5 6 publ ...

  6. C++ primer plus读书笔记——第10章 对象和类

    第10章 对象和类 1. 基本类型完成了三项工作: 决定数据对象需要的内存数量: 决定如何解释内存中的位: 决定可使用数据对象执行的操作或方法. 2. 不必在类声明中使用关键字private,因为这是 ...

  7. 使用git rebase去掉无谓的融合

    git pull 預設的行為是將遠端的 repo. 與本地的 repo. 合併,這也是 DVCS 的初衷,將兩個 branch 合併.但是,很多時候會發生以下這種情形: 這是因為,我們團隊的開發模式是 ...

  8. ALPHA任务拆解

    项目 内容 这个作业属于哪个课程 BUAA2020软件工程 这个作业的要求在哪里 作业要求 我们在这个课程的目标是 学会团队合作,共同开发一个完整的项目 这个作业在哪个具体方面帮助我们实现目标 团队任 ...

  9. Taro使用多线程Worker相关问题解决

    JavaScript 语言采用的是单线程模型,HTML5标准中的Web Worker ,为 JavaScript 创造多线程环境.微信小程序也有相应的Worker,同样具备多线程运行的能力 主页面中创 ...

  10. 在Visual Studio 中使用git——浏览版本库(七)

    在Visual Studio 中使用git--什么是Git(一) 在Visual Studio 中使用git--给Visual Studio安装 git插件(二) 在Visual Studio 中使用 ...