java hashmap,如果确定只装载100个元素,new HashMap(?)多少是最佳的,why?

要回答这个问题,首先得知道影响HashMap性能的参数有哪些。咱们翻翻JDK。

在JDK6中是这么描述的:

HashMap的实例有两个参数影响其性能:初始容量和加载因子。

首先我们来看初始容量和加载因子的定义。

容量是哈希表中桶的数量,初始容量只是哈希表在创建时的容量。

加载因子是哈希表在其容量自动增加之前可以达到多满的一种尺度。

当哈希表中条目的数目超过 容量乘加载因子 的时候,则要对该哈希表进行rehash操作,从而哈希表将具有大约两倍的桶数。(以上摘自JDK6)

HashMap默认的加载因子是0.75 .它在时间和空间成本上寻求了一种折中。

回到本文的问题。根据JDK中的描述,如果这个只装载100个元素的HashMap没有特殊的用途,那么为了在时间和空间上达到最佳性能,HashMap的初始容量可以设为

100/0.75 = 133.33。为了防止rehash,向上取整,为134。

但是还有另外一个问题,就是hash碰撞的问题。如果我们将HashMap的容量设置为134,那么如何保证其中的哈希碰撞会比较少呢?

除非重写hashcode()方法,否则,似乎没有办法保证。

那么这里不得不提HashMap如何为元素选择下标的方法了。

    static int indexFor(int h, int length) {
return h & (length-1);
}

其中h为key哈希后得到的值,length为哈希表的长度。

134-1 = 128 + 6 -1;

那么 length-1的二进制值的最后3位为101;

假设这100个装载的元素中他们的key在哈希后有得到两个值(h),他们的二进制值除了低3位之外都相同,而第一个值的低3位为011,第二个值的低3位为001;

这时候进行java的&预算,011 & 101 = 001 ;001 & 101 = 001;

他们的值相等了,那么这个时候就会发生哈希碰撞。

除此之外还有一个更加严重的问题,由于在101中第二位是0,那么,无论我们的key在哈希运算之后得到的值h是什么,那么在&运算之后,得到的结果的倒数第二位均为0;

因此,对于hash表所有下标的二进制的值而言,只要低位第二位的值为1,(例如0010,0011,0111,1111)那么这个下标所代表的桶 将一直是空的,因为代码中的&运算的结果永远不会产生低位第二位为1的值。这就大大地浪费了空间,同时还增加了哈希碰撞的概率。这无疑会降低 HashMap的效率。

那么如何才能减少这种浪费呢?最佳的方法当然是让length-1的二进制值全部位均为1.那么length的值是多少合适呢?

没错,length=2^n。

只要将hash表的长度设为2的N次方,那么,所有的哈希桶均有被使用的可能。

再次回到提出的问题,与134最靠近的2^n无疑是128。

如果只修改HashMap的长度而不修改HashMap的加载因子的话,HashMap会进行rehash操作,这是一个代价很大的操作,所以不可取。

那么应该选择的就应该是256。

而由于空间加大和有效利用哈希桶,这时的哈希碰撞将大大降低,因此HashMap的读取效率会比较高。

所以,最后结论就是:HashMap的大小应该设置为256。

结果的补充:其实在Java中,无论你的HashMap(x)中的x设置为多少,HashMap的大小都是2^n。2^n是大于x的第一个数。因为HashMap的初始化代码中有以下这行代码:

 int capacity = 1;
while (capacity < initialCapacity)
capacity <<= 1;

但是这就带来了一个问题,如果x=100,那么HashMap的初始大小应该是128.但是100/128=0.78,已经超过默认加载因子的大小了。因此会resize一次,变成256。所以最好的结果还是256。

