-
HashMap初始容量
2020-06-08 14:56:59 -
Java规范 HashMap初始容量与容量大小
2020-11-22 21:46:36为什么设置初始容量 初始容量多大合适 第一个问题:为什么设置初始容量 这个答案其实通过阅读源码也可以得到。简单来说就是避免扩容带来的效率问题。扩容机制具体详见源码。 在初始化 HashMap 的时候,应该尽量指定...Java规范 HashMap初始容量与容量大小
这是两个问题
- 为什么设置初始容量
- 初始容量多大合适
第一个问题:为什么设置初始容量
这个答案其实通过阅读源码也可以得到。简单来说就是避免扩容带来的效率问题。扩容机制具体详见源码。
在初始化 HashMap 的时候,应该尽量指定其大小。尤其是当你已知 map 中存放的元素个数时。(《阿里巴巴 Java 开发规约》)第二个问题:初始容量多大合适
那么,既然建议我们集合初始化的时候,要指定初始值大小,那么我们创建
HashMap 的时候,到底指定多少合适呢?有些人会自然想到,我准备塞多少个元素我就设置成多少呗。比如我准备塞 7 个元素,那就 new HashMap(7)。但是,这么做不仅不对,而且以上方式创建出来的 Map 的容量也不是 7。因 为, 当 我 们 使 用 HashMap(int initialCapacity) 来 初 始 化 容 量 的 时 候,HashMap 并不会使用我们传进来的 initialCapacity 直接作为初识容量。JDK 会默认帮我们计算一个相对合理的值当做初始容量。所谓合理值,其实是找到第一个比用户传入的值大的 2 的幂。也就是说,当我们 new HashMap(7) 创建 HashMap 的时候,JDK 会通过计算,帮我们创建一个容量为 8 的 Map;当我们 new HashMap(9) 创建 HashMap 的时候,JDK 会通过计算,帮我们创建一个容量为 16 的 Map。但是,这个值看似合理,实际上并不尽然。因为 HashMap 在根据用户传入的capacity 计算得到的默认容量,并没有考虑到 loadFactor 这个因素,只是简单机械的计算出第一个大约这个数字的 2 的幂。
loadFactor 是负载因子,当 HashMap 中的元素个数(size)超过 threshold
= loadFactor * capacity 时,就会进行扩容。也就是说,如果我们设置的默认值是 7,经过 JDK 处理之后,HashMap 的容量会被设置成 8,但是,这个 HashMap 在元素个数达到 8*0.75 = 6 的时候就会进行一次扩容,这明显是我们不希望见到的。那么,到底设置成什么值比较合理呢?
这里我们可以参考 JDK8 中 putAll 方法中的实现的,这个实现在 guava(21.0版本)也被采用。这个值的计算方法就是:return (int) ((float) expectedSize / 0.75F + 1.0F);
比如我们计划向 HashMap 中放入 7 个元素的时候,我们通过 expectedSize /0.75F + 1.0F 计算,7/0.75 + 1 = 10 ,10 经过 JDK 处理之后,会被设置成 16,这就大大的减少了扩容的几率。
当 HashMap 内 部 维 护 的 哈 希 表 的 容 量 达 到 75% 时(默 认 情 况 下), 会 触发 rehash, 而 rehash 的 过 程 是 比 较 耗 费 时 间 的。 所 以 初 始 化 容 量 要 设 置 成expectedSize/0.75 + 1 的话,可以有效的减少冲突也可以减小误差。所以,我们可以认为,当我们明确知道 HashMap 中元素的个数的时候,把默认容量设置成 expectedSize / 0.75F + 1.0F 是一个在性能上相对好的选择,但是,同时也会牺牲些内存。这个算法在 guava 中有实现,开发的时候,可以直接通过 Maps 类创建一个HashMap:
Map<String, String> map = Maps.newHashMapWithExpectedSize(7);其代码实现如下:36 > Java 开发手册建议创建 HashMap 时设置初始化容量,但是多少合适呢?
public static <K, V> HashMap<K, V> newHashMapWithExpectedSize(int expectedSize) {
return new HashMap(capacity(expectedSize));
}
static int capacity(int expectedSize) {
if (expectedSize < 3) {
CollectPreconditions.checkNonnegative(expectedSize, “expectedSize”);
return expectedSize + 1;
} else {
return expectedSize < 1073741824 ? (int)((float)expectedSize/0.75F+1.0F) : 2147483647;
}
}但是, 以上的操作是一种用内存换性能的做法,真正使用的时候,要考虑到内存的影响。但是,大多数情况下,我们还是认为内存是一种比较富裕的资源。但是话又说回来了,有些时候,我们到底要不要设置 HashMap 的初识值,这个值又设置成多少,真的有那么大影响吗?其实也不见得!可是,大的性能优化,不就是一个一个的优化细节堆叠出来的吗?再 不 济, 以 后 你 写 代 码 的 时 候, 使 用 Maps.newHashMapWithExpectedSize(7); 的写法,也可以让同事和老板眼前一亮。或者哪一天你碰到一个面试官问你一些细节的时候,你也能有个印象,或者某一天你也可以拿这个出去面试问其他人 ~ !啊哈哈哈
-
HasMap初始容量设置
2019-11-27 10:47:21构造一个具有默认初始容量 (16) 和默认加载因子 (0.75) 的空 HashMap。 HashMap(int initialCapacity) 造一个带指定初始容量和默认加载因子 (0.75) 的空 HashMap。 HashMap(int initialCapacity, float ...JDK构造方法摘要
HashMap()
构造一个具有默认初始容量 (16) 和默认加载因子 (0.75) 的空 HashMap
。HashMap(int initialCapacity)
造一个带指定初始容量和默认加载因子 (0.75) 的空 HashMap
。HashMap(int initialCapacity, float loadFactor)
构造一个带指定初始容量和加载因子的空 HashMap
。HashMap(Map<? extends K,? extends V> m)
构造一个映射关系与指定 Map
相同的新HashMap
。一、概念
HashMap 的实例有两个参数影响其性能:初始容量和加载因子。容量是哈希表中桶的数量,初始容量只是哈希表在创建时的容量。加载因子是哈希表在其容量自动增加之前可以达到多满的一种尺度。当哈希表中的条目数超出了加载因子与当前容量的乘积时,则要对该哈希表进行 rehash 操作(即重建内部数据结构),从而哈希表将具有大约两倍的桶数。
通常,默认加载因子 (0.75) 在时间和空间成本上寻求一种折衷。加载因子过高虽然减少了空间开销,但同时也增加了查询成本(在大多数 HashMap 类的操作中,包括 get 和put 操作,都反映了这一点)。在设置初始容量时应该考虑到映射中所需的条目数及其加载因子,以便最大限度地减少 rehash 操作次数。如果初始容量大于最大条目数除以加载因子,则不会发生 rehash 操作。
二、举例
像HashMap,默认大小是16,也就是支持存储最多20个键值对,如果不超过20个键值对,可以不设置,如果超出,按如下公式计算后设置:
initialCapacity = (需要存储的元素(键值对)个数 / 负载因子) + 1
但是,hashmap在我们存放的数据大于初始化容量*负载因子(默认0.75)时就会自动扩容,自动扩容是非常消耗性能的。因为元素要重新hash分配。
-
hashmap初始容量问题?
2020-04-28 09:12:53初始容量就是指定容器的初始大小,但是如果超过了初始容量会发生什么呢?是会数组越界异常,因为初始容量指定的是key的个数,而key是存在数组里面的。因为数组指定大小后就不可变,所以超过容量会报异常 ...最近遇到一个关于hashmap的面试题,关于指定处理容量的。初始容量就是指定容器的初始大小,但是如果超过了初始容量会发生什么呢?是会数组越界异常,因为初始容量指定的是key的个数,而key是存在数组里面的。因为数组指定大小后就不可变,所以超过容量会报异常
-
HashMap初始容量剖析
2020-05-15 17:21:46问题: 确定只装载10个元素, HashMap初始容量多少是最佳? 答案: 16 目的: 防止HashMap频繁扩容,影响性能 解析: HashMap的底层数据结构是由 数组 和 单向链表 组成 扩容概念: 当所用数组的长度 大于 初始长度 * 0.75... -
# 深入理解ArrayList集合的初始容量和初始容量为0的两种扩容机制(1.8版本)
2018-09-06 17:05:19浅析ArrayList集合的初始容量和初始容量为0的两种扩容机制(1.8版本) 网络上对于ArrayList集合的空参构造是否为0,存在不同的的看法。对此,分析了源码,有以下见解: 1.空参构造,集合初始容量必定为0,添加一... -
容器的初始容量
2019-02-21 17:49:06ArrayList、Vector默认初始容量为10 Vector:线程安全,但速度慢 底层数据结构是数组结构 加载因子为1:即当 元素个数 超过 容量长度 时,进行扩容 扩容增量:原容量的 1倍 如 Vector的容量为10,一次... -
计算Map初始容量算法
2019-10-11 10:41:28在实际开发中经常需要使用到Map,但给Map一个怎样的初始容量比较合理? 众所周知是最接近(要大于)数据长度的2的N次方 那么,如何计算? 欢迎指出错误 /** * 计算Map初始容量 * @author 枫铃也 * @since 2019-10-... -
HashMap初始容量设置问题
2020-04-26 00:08:23HashMap初始容量设置问题 我们都知道HashMap的默认容量为16,但是: HashMap<Object, Object> objectObjectHashMap = new HashMap<>(13); //13为自定义的hashmap容量 为什么我们可以这样设置HashMap的... -
关于ArrayList初始容量的问题
2020-09-02 19:27:10关于ArrayList初始容量的问题 先上结论: 1、使用无参构造器创建ArrayList对象时,默认容量是0 2、当往ArrayList中添加了一个元素后,默认容量自动扩充成10 3、当容量到达上限时会使用位运算自动扩容,新的... -
HashMap的初始容量设置
2019-06-13 14:23:00Java中HashMap的初始容量设置问题 阿里规约建议集合初始化时,指定初始化大小。 像HashMap,默认大小是16,也就是支持存储最多20个键值对。 如果不超过20个键值对,可以不设置,如果超出,按如下公式计算后设置: ... -
java1.7 初始容量的问题
2018-07-11 17:16:15的时候 ,初始容量已经是默认的10了但是最近看源码发现它在初始化的时候, 初始化的是一个空的Object[] , 并没有初始化容量在add()的时候 ,才会初始化容量所以在java1.7是 ,初次new的时候 ,是没有容量的 ,在add的时候 ... -
Java中的ArrayList的初始容量和容量分配
2017-11-02 10:55:23Java中的ArrayList的初始容量和容量分配 本文是转载文章,文章的来源:博客园 博主:潸何 文章:Java中的ArrayList的初始容量和容量分配 博文地址:http://www.cnblogs.com/ShanHeDiao/p/4402030.html List... -
HashMap初始容量指定规则
2020-06-25 16:20:59public static void main(String[] args) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException { Map<String, Object> map = new HashMap<>(8); for (int i = 0;... -
关于HashMap(JDK 1.8) 初始容量设置
2019-05-09 21:58:58可以设置初始容量,可以不设置初始容量。如果map已有数据,然后执行putAll操作,那么在初始化map时指定初始容量。知道最终要put的数据总量,初始容量设置为 (int) ((float) expectedSize / 0.75F + 1.0F)。不知道... -
HashMap中的初始容量和加载因子
2021-01-09 09:37:26HashMap有两个参数影响其性能:初始容量和加载因子。容量是哈希表中桶的数量,初始容量只是哈希表在创建时的容量。加载因子是哈希表在其容量自动扩容之前可以达到多满的一种度量。当哈希表中的条目数超出了加载因子... -
求的ArrayList的初始容量大小
2019-03-26 09:51:42这里如果有 list.add("jldsk"); 那么初始容量为10,如果没有添加这条语句,那么初始化容量为0; -
java初始容量设置
2012-09-06 17:05:21我们常用Collection中的Map做Cache,但是我们经常会遗忘设置初始容量。 初始容量的影响有多大?拿LinkedHashMap来说,初始容量如果不设置默认是16,超过16×LOAD_FACTOR,会resize(2 * table.length),扩大2倍:... -
集合的默认初始容量、加载因子、扩充容量
2019-04-18 15:40:49今天有空,总结下集合的默认初始容量、加载因子、扩充容量的一些常识性东西,也方便自己查阅。 1、常用集合的默认初始容量和扩容的原因 当底层实现涉及到扩容时,容器会重新分配一段更大的连续内存(如果是离散... -
ArrayList 的初始容量多少?
2019-04-24 16:50:38List<Integer> list = new ArrayList<... list 的初始容量到底是多少 在 JDK 8 中 查看 ArrayList 源码 /** * Constructs an empty list with an initial capacity of ten. */ public ArrayList(... -
java hashmap容量_Java HashMap初始容量的取值示例
2021-02-12 19:38:19HashMap使用过程中,如果数据量加大,最好指定初始容量,以免不必要的rehash开销影响执行效率了,下面我们一起来看几个例子HashMap中底层数据的长度总是2的n次方在某个元素存入HashMap底层数组时,为确定其位置,最... -
Java中HashMap的初始容量设置
2019-06-26 14:12:00Java中HashMap的初始容量设置: 根据阿里巴巴Java开发手册上建议HashMap初始化时设置已知的大小,如果不超过16个,那么设置成默认大小16: 集合初始化时, 指定集合初始值大小。 说明: HashMap使用HashMap... -
通过反射对ArrayList的初始容量浅析
2020-08-15 20:45:58今天在看ArrayList的源码时发现,ArrayList的空参构造方法中默认初始容量是0,有一点感到不解,上课老师有提到过ArrayList的初始容量是10。找来旧版查看JDK源码后发现,JDK1.6、1.7、1.8在ArrayList的空参构造方法上... -
ArrayList的初始容量以及扩容
2018-12-21 09:11:51先看没有指定容量的ArrayList构造函数和相关代码: public ArrayList() { ... // 默认初始容量,这只是一个标记,在执行add方法的时候检测到这个标记会把初始值设为10 } public boolean add(E e) { ensureCapacit... -
集合的初始容量与性能
2019-09-29 00:29:02没事随便写写 :) 你知道当你写下下面这两句时这些数据结构的实际长度吗...你知道初始容量对今后的操作有什么性能上的影响吗?如果你不知道,让我来告诉你,因为我研究过了。 ArrayList与List<T> .NET... -
ArrayList的初始容量的问题
2015-06-07 08:57:45ArrayList的初始容量的问题 -
请为集合指定初始容量
2016-05-20 11:44:43当这个海、容器的量变得非常大的时候,它的初始容量就会显得很重要了,因为挖海、扩容是需要消耗大量的人力物力财力的。同样的道理,Collection的初始容量也显得异常重要。所以:对于已知的情景,请为集合指定初始...
-
ttt-9播放循环q-000-源码
-
MySQL 四类管理日志(详解及高阶配置)
-
js 实现拖拽(面向对象方式实现)
-
MaxScale 实现 MySQL 读写分离与负载均衡
-
牛牛量化策略交易
-
android-ClippingBasic:已迁移:-源码
-
IOC容器概述
-
ember-hold-button:[未维护]按住以确认按钮,易于定制,用于ember-cli-源码
-
Chapter 6 Graphical Representation of Causal Effects
-
tarotace:使用CodeSandbox创建-源码
-
MySQL 触发器
-
ERROR: Could not build wheels for mujoco-py which use PEP 517 and cannot be installed directly
-
用于白色发光二极管的新型SrAl“ 2B” 2O“ 7:Eu ^ 2 ^ +,Mn ^ 2 ^ +荧光粉
-
织梦响应式中小学早教教育机构类网站织梦模板(自适应手机端)
-
pycharm 删除所有注释
-
织梦响应式日化食品零食类网站织梦模板(自适应手机端)
-
解决打包遇到错误Failed to execute goal org.apache.maven.plugins:maven-surefire-plugin:2.22.2:test
-
git-gui.exe
-
实验1-源码
-
window版mysql8.0.23_win64安装包