前言:当您在读该文章的时候,我认为您已经知道HashMap的底层实现原理,如果您还不清楚HashMap是如何实现的,请先去了解,再回来看本文章。

1.HashMap什么时候扩容?

HashMap的容量是有限的。当经过多次元素插入的时候,使得HashMap达到一定的饱和度,Key映射位置的几率不断变大。这个时候,HashMap就需要扩容了,也就是Resize。

影响发生Resize的因素有两个:

1)Capacity:HashMap的当前长度,HashMap的长度必是2的幂。

测试一下:

请问如下map的长度分别为多少呢?

  1. HashMap<String,String> map = new HashMap<String, String>();
  2. HashMap<String,String> map = new HashMap<String, String>(8);
  3. HashMap<String,String> map = new HashMap<String, String>(5);

答案:16 8 8 你答对了么?(原理很简单,就是HashMap的长度必是2的幂)

2)LoadFactor:HashMap负载因子,默认是0.75f。

当 HashMap.size >= Capacity*LoadFactor 时,HashMap就会进行Resize。

2.HashMap怎么扩容?

1)创建一个新的Entry空数组,长度是原来的2倍。

2)遍历原Entry数组,把所有的Entry重新Hash到新数组里。为什么要重新Hash呢?因为长度扩大以后,Hash的规则也随之改变了。

让我们了解一下Hash公式:

index = HashCode(key) & (Length - 1) jdk1.8

网上有另一种说法: index = HashCode(key)% Length jdk1.7

当你经过运算的时候,你就会发现,两种方式得到的结果是一致的,所以都正确。

注意:HashMap并不是线性安全的,在并发的情况下可能会形成链表环。

3.jdk1.8对HashMap做的哪些优化?

1)哈希值的计算方法

实际上在jdk1.7中使用的是取模算法,而jdk1.8中使用的是高位与运算。因为&运算比%运算速度更快。

2)引入红黑树

如果HashMap的同一个Hash桶中链表节点数超过8个,则链表转为红黑树处理。

https://zhuanlan.zhihu.com/p/33714985

HashMap扩容的更多相关文章

  1. 面试笔记--HashMap扩容机制

    转载请注明出处 http://www.cnblogs.com/yanzige/p/8392142.html 扩容必须满足两个条件: 1. 存放新值的时候当前已有元素的个数必须大于等于阈值 2. 存放新 ...

  2. JDK1.8 HashMap 扩容 对链表(长度小于默认的8)处理时重新定位的过程

    关于HashMap的扩容过程,请参考源码或百度. 我想记录的是1.8 HashMap扩容是对链表中节点的Hash计算分析. 对术语先明确一下: hash计算指的确定节点在table[index]中的链 ...

  3. 关于JDK1.8 HashMap扩容部分源码分析

    今天回顾hashmap源码的时候发现一个很有意思的地方,那就是jdk1.8在hashmap扩容上面的优化. 首先大家可能都知道,1.8比1.7多出了一个红黑树化的操作,当然在扩容的时候也要对红黑树进行 ...

  4. Java8中HashMap扩容算法小计

    Java8的HashMap扩容过程主要就是集中在resize()方法中 final Node<K,V>[] resize() { // ...省略不重要的 } 其中,当HashMap扩容完 ...

  5. HashMap扩容死循环问题

    原文:https://blog.csdn.net/Leon_cx/article/details/81911223 下面我们来模拟一下多线程场景下扩容会出现的问题: 假设在扩容过程中旧hash桶中有一 ...

  6. ArrayList && HashMap扩容策略

    ArrayList扩容策略:默认10 扩容时是base + base/2, 即10 15 22 33 49...扩容时不安全:grow方法扩容时,赋值 elementData = Arrays.cop ...

  7. HashSet保证元素唯一原理以及HashMap扩容机制

    一.HashSet保证元素唯一原理: 依赖于hashCode()和equals()方法1.唯一原理: 1.1 当HashSet集合要存储元素的时候,会调用该元素的hashCode()方法计算哈希值 1 ...

  8. 如果让你来做HashMap扩容,如何实现在不影响读写的情况下扩容?

    我觉得逼格高,不是体现在问题多刁钻,知识点多深,而是一个非常明确,无歧义的问题,能考察出面试者多方面的能力.这个问题背后:1.了解java中,HashMap的实现:如果一个面试者了解这一点,说明至少他 ...

  9. HashMap 扩容 加载因子

    HashMap: public HashMap(int initialCapacity, float loadFactor) { //初始容量不能<0 if (initialCapacity & ...

  10. HashMap扩容全过程

      1.如果HashMap的大小超过了负载因子(load factor)定义的容量,怎么办? 默认的负载因子大小为0.75,也就是说,当一个map填满了75%的bucket时候,和其它集合类(如Arr ...

随机推荐

  1. logback error 分开存日志

    <?xml version="1.0" encoding="UTF-8"?> <configuration> <property ...

  2. MySQL SQL_MODE详解

    http://blog.itpub.net/29773961/viewspace-1813501/

  3. 15.Servlet程序结构与部署

    1.JavaEE应用程序结构 组成:Servlet  JSP  工具类  第三方jar包,HTML页面(图片.Flash) 部署结构: JavaEE应用根目录下的资源都是允许客户端访问的(WEB-IN ...

  4. springBoot学习资料

    转载:http://www.importnew.com/29363.html 官网搭建springBoot项目:https://www.cnblogs.com/lcplcpjava/p/7406253 ...

  5. requirej入门(二)

    requirejs中的一些基本知识,包括API使用方式等. 基本API require会定义三个变量:define,require,requirejs,其中require === requirejs, ...

  6. CAD安装失败怎样卸载CAD 2019?错误提示某些产品无法安装

    AUTODESK系列软件着实令人头疼,安装失败之后不能完全卸载!!!(比如maya,cad,3dsmax等).有时手动删除注册表重装之后还是会出现各种问题,每个版本的C++Runtime和.NET f ...

  7. 牛客网Java刷题知识点之内存的划分(寄存器、本地方法区、方法区、栈内存和堆内存)

    不多说,直接上干货!  其中        1)程序计数器:用于指示当前线程所执行的字节码执行到了第几行,可以理解为当前线程的行号指示器.每个计数器志勇赖记录一个线程的行号,所以它是线程私有的.    ...

  8. Spring Boot(一)Hello World

    Spring Boot适合与微服务,方便快速开发,简化配置(约定>配置). 准备工作: SpringBoot 2.0 jdk8 IDEA或者eclipse+Spring Tool Suits 创 ...

  9. DEDE日期调用小插件

    在日期文本框里面,点击的时候,下面出来一个和万年历一样的日期选择表,在dede里面,有一个现成的js小插件,直接调用就OK了... <input type="text" on ...

  10. git 摘要

    git使用摘记 git冲突的问题主要是在修改的部分而不是添加的部分, 如果merge的文件在同一个位置有不同的信息则git会报错 git push origin中的origin表示的是远程的仓库名为o ...