HashMap大小选择的更多相关文章

  1. Ubuntu 14.04 16.04 17.10 + Win10 双系统安装记录 + 分区大小选择办法

    安装了N遍,重要的东西在此记录. 参考了 http://www.libinx.com/2017/five-steps-win10-ubuntu-dual-boot/ 忠告:为了让日后喘气能匀呼些,要选 ...

  2. 卷积神经网络(CNN)的细节问题(滤波器的大小选择)

    0. 滤波器的大小选择 大部分卷积神经网络都会采用逐层递增(1⇒ 3 ⇒ 5 ⇒ 7)的方式. 每经过一次池化层,卷积层过滤器的深度都会乘以 2: 1. 权值共享:减轻过拟合 & 降低计算量 ...

  3. HashMap的工作原理

    HashMap的工作原理   HashMap的工作原理是近年来常见的Java面试题.几乎每个Java程序员都知道HashMap,都知道哪里要用HashMap,知道HashTable和HashMap之间 ...

  4. HashMap和HashTable到底哪不同?

    HashMap和HashTable有什么不同?在面试和被面试的过程中,我问过也被问过这个问题,也见过了不少回答,今天决定写一写自己心目中的理想答案. 代码版本 JDK每一版本都在改进.本文讨论的Has ...

  5. HashMap底层实现原理/HashMap与HashTable区别/HashMap与HashSet区别

    ①HashMap的工作原理 HashMap基于hashing原理,我们通过put()和get()方法储存和获取对象.当我们将键值对传递给put()方法时,它调用键对象的hashCode()方法来计算h ...

  6. JAVA hashmap知识整理

    HashMap和Hashtable的比较是Java面试中的常见问题,用来考验程序员是否能够正确使用集合类以及是否可以随机应变使用多种思路解决问题.HashMap的工作原理.ArrayList与Vect ...

  7. HashMap的工作原理深入再深入

    前言 首先再次强调hashcode (==)和equals的真正含义(我记得以前有人会说,equals是判断对象内容,hashcode是判断是否相等之类): equals:是否同一个对象实例.注意,是 ...

  8. HashMap的面试总结(摘抄)

    HashMap的工作原理是近年来常见的Java面试题.几乎每个Java程序员都知道 HashMap,都知道哪里要用HashMap,知道HashTable和HashMap之间的区别,那么为何这道面试题如 ...

  9. HashMap工作原理(转载)

    转载自:http://www.importnew.com/7099.html  HashMap的工作原理是近年来常见的Java面试题.几乎每个Java程序员都知道HashMap,都知道哪里要用Hash ...

随机推荐

  1. [Eclipse]The type XXX cannot be resolved. It is indirectly referenced from required .class files

    在Eclipse中遇到The type XXX cannot be resolved. It is indirectly referenced from required .class files错误 ...

  2. python 内置函数和表达式

    对于简单的函数来说,可以使用类似于三元运算来表示,即: lambda表达式 格式: lambda [arg1[, arg2, ... argN]]: expression   先来看看三元表达式 #普 ...

  3. JS获取URL的参数

    function request(paras) { var url = location.href; , url.length).split("&"); var paraO ...

  4. jQuery模拟页面加载进度条

    因为我们无法通过任何方法获取整个页面的大小和当前加载了多少,所以想制作一个加载进度条的唯一办法就是模拟.那要怎么模拟呢? 我们知道,页面是从上往下执行的,也就是说我们可以大致估算出在页面的某个位置加载 ...

  5. webrtc学习———记录一

    最近导师让研究一下webrtc,希望将来用到我们的ICT2系统中. 但是从来没有过做web的基础,无论前端还是后端,html.js全都从头学起.html还好说,没有太过复杂的东西. js就有点难度了, ...

  6. [Excel] C#DataToExcel帮助类 (转载)

    点击下载 DataToExcel.rar 看下面代码吧 /// <summary> /// 类说明:DataToExcel /// 编 码 人:苏飞 /// 联系方式:361983679 ...

  7. android系统体系结构

    android系统底层是建立在Linux系统之上的,如下图 从上图可以看出android系统有五部分组成 1.APPLICATIONS(应用程序层) 包含一些核心应用程序,电子邮件,日历,地图,浏览器 ...

  8. 关于AfterLogic WebMail 的.net版无法上传控件的解决办法

    在使用AfterLogic WebMail做客户端的时候发现无论是在FF下还是在IE下发送邮件时附件怎么也无法上传,后来查看代码发现它使用的FLASH上传调用的上传代码是upload.php,问题就出 ...

  9. SQL使用数据库引擎存储过程,系统视图查询,DBA,BI开发人员必备基础知识

    在开发过程中会遇到需要弄清楚这个数据库什么时候建的,这个数据库中有多少表,这个存储过程长的什么样子等等信息,今天把自己工作过程中经常用到的一些数据库引擎存储过程,系统视图等等总结一下以备不时之用.下面 ...

  10. 4.SQL语言基础

    4.1语言分类和用户模式 4.1.1语言分类 1)数据查询语言 用语检索数据库中的数据,主要是select语句,是操作数据库时最为频繁使用. 2)数据操纵语言 用语改变数据库中的数据,主要包括inse ...