【Java集合篇】负载因子和容量的关系

在这里插入图片描述

负载因子和容量有什么关系

  • ✔️典型解析
  • ✔️loadfactor为啥默认是0.75F,不是1呢?
    • ✔️为什么HashMap的默认负载因子设置成0.75
      • ✔️0.75的数学依据是什么
      • ✔️0.75的必然因素
  • ✔️HashMap的初始值设为多少合适?


✔️典型解析


HashMap 中有几个属性,如 capacity 记录了 HashMap 中 table 的 length,size记录了HashMap中KV的对数,threshold记录了扩容的阈值 (=loadFactor*capacity) ,loadFactor则是负载因子,一般是3/4。


HashMap 刚刚初始化的时候,如果不指定容量,那么threshold默认是16,如果指定,则默认是第个比指定的容量大的2的幕(如上文所说),此时size=0,capacity=threshold=16loadfactor 默认是0.75F。


HashMap 开始装载的时候 (即调用#put方法),那么size=KV的对数,capacity=16暂时不变,threashold=12 (loadfactor*capacity) ,loadfactor=0.75F


HashMap 中的 size > 12 (threashold) 时,capacity=32 (16 << 1)threashold=24(loadfactor*capacity) , loadfactor=0.75F


由此可得,负载因子决定了什么时候扩容,也间接的决定了HashMap中容量的多少


✔️loadfactor为啥默认是0.75F,不是1呢?


✔️为什么HashMap的默认负载因子设置成0.75


我们知道,当负载因子为1的时候,HashMap就只有当容量满了才会扩容,这样会显得更加节省内存空间,HashMap为什么不这样做呢?


首先,当HashMap完全填满时,发生扩容操作的代价会很高,因为需要重新计算所有键的哈希码并重新分配到新的桶中。这可能导致性能下降。而且,随着HashMap中添加的元素越来越多,哈希冲突的概率会增加,因为元素分布在相对较少的桶中,极端情况下可能会导致某个 Entry 下引用了很长的链表,最终的结果就是虽然节省了空间,但是查询和插入都会很耗时间。


在JDK的官方文档中,有这样一段描述:


As a general rule, the default load factor (.75) offers a good tradeoff between time and
space costs. Higher values decrease the space overhead but increase the lookup cost
(reflected in most of the operations of the HashMap class, including get and put).


翻译过来意思大概就是:


一般来说,默认的负载因子(0.75)在时间和空间成本之间提供了很好的权衡。更高的值减少了空间开销,但增加了查找成本(反映在HashMap类的大多数操作中,包括get和put


✔️0.75的数学依据是什么


另外,我们可以通过一种数学思维来计算下这个值是多少合适。

我们假设一个 bucket 空和非空的概率为0.5,我们用s表示容量,n表示已添加元素个数。


用s表示添加的键的大小和n个键的数目。根据二项式定理,桶为空的概率为:


P(0) = C(n,0) *(1/s)^0 * (1 - 1/s)^(n - 0)


因此,如果桶中元素个数小于以下数值,则桶可能是空的: log(2)/log(s/(s - 1))


当s趋于无穷大时,如果增加的键的数量使P(0) = 0.5,那么n/s很快趋近于log(2) 约等于0.693…所以合理值大概在0.7左右。


当然,这个数学计算方法,并不是在Java的官方文档中体现的,我们也无从考察到底有没有这层考虑这个推测来源于 Stack Overflor


✔️0.75的必然因素


理论上我们认为负载因子不能太大,不然会导致大量的哈希冲突,也不能太小,那样会浪费空间。


通过一个数学推理,测算出这个数值在0.7左右是比较合理的。


🤣那么,为什么最终选定了0.75呢?

答:因为threshold=loadFactor*capacity,并且capacity永远都是2的幂,为了保证负载因子 (loadFactor) * 容量 (capacity) 的结果是一个整数,这个值是0.75(3/4)比较合理,因为这个数和任何2的幂乘积结果都是整数。


✔️HashMap的初始值设为多少合适?


根据阿里巴巴Java开发手册的描述来看:


在这里插入图片描述


假如说我们预期的Map中的值为16个,那么我们不能直接使用 new HashMap<>(16),因为HashMap会在size>12的时候开始扩容,所以合理的方式应该是使用 new HashMap<>(16*4/3+1)才对,这种计算对于开发者来说,显然会复杂一点,所以推荐使用Guava提供的集合工具类,其源码如下:


public static <K,V> HashMap<KV> newHashMapwithExpectedSize(int expectedsize) {return new HashMap<KV>(capacity(expectedsize));
}/**
*  Returns a capacity that is sufficient to keep the map from being resized as long as it grows no
* larger than expectedsize and the load factor is > its default (0.75).
*/
static int capacity(int expectedsize) {if (expectedsize < 3) {checkNonnegative(expectedsize,"expectedsize");return expectedsize + 1;}if (expectedsize < Ints.MAX_POWER_OF_TWO) {// This is the calculation used in JDK8 to resize when a putAll// happens; it seems to be the most conservative calculation we//can make,  0.75 is the default load factor.return (int) ((float) expectedsize / 0.75F + 1.0F);}return Integer.MAX_VALUE; // any large value
}

不过很多时候,我们其实需要的是一些不可变的Map,可以直接使用Guava提供的不可变集合,就没有上面所说的一些问题了。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/602381.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【已解决】js定义对象属性是.如何访问

当变量没有length属性的时候&#xff0c;可能是个对象变量&#xff0c;当有键值对的时候就可能是个对象&#xff0c;读者都知道的是&#xff0c;用typeof(变量)可以查看属性&#xff0c;今天本文解决的问题是如果js定义对象中属性是"点"如何访问 问题再现 var a {…

iPhone 恢复出厂设置后如何恢复数据

如果您在 iPhone 上执行了恢复出厂设置&#xff0c;您会发现所有旧数据都被清除了。这对于清理混乱和提高设备性能非常有用&#xff0c;但如果您忘记保存重要文件&#xff0c;那就是坏消息了。 恢复出厂设置后可以恢复数据吗&#xff1f;是的&#xff01;幸运的是&#xff0c;…

第13课 利用openCV检测物体是否运动了

FFmpeg与openCV绝对是绝配。前面我们已经基本熟悉了FFmpeg的工作流程&#xff0c;这一章我们重点来看看openCV。 在前面&#xff0c;我们已经使用openCV打开过摄像头并在MFC中显示图像&#xff0c;但openCV能做的要远超你的想像&#xff0c;比如可以用它来实现人脸检测、车牌识…

基于平衡优化器算法优化的Elman神经网络数据预测 - 附代码

基于平衡优化器算法优化的Elman神经网络数据预测 - 附代码 文章目录 基于平衡优化器算法优化的Elman神经网络数据预测 - 附代码1.Elman 神经网络结构2.Elman 神经用络学习过程3.电力负荷预测概述3.1 模型建立 4.基于平衡优化器优化的Elman网络5.测试结果6.参考文献7.Matlab代码…

vivado xsim 终端 模拟

只模拟的话直接终端运行会快很多 计数器举例 mkdir srccounter.v module counter(input wire clk,input wire rst_n,output reg[31:0] cnt ); always (posedge clk or negedge rst_n)if(!rst_n)cnt < 31h0;elsecnt < cnt1;endmodule tb.v module tb; wire[31:0] out…

【大厂秘籍】系列 - Java多线程面试题

Java多线程面试题 友情提示&#xff0c;看完此文&#xff0c;在Java多线程这块&#xff0c;基本上可以吊打面试官了 线程和进程的区别 进程是资源分配的最小单位&#xff0c;线程是CPU调度的最小单位 线程是进程的子集&#xff0c;一个进程可以有很多线程&#xff0c;每条线…

Beauty algorithm(三)腮红

查阅资料了解到腮红位于苹果肌处,同样使用关键点确定目标区域,然后对该区域进行渲染达到美妆效果。考虑到如果使用简单的RGB是很难做到特效,本篇采用模板方式进行区域融合。 一、skills 前瞻 1、png图像读取 cv::imread(imgPath, cv::IMREAD_UNCHANGED) IMREAD_UNCHANGE…

小红书 X WSDM 2024「对话式多文档问答挑战赛」火热开赛!

基于大语言模型&#xff08;LLM&#xff09;的对话问答机器人&#xff0c;已经成为当前人工智能领域学术界和工业界共同关注的的热门研究方向之一。在对话过程中&#xff0c;为大模型引入搜索结果&#xff0c;进行检索增强的生成&#xff08;Retrieval Augmented Generation&am…

Go语言并发模式视角思考

犹记得2019年中旬进行知识点的学习和demo的练习&#xff0c;熟悉各种语法和并发调度的场景&#xff0c; 在2019年末开始参与项目实战开发和逻辑梳理 Go语言的接触也是更多探索和业务的拆件&#xff0c;做一些雏形工具&#xff0c;来慢慢的孵化业务生态 后来陆陆续续&#xff…

时间序列预测 — LSTM实现多变量多步负荷预测(Tensorflow):多输入多输出

目录 1 数据处理 1.1 导入库文件 1.2 导入数据集 ​1.3 缺失值分析 2 构造训练数据 3 LSTM模型训练 4 LSTM模型预测 4.1 分量预测 4.2 可视化 1 数据处理 1.1 导入库文件 import time import datetime import pandas as pd import numpy as np import matplotlib.p…

软件测试|教你如何使用UPDATE修改数据

简介 在SQL&#xff08;Structured Query Language&#xff09;中&#xff0c;UPDATE语句用于修改数据库表中的数据。通过UPDATE语句&#xff0c;我们可以更新表中的特定记录或多条记录&#xff0c;从而实现数据的修改和更新。本文将详细介绍SQL UPDATE语句的语法、用法以及一…

【AI视野·今日Robot 机器人论文速览 第六十七期】Mon, 1 Jan 2024

AI视野今日CS.Robotics 机器人学论文速览 Mon, 1 Jan 2024 Totally 16 papers &#x1f449;上期速览✈更多精彩请移步主页 Daily Robotics Papers MURP: Multi-Agent Ultra-Wideband Relative Pose Estimation with Constrained Communications in 3D Environments Authors A…

【高效视频处理】BMF 项目安装与老视频修复体验全流程及总结

一、BMF简介 BMF&#xff08;Babit Multimedia Framework&#xff09;是字节跳动开发的跨平台、多语言、可定制的多媒体处理框架。经过 4 年多的测试和改进&#xff0c;BMF 已经过量身定制&#xff0c;能够熟练地应对我们现实生产环境中的挑战。目前广泛应用于字节跳动的视频串…

主流大语言模型从预训练到微调的技术原理

引言 本文设计的内容主要包含以下几个方面&#xff1a; 比较 LLaMA、ChatGLM、Falcon 等大语言模型的细节&#xff1a;tokenizer、位置编码、Layer Normalization、激活函数等。大语言模型的分布式训练技术&#xff1a;数据并行、张量模型并行、流水线并行、3D 并行、零冗余优…

机器学习--回归算法

&#x1f333;&#x1f333;&#x1f333;小谈&#xff1a;一直想整理机器学习的相关笔记&#xff0c;但是一直在推脱&#xff0c;今天发现知识快忘却了&#xff08;虽然学的也不是那么深&#xff09;&#xff0c;但还是浅浅整理一下吧&#xff0c;便于以后重新学习。 &#x1…

IOS:Safari无法播放MP4(H.264编码)

一、问题描述 MP4使用H.264编码通常具有良好的兼容性&#xff0c;因为H.264是一种广泛支持的视频编码标准。它可以在许多设备和平台上播放&#xff0c;包括电脑、移动设备和流媒体设备。 使用caniuse查询H.264兼容性&#xff0c;看似确实具有良好的兼容性&#xff1a; 然而…

【响应式编程-05】Lambda方法引用

一、简要描述 Lambda的方法引用也叫引用方法 方法引用初体验方法引用的底层实现方法引用的语法格式方法引用举例 静态方法引用构造方法引用普通方法引用super和this方法引用数组的方法引用 二、方法引用初体验 为什么出现方法引用&#xff1f; 引用已存在方法&#xff0c;避免重…

四则运算 C语言xdoj20

问题描述&#xff1a; 输入两个整数和一个四则运算符&#xff0c;根据运算符计算并输出其运算结果&#xff08;和、差、积、商、余之一&#xff09;。注意做整除及求余运算时&#xff0c;除数不能为零。 输入说明&#xff1a; 使用scanf()函数输入两个整数和一个运算符&#xf…

政府采购变数大,AI PC是联想的“新希望”?

文&#xff5c;新熔财经 作者&#xff5c;余一 发布两款AI PC&#xff0c;并预热CES将有AI PC大动作后&#xff0c;联想似乎找到了计算机终端的新思路。 而在这之前&#xff0c;联想终端业务面临的挑战不可谓不严重。 “事业单位更换纯国产电脑”、“联想被排除在大订单之外…

前端面试题-nodejs

1.什么是nodejs&#xff0c;它与传统的网页服务器有什么不同&#xff1f; 是什么&#xff1f;nodejs是基于Chrome V8引擎的JavaScript运行环境&#xff0c;它可以使JavaScript代码在服务器上运行。 有什么不同&#xff1f;第一&#xff0c;nodejs采用事件驱动、非阻塞式I/O模型…