HashMap为了存取高效,要尽量较少碰撞,就是要尽量把数据分配均匀,每个链表长度大致相同,这个实现就在把数据存到哪个链表中的算法;
这个算法实际就是取模,hash%length,计算机中直接求余效率不如位移运算,源码中做了优化hash&(length-1),
hash%length==hash&(length-1)的前提是length是2的n次方;
为什么这样能均匀分布减少碰撞呢?2的n次方实际就是1后面n个0,2的n次方-1  实际就是n个1;
例如长度为9时候,3&(9-1)=0  2&(9-1)=0 ,都在0上,碰撞了;
例如长度为8时候,3&(8-1)=3  2&(8-1)=2 ,不同位置上,不碰撞;

其实就是按位“与”的时候,每一位都能  &1  ,也就是和1111……1111111进行与运算

0000 0011     3

& 0000 1000      8

= 0000 0000      0

0000 0010     2

& 0000 1000    8

= 0000 0000      0

-------------------------------------------------------------

0000 0011     3

& 0000 0111     7

= 0000 0011       3

0000 0010      2

& 0000 0111      7

= 0000 0010      2

当然如果不考虑效率直接求余即可(就不需要要求长度必须是2的n次方了);

有人怀疑两种运算效率差别到底有多少,我做个测试:

    /**
*
* 直接【求余】和【按位】运算的差别验证
*/
public static void main(String[] args) { long currentTimeMillis = System.currentTimeMillis();
int a=0;
int times = 10000*10000;
for (long i = 0; i < times; i++) {
a=9999%1024;
}
long currentTimeMillis2 = System.currentTimeMillis(); int b=0;
for (long i = 0; i < times; i++) {
b=9999&(1024-1);
} long currentTimeMillis3 = System.currentTimeMillis();
System.out.println(a+","+b);
System.out.println("%: "+(currentTimeMillis2-currentTimeMillis));
System.out.println("&: "+(currentTimeMillis3-currentTimeMillis2));
}

结果:

783,783
%: 359
&: 93

---------------------

本文来自 四滴火 的CSDN 博客 ,全文地址请点击:https://blog.csdn.net/sidihuo/article/details/78489820?utm_source=copy

HashMap的长度为什么要是2的n次方的更多相关文章

  1. 【Java集合】为什么HashMap的长度是2的N次幂?

    这个问题应该倒过来思考,HashMap的长度是2的N次幂,有什么优势? 在HashMap的putVal()方法中,为了确定插入元素在table[]数组中的下标位置,使用的与(&)运算来计算 如 ...

  2. HashMap的最大容量为什么是2的30次方?

    今天看HashMap的底层实现,发现HashMap的最大容量规定为: // 最大容量(必须是2的幂且小于2的30次方,传入容量过大将被这个值替换) static final int MAXIMUM_C ...

  3. hashmap 为什么初始化容量是2的幂次方

    个人理解 做下记录,不正确的地方望不吝赐教 这是hashmap初始化容量时候 对容量大小做的处理,保证初始化容量为最近的2的幂次方(JDK1.8) static final int tableSize ...

  4. Android版数据结构与算法(四):基于哈希表实现HashMap核心源码彻底分析

    版权声明:本文出自汪磊的博客,未经作者允许禁止转载. 存储键值对我们首先想到HashMap,它的底层基于哈希表,采用数组存储数据,使用链表来解决哈希碰撞,它是线程不安全的,并且存储的key只能有一个为 ...

  5. HashMap与ConcurrentHashMap、HashTable

    (1)HashMap的线程不安全原因一:死循环 原因在于HashMap在多线程情况下,执行resize()进行扩容时容易造成死循环. 扩容思路为它要创建一个大小为原来两倍的数组,保证新的容量仍为2的N ...

  6. HashMap、Hash Table、ConcurrentHashMap

    这个这个...本王最近由于开始找实习工作了,所以就在牛客网上刷一些公司的面试题,大多都是一些java,前端HTML,js,jquery,以及一些好久没有碰的算法题,说实话,有点难受,其实在我不知道的很 ...

  7. HashMap了解吗?

    HashCode() HashMap 底层实现 HashMap 的长度为什么默认初始长度是16,并且每次resize()的时候,长度必须是2的幂次方? HashMap 死链问题 Java 8 与 Ja ...

  8. [转帖]HashMap、HashTable、ConcurrentHashMap的原理与区别

    HashMap.HashTable.ConcurrentHashMap的原理与区别 http://www.yuanrengu.com/index.php/2017-01-17.html 2017年1月 ...

  9. Java中HashMap扩容机制思考

    1. HashMap在什么条件下扩容 判断HashMap的数组Size大小如果超过loadFactor*capacity,就要扩容. 相关的类属性: capacity:当前数组容量,始终保持 2^n, ...

随机推荐

  1. shouldAutoRotate Method Not Called in iOS6

    转自:http://stackoverflow.com/questions/13588325/shouldautorotate-method-not-called-in-ios6 参考1:http:/ ...

  2. 哈佛大学 Machine Learning

    https://am207.github.io/2017/material.html https://am207.github.io/2017/topics.html https://am207.gi ...

  3. python-计算数据的相关性

    先解释下什么叫数据的相关性: 计算两个数组的平均值,如果两个数组中的两个值都大于平均值或者都小于平均值,则得到true. 如果一个大于平均值一个小于平均值,则得到false.最后计算true和fals ...

  4. flash 拾遗

    http://sourceforge.net/adobe/wiki/Projects/ http://www.adobe.com/devnet/air/air-sdk-download.html ht ...

  5. vs code 快捷键的使用

    vs code 快捷键的使用 shift + f12 快速查找函数的生成Ctrl+F12 查看单个函数的定义Shift+F12 查看所有函数的定义ctrl + ` 是打开运行的程序ctrl + Tab ...

  6. js设置cookie(原生js)

    cookie 与 session 是网页开发中常用的信息存储方式.Cookie是在客户端开辟的一块可存储用户信息的地方:Session是在服务器内存中开辟的一块存储用户信息的地方. JavaScrip ...

  7. 【Java】LinkedBlockingQueue、PriorityQueue and ConcurrentLinkedQueue

    1.LinkedBlockingQueue: 基于链接节点的可选限定的blocking queue . 这个队列排列元素FIFO(先进先出). 队列的头部是队列中最长的元素. 队列的尾部是队列中最短时 ...

  8. 在Mac上安装与使用mitmproxy

    [本文出自天外归云的博客园] 介绍 Mitmproxy是一款支持HTTP(S)的中间人代理工具.不同于Fiddler2,burpsuite等类似功能工具,mitmproxy可在终端下运行,并且支持编写 ...

  9. C#学习笔记(6)——大项目增删改查

    说明(2017-5-28 11:35:39): 1. 需要注意的地方很多 2. 首先是连接字符串str要直接写在类里面,不然每个按钮里面都要写一遍. 3. 查询用到sqlDataReader等三个方法 ...

  10. Joint Extraction of Entities and Relations论文解析

    1. 前言 实体和关系的联合抽取问题作为信息抽取的关键任务,其实现方法可以简单分为两类: 一类是串联抽取方法.传统的串联抽取就是首先进行实体抽取,然后进行关系识别.这种分开的方法比较容易实现,而且各个 ...