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. 【Unity】11.6 恒定力 (Constant Force)

    分类:Unity.C#.VS2015 创建日期:2016-05-02 一.简介 恒定力 (Constant Force) 是用于向刚体 (Rigidbody) 添加恒定力的快速实用工具,适用于类似火箭 ...

  2. Binlog中最容易踩到的坑

    MySQL高可用架构中,主库复制是非常常见的一种. 当主库宕机后,可以提升一个从库作为新的主库,保证服务可用性:同时可以通过扩展从库,提高整个集群的QPS. 在主从复制架构下,MySQL通过binlo ...

  3. 2-7-集合运算(A-B)∪(B-A)-线性表-第2章-《数据结构》课本源码-严蔚敏吴伟民版

    课本源码部分 第2章  线性表 - 集合运算(A-B)∪(B-A) ——<数据结构>-严蔚敏.吴伟民版        ★有疑问先阅读★ 源码使用说明  链接☛☛☛ <数据结构-C语言 ...

  4. 多个inputstream的情况下,watermark的值怎么赋值? kakfa中多个partition提取 watermark

    1,org.apache.flink.streaming.api.operators; AbstractStreamOperator public void processWatermark1(Wat ...

  5. 手动分析linux是否中毒的几个考虑点

    linux服务器在不允许安装任何杀毒软件的时候,手动分析有没有中病毒可以从以下几个特征点来考虑. 特征一:查看系统里会产生多余的不明的用户cat /etc/passwd 特征二:查看开机是否启动一些不 ...

  6. [Windows Azure] Developing Multi-Tenant Web Applications with Windows Azure AD

    Developing Multi-Tenant Web Applications with Windows Azure AD 2 out of 3 rated this helpful - Rate ...

  7. HBase 管理,性能调优

    设置 Hadoop 来扩展磁盘 I/O 现代服务器通常有多个磁盘硬件来提供大存储能力.这些磁盘通常配置成 RAID 阵列,作为它们的出厂设置.这在很多情况下是有益的,但对 Hadoop 却不是. Ha ...

  8. FFmpeg Basic学习笔记(4)

    图像处理 常见的图片格式包括YUV.BMP.JPG.GIF.PNG. 图像的创建 可以使用下面命令从输入源中截取图像 ffmpeg -i input -ss t image.type 从videocl ...

  9. 【深度学习】理解dropout

    dropout是指在深度学习网络的训练过程中,对于神经网络单元,按照一定的概率将其暂时从网络中丢弃.注意是暂时,对于随机梯度下降来说,由于是随机丢弃,故而每一个mini-batch都在训练不同的网络. ...

  10. 获得discuz7.2 目录下所有文件,并写到txt

    # -*- coding: utf-8 -*- import os fileList = [] dzList = [] def GetFileList(path): List = [] for roo ...