java hashmap扩容大小_HashMap 扩容机制

java hashmap扩容大小_HashMap 扩容机制HashMap:publicHashMap(intinitialCapacity,floatloadFactor){//初始容量不能<0if(initialCapacity<0)thrownewIllegalArgumentException(“Illegalinitialcapacity:”+initialCapacity)…

大家好,又见面了,我是你们的朋友全栈君。

HashMap:

48304ba5e6f9fe08f3fa1abda7d326ab.png

public HashMap(int initialCapacity, floatloadFactor) {

//初始容量不能<0

if (initialCapacity < 0)throw new IllegalArgumentException(“Illegal initial capacity: ” +initialCapacity);

//初始容量不能 > 最大容量值,HashMap的最大容量值为2^30

if (initialCapacity >MAXIMUM_CAPACITY)

initialCapacity=MAXIMUM_CAPACITY;//负载因子不能 < 0

if (loadFactor <= 0 ||Float.isNaN(loadFactor))

throw new IllegalArgumentException(“Illegal load factor: ” +loadFactor);

//计算出大于 initialCapacity 的最小的 2 的 n 次方值。

int capacity = 1;

while (capacity

capacity<<= 1;this.loadFactor =loadFactor;

//设置HashMap的容量极限,当HashMap的容量达到该极限时就会进行扩容操作

threshold = (int) (capacity *loadFactor);//初始化table数组

table = newEntry[capacity]; init();

}

48304ba5e6f9fe08f3fa1abda7d326ab.png

在这里提到了两个参数:初始容量,加载因子。

这两个参数是影响HashMap性能的重要参数,其中容量表示哈希表中桶的数量,初始容量是创建哈希表时的容量,

加载因子是哈希表在其容量自动增加之前可以达到多满的一种尺度,它衡量的是一个散列表的空间的使用程度,负载因子越大表示散列表的装填程度越高,反之愈小。

对于使用链表法的散列表来说,查找一个元素的平均时间是O(1+a),因此如果负载因子越大,对空间的利用更充分,然而后果是查找效率的降低;

如果负载因子太小,那么散列表的数据将过于稀疏,对空间造成严重浪费。系统默认负载因子为0.75,一般情况下我们是无需修改的。

加载因子:

loadFactor

扩容:

48304ba5e6f9fe08f3fa1abda7d326ab.png

void addEntry(int hash, K key, V value, intbucketIndex) {

Entry e =table[bucketIndex];

table[bucketIndex]= new Entry(hash, key, value, e);

if (size++ >= threshold) //这里是关键,一旦大于等于threshold的数值

resize(2 * table.length); //将会引起容量2倍的扩大

}

48304ba5e6f9fe08f3fa1abda7d326ab.png

48304ba5e6f9fe08f3fa1abda7d326ab.png

void resize(intnewCapacity) {

Entry[] oldTable=table;

int oldCapacity =oldTable.length;

if (oldCapacity ==MAXIMUM_CAPACITY) {

threshold=Integer.MAX_VALUE;return;

}

Entry[] newTable= new Entry[newCapacity]; //新的容器空间

transfer(newTable); //复制数据过去

table =newTable;

threshold= (int)(newCapacity * loadFactor); //重新计算threshold的值

}

48304ba5e6f9fe08f3fa1abda7d326ab.png

48304ba5e6f9fe08f3fa1abda7d326ab.png

voidtransfer(Entry[] newTable) {//保留原数组的引用到src中,

Entry[] src =table;//新容量使新数组的长度

int newCapacity =newTable.length;

//遍历原数组

for (int j = 0; j < src.length; j++) {

//获取元素e

Entry e =src[j];if (e != null) {//将原数组中的元素置为null

src[j] = null;

//遍历原数组中j位置指向的链表

do{

Entry next =e.next;//根据新的容量计算e在新数组中的位置

int i =indexFor(e.hash, newCapacity);//将e插入到newTable[i]指向的链表的头部

e.next =newTable[i];

newTable[i]=e;

e=next;

}while (e != null);

}

}

}

48304ba5e6f9fe08f3fa1abda7d326ab.png

通过上面的transfer方法可以看出,

e.next=newTable[i];

newTable[i]=e;

链表存储倒过来了,最先出来的会将其next指向null,后面的就指向前一个,当然数据只有原来的一部分。

===================================================================

随着HashMap中元素的数量越来越多,发生碰撞的概率就越来越大,所产生的链表长度就会越来越长,这样势必会影响HashMap的速度,

为了保证HashMap的效率,系统必须要在某个临界点进行扩容处理。

该临界点在当HashMap中元素的数量等于table数组长度*加载因子。

但是扩容是一个非常耗时的过程,因为它需要重新计算这些数据在新table数组中的位置并进行复制处理。

所以如果我们已经预知HashMap中元素的个数,那么预设元素的个数能够有效的提高HashMap的性能。

问题:

当重新调整HashMap大小的时候,确实存在条件竞争,因为如果两个线程都发现HashMap需要重新调整大小了,它们会同时试着调整大小。

在调整大小的过程中,存储在链表中的元素的次序会反过来,因为移动到新的bucket位置的时候,HashMap并不会将元素放在链表的尾部,而是放在头部,这是为了避免尾部遍历(tail traversing)。

如果条件竞争发生了,那么就死循环了。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/149916.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 常用网络图片url地址「建议收藏」

    常用网络图片url地址「建议收藏」http://www.baidu.com/img/bdlogo.pnghttp://rongcloud-web.qiniudn.com/docs_demo_rongcloud_logo.png

    2022年7月1日
    314
  • Slob分配器的数据结构和分配逻辑

    Slob分配器的数据结构和分配逻辑slob分配器:1.数据链表结构构造;2.分配与释放的逻辑分析;

    2025年6月6日
    2
  • 现在90,00后经常上哪些网站?喜欢看啥网站?

    现在90,00后经常上哪些网站?喜欢看啥网站?现在90,00后经常上哪些网站?喜欢看啥网站?13页PPT:揭秘90后最全研究报告!|网站运营http://www.iyunying.org/seo/sjfx/61716.html90后男生明显比90后女生更愿意在天猫上购买服装和鞋。在天猫上,男装的购买偏好为49%,女装为35%;男鞋的购物偏好为40%,女鞋为31%。90后最渴望的事情是旅行,其中旅行愿望最为迫切的是工作中的90后,达50…

    2022年7月25日
    8
  • 概率矩阵分解模型 PMF[通俗易懂]

    概率矩阵分解模型 PMF[通俗易懂]本文是论文《一种结合推荐对象间关联关系的社会化推荐算法》的笔记(上)。因为对其中的概率矩阵分解(ProbabilisticMatrixFactorization,PMF)不够了解,因而我先去脑补了PMF在推荐系统中的应用,然后再对论文进行总结。主要内容包括svd的两种形式和PMF的介绍。

    2022年6月18日
    61
  • JavaWeb——Servlet(全网最详细教程包括Servlet源码分析)「建议收藏」

    JavaWeb——Servlet(全网最详细教程包括Servlet源码分析)「建议收藏」JavaWeb——ServletTomcat工作机制动画演示(点击动图可全屏观看)什么是ServletServlet(ServerApplet),全称JavaServlet,未有中文译文。是用Java编写的服务器端程序。其主要功能在于交互式地浏览和修改数据,生成动态Web…

    2022年4月27日
    42
  • 解决windows update 8024402C错误[通俗易懂]

    解决windows update 8024402C错误[通俗易懂]安装了2003SP1更新时总是会有8024402C错误错误网上daimoon兄的解决方式他的机器在ISASERVER后而我的机器是ISASERVER2004网上daimoon兄的解决方式他的机器在ISASERVER后环境:windowsxpsp1,位于isaserver后问题:使用windowsautoupdate后出错误提示:0x8024402C…

    2022年5月30日
    170

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号