HashMap负载因子
下面是HashMap的一个构造函数,两个参数initialCapacity,loadFactor
这关系HashMap的迭代性能。
/**
* Constructs an empty <tt>HashMap</tt> with the specified initial
* capacity and load factor.
*
* @param initialCapacity the initial capacity
* @param loadFactor the load factor
* @throws IllegalArgumentException if the initial capacity is negative
* or the load factor is nonpositive
*/
public HashMap(int initialCapacity, float loadFactor) {
if (initialCapacity < 0)
throw new IllegalArgumentException("Illegal initial capacity: " +
initialCapacity);
if (initialCapacity > MAXIMUM_CAPACITY)
initialCapacity = MAXIMUM_CAPACITY;
if (loadFactor <= 0 || Float.isNaN(loadFactor))
throw new IllegalArgumentException("Illegal load factor: " +
loadFactor);
this.loadFactor = loadFactor;
this.threshold = tableSizeFor(initialCapacity);
}
关于这两个参数值的设定界限:
1. initialCapacity是map的初始化容量,initialCapacity > MAXIMUM_CAPACITY,表明map的最大容量是1<<30,也就是1左移30位,每左移一位乘以2,所以就是1*2^30=1073741824.
2. loadFactor是map的负载因子,loadFactor <= 0 || Float.isNaN(loadFactor),表明负载因子要大于0,且是非无穷大的数字
负载因子为什么会影响HashMap性能
首先回忆HashMap的数据结构,
我们都知道有序数组存储数据,对数据的索引效率都很高,但是插入和删除就会有性能瓶颈(回忆ArrayList),
链表存储数据,要一次比较元素来检索出数据,所以索引效率低,但是插入和删除效率高(回忆LinkedList),
两者取长补短就产生了哈希散列这种存储方式,也就是HashMap的存储逻辑.
而负载因子表示一个散列表的空间的使用程度,有这样一个公式:initailCapacity*loadFactor=HashMap的容量。
所以负载因子越大则散列表的装填程度越高,也就是能容纳更多的元素,元素多了,链表大了,所以此时索引效率就会降低。
反之,负载因子越小则链表中的数据量就越稀疏,此时会对空间造成烂费,但是此时索引效率高。
如何科学设置 initailCapacity,loadFactor的值
HashMap有三个构造函数,可以选用无参构造函数,不进行设置。默认值分别是16和0.75.
官方的建议是initailCapacity设置成2的n次幂,laodFactor根据业务需求,如果迭代性能不是很重要,可以设置大一下。
为什么initailCapacity要设置成2的n次幂,网友解释了,我觉得很对,以下摘自网友博客:深入理解HashMap
左边两组是数组长度为16(2的4次方),右边两组是数组长度为15。两组的hashcode均为8和9,但是很明显,当它们和1110“与”的时候,产生了相同的结果,也就是说它们会定
位到数组中的同一个位置上去,这就产生了碰撞,8和9会被放到同一个链表上,那么查询的时候就需要遍历这个链表,得到8或者9,这样就降低了查询的效率。同时,我们也可以
发现,当数组长度为15的时候,hashcode的值会与14(1110)进行“与”,那么最后一位永远是0,而0001,0011,0101,1001,1011,0111,1101这几个位置永远都不能
存放元素了,空间浪费相当大,更糟的是这种情况中,数组可以使用的位置比数组长度小了很多,这意味着进一步增加了碰撞的几率,减慢了查询的效率!

