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

news2024/10/1 9:35:04

在这里插入图片描述

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

  • ✔️典型解析
  • ✔️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.coloradmin.cn/o/1362767.html

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

相关文章

使用qtquick调用python程序,pytorch

一. 内容简介 使用qtquick调用python程序 二. 软件环境 2.1vsCode 2.2Anaconda version: conda 22.9.0 2.3pytorch 安装pytorch(http://t.csdnimg.cn/GVP23) 2.4QT 5.14.1 新版QT6.4,&#xff0c;6.5在线安装经常失败&#xff0c;而5.9版本又无法编译64位程序&#xf…

云尚办公项目学习

完整的笔记可以参考这个专栏&#xff0c;写的挺详细的&#xff1a;云尚办公课件笔记&#xff0c;come on boy 文章目录 form-create表设计步骤1&#xff0c;创建审批类型2&#xff0c;创建审批类型下的审批模板3&#xff0c;为指定的审批模板设置模板名称&#xff0c;表单项&am…

Python笔记01-你好Python

文章目录 Python简介环境安装Hello world开发工具 Python简介 python的诞生 1989年&#xff0c;为了打发圣诞节假期&#xff0c;Gudio van Rossum吉多 范罗苏姆&#xff08;龟叔&#xff09;决心开发一个新的解释程序&#xff08;Python雏形&#xff09; 1991年&#xff0c;第…

CSS 压重按钮 效果

<template><view class="cont"><div class="container"><div class="pane"><!-- 选项1 --><label class="label" @click="handleOptionClick(0)":style="{ color: selectedOption ==…

【机器学习】循环神经网络(二)-LSTM示例(keras)国际航空乘客问题的回归问题...

使用 Keras 在 Python 中使用 LSTM 循环神经网络进行时间序列预测 国际航空乘客问题的回归问题 这个文件是一个CSV格式的数据集&#xff0c;它包含了从1949年1月到1960年12月的每个月的国际航空乘客的总数&#xff08;以千为单位&#xff09;。第一行是列名&#xff0c;分别是&…

Open CASCADE学习|入门Hello world

目录 1、新建项目 2、写代码 3、配置 3.1配置头文件 3.2配置静态库文件 3.3配置动态库文件 4、编译运行 1、新建项目 新建一个Win32控制台应用程序&#xff0c;取名为HelloWorld&#xff0c;如下图所示&#xff1a; 2、写代码 测试所用的代码如下&#xff1a; // Use T…

数据分析基础之《numpy(6)—IO操作与数据处理》

了解即可&#xff0c;用panads 一、numpy读取 1、问题 大多数数据并不是我们自己构造的&#xff0c;而是存在文件当中&#xff0c;需要我们用工具获取 但是numpy其实并不适合用来读取和处理数据&#xff0c;因此我们这里了解相关API&#xff0c;以及numpy不方便的地方即可 2…

Rockchip平台双屏异显功能实现(基于Android13)

Rockchip平台双屏异显功能实现(基于Android13) 1. 异显实现方案 Rockchip SDK平台支持两种不同的异显方案&#xff1a;Android Presentation和Android Activity指定屏幕启动。 使用Android Presentation方案&#xff0c;需要在APP开发中调用相应接口以使指定视图&#xff08…

ATTCK视角下的信息收集:主机发现

目录 1、利用协议主动探测主机存活 利用ICMP发现主机 利用ARP发现主机 利用NetBIOS协议发现主机 利用TCP/UDP发现主机 利用DNS协议发现主机 利用PRC协议发现主机程序 2、被动主机存活检测 利用Browser主机探测存活主机 利用ip段探测主机存活 利用net命令探测主机存活…

论文笔记 Understanding Electricity-Theft Behavior via Multi-Source Data

WWW 2020 oral 1 INTRO 1.1 背景 1.1.1 窃电 窃电&#xff08;electricity theft&#xff09;指用户为了逃避电费而进行非法操作的一种行为 常用的反窃电方法可分为两类&#xff1a; 基于硬件驱动的反窃电方法 ​​​​​​​电表开盖检测、集中器检测。。。。 硬件驱动的…

18.标题统计

题目 import java.util.Scanner;public class Main {public static void main(String[] args) {Scanner sc new Scanner(System.in);String str sc.nextLine();int res 0;for(int i0;i<str.length();i) {char c str.charAt(i);if(c! && c!\n) {res;}}System.o…

Simply主题 简约风格的Emlog博客模板 响应式布局

主题介绍 Simply是一款简约风格的Emlog博客模板&#xff0c;响应式布局、界面简单大方&#xff0c;实用性强&#xff01; 支持夜间模式&#xff0c;采用localStorage存储配置。IOS系统下支持随系统自动切换浅/深色模式。 文章页支持显示文章字数及阅读时间。 支持http/https …

MCS-51单片机的基本结构

目录 一.单片机的逻辑结构 1.单片机的基本结构 2.引脚 3.中断系统 4.时钟电路 5.时序 6.典型指令的取指、执行时序 7.80C51中定时器/计数器 二.单片机的复位 三.程序的执行方式 1.单步执行方式 2.低功耗操作方式 3.EPROM编程和校验方式 首先补充一个知识点&#x…

JVM工作原理与实战(八):类加载器的分类

专栏导航 JVM工作原理与实战 RabbitMQ入门指南 从零开始了解大数据 目录 专栏导航 前言 一、类加载器介绍 二、类加载器的分类 1.Java代码实现的类加载器 2.Java虚拟机底层源码实现的类加载器 3.默认的类加载器层次&#xff08;JDK8及之前的版本&#xff09; 总结 前言…

听GPT 讲Rust源代码--compiler(15)

File: rust/compiler/rustc_arena/src/lib.rs 在Rust源代码中&#xff0c;rustc_arena/src/lib.rs文件定义了TypedArena&#xff0c;ArenaChunk&#xff0c;DroplessArena和Arena结构体&#xff0c;以及一些与内存分配和容器操作相关的函数。 cold_path<F: FnOnce,drop,new,…

PHP在线sqlite转html表格小功能(sqlite2html)

6KB PHP实现在线sqlite转html表格小功能(支持大文件上传,得到一表一文件) 可自定义&#xff1a;上传限制大小&#xff1b;支持后缀格式!下载格式位压缩包&#xff0c;内含一表一个html文件。 作用&#xff1a;程序员实用工具&#xff0c;上传sqlite数据得到html表格数据供本地…

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

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

迁移数据mysql到clickhouse

场景&#xff1a; 项目上需要将mysql表中数据迁移到clickhouse。 理论&#xff1a; 借助MaterializeMySQL 说明&#xff1a; 首先该方案实施需要启动mysql的binlog配置否则同步不了&#xff0c;尽管MaterializeMySQL官方说是在实验阶段&#xff0c;不应该在生产上使用&#x…

【详解】静态库和动态库的认识和使用【Linux】

静态库和动态库的认识和使用 静态库和动态库的概述动静态库的实现静态库动态库库文件名称和引入库的名称 静态库和动态库的概述 静态库&#xff08;.a&#xff09;&#xff1a;程序在编译链接的时候把库的代码链接到可执行文件中。程序运行的时候将不再需要静态库 动态库&#…

【InternLM】书生-浦语大模型demo搭建服务接口部署本地映射

目录 前言一、InternLM大模型介绍1-1、大模型简介1-2、InternLM大模型简介1-2-1、InternLM-7B1-2-2、InternLM-20B 二、从0开始搭建InternLM-Chat-7B 智能对话 Demo2-0、环境搭建2-1、创建虚拟环境2-2、导入所需要的包2-3、模型下载2-4、代码克隆2-5、终端运行 三、服务器接口部…