说在前面

​ 在HashMap中,默认创建的数组长度是16,也就是哈希桶个数为16,当添加key-value的时候,会先计算出他们的哈希值(h = hash),然后用return h & (length-1)就可以算出一个数组下标,这个数组下标就是键值对应该存放的位置。

​ 但是,当数据较多的时候,不同键值对算出来的hash值相同,而导致最终存放的位置相同,这就是hash冲突,当出现hash冲突的时候,该位置的数据会转变成链表的形式存储,但是我们知道,数组的存储空间是连续的,所以可以直接使用下标索引来查取,修改,删除数据等操作,而且效率很高。而链表的存储空间不是连续的,所以不能使用下标 索引,对每一个数据的操作都要进行从头到尾的遍历,这样会使效率变得很低,特别是当链表长度较大的时候。为了防止链表长度较大,需要对数组进行动态扩容。

​ 数组扩容需要申请新的内存空间,然后把之前的数据进行迁移,扩容频繁,需要耗费较多时间,效率降低,如果在使用完一半的时候扩容,空间利用率就很低,如果等快满了再进行扩容,hash冲突的概率增大!!那么什么时候开始扩容呢???

​ 为了平衡空间利用率和hash冲突(效率),设置了一个加载因子(loadFactor),并且设置一个扩容临界值(threshold = DEFAULT_INITIAL_CAPACITY * loadFactor),就是说当使用了16*0.75=12个数组以后,就会进行扩容,且变为原来的两倍。

  • 为什么加载因子是0.75呢?

    先看一段源码注释:

    Because TreeNodes are about twice the size of regular nodes, we
    * use them only when bins contain enough nodes to warrant use
    * (see TREEIFY_THRESHOLD). And when they become too small (due to
    * removal or resizing) they are converted back to plain bins. In
    * usages with well-distributed user hashCodes, tree bins are
    * rarely used. Ideally, under random hashCodes, the frequency of
    * nodes in bins follows a Poisson distribution
    * (http://en.wikipedia.org/wiki/Poisson_distribution) with a
    * parameter of about 0.5 on average for the default resizing
    * threshold of 0.75, although with a large variance because of
    * resizing granularity. Ignoring variance, the expected
    * occurrences of list size k are (exp(-0.5) * pow(0.5, k) /
    * factorial(k)). The first values are:
    *
    * 0: 0.60653066
    * 1: 0.30326533
    * 2: 0.07581633
    * 3: 0.01263606
    * 4: 0.00157952
    * 5: 0.00015795
    * 6: 0.00001316
    * 7: 0.00000094
    * 8: 0.00000006
    * more: less than 1 in ten million

    大概意思就是说,在理想情况下,使用随机哈希码,节点出现的频率在hash桶中遵循泊松分布,同时给出了桶中元素个数和概率的对照表。从上面的表中可以看到当桶中元素到达8个的时候,概率已经变得非常小,也就是说用0.75作为加载因子,每个碰撞位置的链表长度超过8个的概率达到了一百万分之一。

为什么HashMap的加载因子是0.75?的更多相关文章

  1. HashMap默认加载因子为什么选择0.75?(阿里)

    Hashtable 初始容量是11 ,扩容 方式为2N+1; HashMap 初始容量是16,扩容方式为2N; 阿里的人突然问我为啥扩容因子是0.75,回来总结了一下: 提高空间利用率和 减少查询成本 ...

  2. [转]为什么Java中的HashMap默认加载因子是0.75

    前几天在一个群里看到有人讨论hashmap中的加载因子为什么是默认0.75. HashMap源码中的加载因子 static final float DEFAULT_LOAD_FACTOR = 0.75 ...

  3. 关于new HashMap<>(1)中1的理解(hashMap的加载因子)

    新入公司,阅读代码的时候发现了一行代码,为 Map<String, String> map=new HashMap<>(1); 对于这个括号里面的1不能理解,于是查了资料,大概 ...

  4. HashMap 扩容 加载因子

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

  5. 为什么HashMap初始大小为16,为什么加载因子大小为0.75,这两个值的选取有什么特点?

    先看HashMap的定义: public class HashMap<K,V>extends AbstractMap<K,V>implements Map<K,V> ...

  6. ArrayList、Vector、HashMap、HashSet的默认初始容量、加载因子、扩容增量

    当底层实现涉及到扩容时,容器或重新分配一段更大的连续内存(如果是离散分配则不需要重新分配,离散分配都是插入新元素时动态分配内存),要将容器原来的数据全部复制到新的内存上,这无疑使效率大大降低. 加载因 ...

  7. ArrayList、Vector、HashMap、HashTable、HashSet的默认初始容量、加载因子、扩容增量

    这里要讨论这些常用的默认初始容量和扩容的原因是: 当底层实现涉及到扩容时,容器或重新分配一段更大的连续内存(如果是离散分配则不需要重新分配,离散分配都是插入新元素时动态分配内存),要将容器原来的数据全 ...

  8. List、Map、set的加载因子,默认初始容量和扩容增量

    首先,这三个概念说下.初始大小,就是创建时可容纳的默认元素个数:加载因子,表示某个阀值,用0~1之间的小数来表示,当已有元素占比达到这个阀值后,底层将进行扩容操作:扩容方式,即指定每次扩容后的大小的规 ...

  9. Java集合类初始容量、加载因子、扩容增量

    当底层实现涉及到扩容时,容器或重新分配一段更大的连续内存(如果是离散分配则不需要重新分配,离散分配都是插入新元素时动态分配内存),要将容器原来的数据全部复制到新的内存上,这无疑使效率大大降低. 加载因 ...

随机推荐

  1. Mssql 查询某记录前后N条

    Sqlserver 查询指定记录前后N条,包括当前数据 条件 [ID] 查询 [N]条 select * from [Table] where ID in (select top ([N]+1) ID ...

  2. [ch01-03]神经网络基本原理

    系列博客,原文在笔者所维护的github上:https://aka.ms/beginnerAI, 点击star加星不要吝啬,星越多笔者越努力. 前言 For things I don't know h ...

  3. nyoj 7 街区最短路径问题 (曼哈顿距离(出租车几何) or 暴力)

    街区最短路径问题 时间限制:3000 ms  |  内存限制:65535 KB 难度:4   描述 一个街区有很多住户,街区的街道只能为东西.南北两种方向. 住户只可以沿着街道行走. 各个街道之间的间 ...

  4. C语言|博客作业03

    这个作业属于哪个课程 C程序语言设计 这个作业要求在哪里 https://edu.cnblogs.com/campus/zswxy/CST2019-1/homework/8654 我在这个课程的目标是 ...

  5. python中的__str__和__repr__方法

    如果要把一个类的实例变成 str,就需要实现特殊方法__str__(): class A(object): def __init__(self,name,age): self.name=name se ...

  6. 初探three.js

    相信大多数选择前端的小伙伴都有一个设计师的梦,今天我来说一说three.js.three.js是一款运行在浏览器中的 3D 引擎,你可以用它创建各种三维场景,包括了摄影机.光影.材质等各种对象.学习了 ...

  7. 元数据管理的重要性 - xms

    什么是元数据?引用百科的描述就是:元数据(Metadata),又称中介数据.中继数据,为描述数据的数据(data about data),主要是描述数据属性(property)的信息: 看起来有点抽象 ...

  8. 1 JAVA语言的特点

    1.可移植性 通过先将java文件编译成字节码,再由特定平台的JVM转义为机器码,使得JAVA语言具有,编写一次,到处执行的特点.可移植性好. 2.面向对象的编程 面向对象编程的良好实现.有良好的面向 ...

  9. HTML,CSS,Javascript,PHP在网站结构中扮演的“角色”

    ①HTML   在网站结构中使用来,展示网页内容的: ②CSS   在网站结构中使用来,美化页面,如字体颜色大小等: ③Javascript(JS)   在网站结构中使用来,让页面动起来,提高浏览体验 ...

  10. Erlang/Elixir精选-第1期

    第1期(20191202) 文章 A short guide to the structure and internals of the Erlang distributed messaging fa ...