所以说,当数组长度为2的n次幂的时候,不同的key算得得index相同的几率较小,那么数据在数组上分布就比较均匀,也就是说碰撞的几率小,相对的,查询的时候就不用
遍历某个位置上的链表,这样查询效率也就较高了。
resize()方法
initailCapacity,loadFactor会影响到HashMap扩容。
HashMap每次put操作是都会检查一遍 size(当前容量)>initailCapacity*loadFactor 是否成立。如果不成立则HashMap扩容为以前的两倍(数组扩成两倍),
然后重新计算每个元素在数组中的位置,然后再进行存储。这是一个十分消耗性能的操作。
所以如果能根据业务预估出HashMap的容量,应该在创建的时候指定容量,那么可以避免resize().
HashMap负载因子的更多相关文章
- HashMap负载因子为什么是0.75
待写 HashMap负载因子为什么是0.75?HashMap有一个初始容量大小,默认是16static final int DEAFULT_INITIAL_CAPACITY = 1 << ...
- 关于HashMap中的负载因子
这两天在看HashMap的时候,被负载因子float loadFactor搞得很晕,经过一天的研究,最后理出了自己的一点个人见解. 在HashMap的底层存在着一个名字为table的Entry数组,在 ...
- java基础 - 什么是hashmap的负载因子,hashmap的容量(即桶个数)为什么是2的幂次
HashMap的负载因子是指,比如容量为16,负载因子为0.75,则当HashMap的元素个数达到16*0.75=12时,触发扩容.(16和0.75是初始默认的容量和负载因子). HashMap的容量 ...
- 我说我了解集合类,面试官竟然问我为啥HashMap的负载因子不设置成1!?
在Java基础中,集合类是很关键的一块知识点,也是日常开发的时候经常会用到的.比如List.Map这些在代码中也是很常见的. 个人认为,关于HashMap的实现,JDK的工程师其实是做了很多优化的,要 ...
- 面试这么撩准拿offer,HashMap深度学习,扰动函数、负载因子、扩容拆分,原理和实践验证,让懂了就是真的懂!
作者:小傅哥 博客:https://bugstack.cn 沉淀.分享.成长,让自己和他人都能有所收获! 一.前言 得益于Doug Lea老爷子的操刀,让HashMap成为使用和面试最频繁的API,没 ...
- coding++:java-HashMap的负载因子为什么默认是0.75?
本篇文章基于JDK1.8,特在此说明 1):负载因子的作用 负载因子是和扩容机制有关的,意思是如果当前容器的容量,达到了我们设定的最大值,就要开始执行扩容操作.举个例子来解释,避免小白听不懂: 比如说 ...
- unordered_map / HashTable 的负载因子是什么意思
// in C++ 前段时间在看一些关于这个的文章时遇到了一些问题:unordered_map / HashTable 的负载因子是什么意思 经过度娘的搜索,最后得出: 若设 Hash 表的桶数量为 ...
- Hashtable 负载因子Load Factor
负载因子(load factor),它用来衡量哈希表的 空/满 程度,一定程度上也可以体现查询的效率,计算公式为: The ratio of the number of elements in the ...
- HashMap其实就那么一回事儿之源码浅析
上篇文章<LinkedList其实就那么一回事儿之源码分析>介绍了LinkedList, 本次将为大家介绍HashMap. 在介绍HashMap之前,为了方便更清楚地理解源码,先大致说说H ...
随机推荐
- 自定义 Layout布局 UICollectionViewLayout
from: http://www.tuicool.com/articles/vuyIriN 当我们使用系统自带的UICollectionViewFlowLayout无法实现我们的布局时,我们就可以 ...
- JSP +++SERVIET总复习
一. JSP基础概念 软件架构 B/S架构:Browser/Server,浏览器-服务器 最大的优点就是:一次部署,处处访问. C/S架构:Client/Server,客户端-服务器 功能.事件丰富, ...
- Oracle-操作
登录PL_SQL,输入用户名sys 密码 安装时输入的密码,选择 sysdba 打开plsqldev.exe所在目录下的PlugIns文件夹,如果没有请从其它地方拷入 打开运行命令窗口,输入命令 re ...
- SQL一次查出相关类容避免长时间占用表(下)
/* server: db: EDI */ -- 以下案例多次查询同一张表,仅有Name条件不同 --可以使用一次查出相关类容避免长时间占用表 USE EDI GO DECLARE @FileType ...
- 自学spring过程中碰到的问题list,一个一个解决
1.spring的基本原理 2.spring注解有哪几种方式 3.什么情况下适合用哪种注解 4.@autowired @Resource 等的区别 5.spring是怎么使用反射的 6.cjlibe ...
- android 关于表格布局的认识
表格布局(TableLayout) 使用的知识点有: 控件 TableRow:为这个表格添加一行 table的特殊属性 android:layout_column:确定此表格的列数 android:s ...
- _1_html_
创:18_3_2017修:20_3_2017什么是html? 超文本标记语言 告诉浏览器内容的语义,html中包含了各种标签html页面的框架是什么? <!DOCTYPE html> #D ...
- Http相关
1.http请求 http请求分为三部分:请求行,请求头,请求正文 1. 请求行 请求方式 GET POST 请求资源路径 协议版本 GET与POST请求区别? get只能传递1kb以下数据,P ...
- zabbix_agent-linux下的安装
scp 10.25.133.184:/usr/local/zabbix-2.4.1.tar.gz /usr/local 1.为了安全考虑zabbix只使用普通用户运行,假如你当前用户叫ttlsa,那么 ...
- [原]docker 操作记录
开启新容器 docker run --name 容器名字 -ti[d] 镜像 初始化命令(需要是阻塞的) 额外参数 -v 本地目录:容器目录[:ro] 映射本地路径和容器路径(时区同步.数据库dock ...