HashMap中 工具方法tableSizeFor的作用
【转】 https://blog.csdn.net/fan2012huan/article/details/51097331
首先看下该方法的定义以及被使用的地方
static final int tableSizeFor(int cap) {
int n = cap - 1;
n |= n >>> 1;
n |= n >>> 2;
n |= n >>> 4;
n |= n >>> 8;
n |= n >>> 16;
return (n < 0) ? 1 : (n >= MAXIMUM_CAPACITY) ? MAXIMUM_CAPACITY : n + 1;
}
public HashMap(int initialCapacity, float loadFactor) {
// code...
this.threshold = tableSizeFor(initialCapacity);
}
tableSizeFor()这个方法的作用是找到大于等于给定容量的最小2的次幂值
>>>这个符号在java里是无符号右移的意思。
接下来分析一下这个方法的作用。
第一句
int n = cap - 1;
先不用考虑,我们分析完后面的之后再回过头来看它
然后是第二句
n |= n >>> 1;
我们这里假设n的初始值为9,那么9的二进制表示是
00000000 00000000 00000000 00001001
那么经历一次右移之后,二进制表示是
00000000 00000000 00000000 00000100
这两个值进行异或之后,就是
00000000 00000000 00000000 00001100
这里我们如果看最高的1的话,那么可以发现右移1位并且异或之后,使得最高位的右边一位也是1.
同理,我们可以下一句右移2位并且异或之后,使得最高两位1的后两位也是1.
我们之后运行到最后一个右移,可以发现n的值变为了
00000000 00000000 00000000 00001111
当然该值大于1并且小于最大值那么+1之后,该值就变成了
00000000 00000000 00000000 00010000
惊讶的发现这个值不就是2的次幂嘛!!!
此时我们回到第一句-1,如果给定的n已经是2的次幂,但是不进行-1操作的话,那么得到的值就是大于给定值的最小2的次幂值。
至于为什么右移到16位,可以得到的最大值是32个1
11111111 11111111 11111111 11111111
这个是因为java的int类型用4个字节32位来进行存储的。最往后没有意义。
HashMap中 工具方法tableSizeFor的作用的更多相关文章
- Java中hashCode()方法以及HashMap()中hash()方法
Java的Object类中有一个hashCode()方法: public final native Class<?> getClass(); public native int hashC ...
- Java基础:HashMap中putAll方法的疑惑
最近回顾了下HashMap的源码(JDK1.7),当读到putAll方法时,发现了之前写的TODO标记,当时由于时间匆忙没来得及深究,现在回顾到了就再仔细思考了下 @Override public v ...
- Cstring中GetBuffer()方法的主要作用
摘自:http://bbs.csdn.net/topics/310247836 GetBuffer()主要作用是将字符串的缓冲区长度锁定 CString::GetBuffer有两个重载版本: (1 ...
- Jquery中addClass方法不起作用的解决方案
selected类是要在点击后添加上去的新样式,在点击后,发现没有变化,打开开发者工具,发现selected类已经添加成功了. 在这里没有显示成功的主要原因是后添加的样式表优先级更低,我暂时不清楚具体 ...
- POI中setDefaultColumnWidth方法不起作用的原因
sheet.setDefaultRowHeight((short) (2 * 256)); //设置默认行高,表示2个字符的高度 sheet.setDefaultColumnWidth(17); ...
- K:HashMap中hash函数的作用
在分析了hashCode方法和equals方法之后,我们对hashCode方法和equals方法的相关作用有了大致的了解.在通过查看HashMap类的相关源码的时候,发现其中存在一个int has ...
- 统计字符串中每种字符出现的评率(HashMap中getOrDefault(K, V)方法的使用)
为了统计字符串中每种字符出现的频率,使用HashMap这种数据结构.其中,字符作为Key,出现的频率作为Value. 基本算法为: 1. 将字符串分成字符数组 2. (1)如果HashMap中的Key ...
- java中native方法的使用
在非常多情况下,java须要调用其它语言的代码,比方c的代码.那么这个时候java中native方法就发挥作用了.以下就介绍native方法的使用. 一.JNI使用流程 a.编写带有native声明的 ...
- Python--day37--多进程中的方法join()
1,多进程中的方法join()的作用: 感知一个子进程的结束,将异步的程序改为同步 #join() import time from multiprocessing import Process de ...
随机推荐
- 正确设置越狱版ios的终端编码--命令行中文的处理
本文是针对越狱版iPhone手机的,手机没有越狱就别看了,看了也没办法用. 越狱版的iPhone当然是为了跟电脑一样做各种有趣的事情的. 但通常越狱的iPhone在命令行都无法处理中文,比如你的播放器 ...
- JS去重的几种常见方法
JS数组去重的几种常见方法 一.简单的去重方法 // 最简单数组去重法 /* * 新建一新数组,遍历传入数组,值不在新数组就push进该新数组中 * IE8以下不支持数组的indexOf方法 * */ ...
- ETCD:词汇表
原文地址:词汇表 本文档定义了etcd文档,命令行和源代码中使用的各种术语. Alarm 每当集群需要操作员干预以保持可靠性时,etcd服务器都会发出警报. Authentication 身份验证管理 ...
- Java入门系列之包装类(四)
前言 上一节我们讲解了StringBuilder VS StringBuffer以及二者区别,本节我们来讲解包装类. 包装类 我们知道在Java中有8中基本数据类型,分为数值类型:byte.short ...
- C++ float vs double
精度 相比 float ,double 从其名字上已经展示出,它的精度是前者的两倍,他们的精度分别为: float: 7 位数字 double: 15 位数字 可通过如下的示例看出,在重复进行计算时, ...
- Android Fragment 隐藏或显示时调用的生命周期方法
Fragment使用方式大体分两种: 大家要注意不同的Fragment使用方法,Fragment隐藏和显示调用的生命周期方法是不同的,以下是Fragment显示隐藏调用的方法: //判断是否展示—与V ...
- [Abp vNext 源码分析] - 5. DDD 的领域层支持(仓储、实体、值对象)
一.简要介绍 ABP vNext 框架本身就是围绕着 DDD 理念进行设计的,所以在 DDD 里面我们能够见到的实体.仓储.值对象.领域服务,ABP vNext 框架都为我们进行了实现,这些基础设施都 ...
- python django-admin.py startproject xxx 错误:from django.core import management
1. Python安装路径以及Python安装路径\Script文件夹,已经添加到PATH环境变量中. 2. 查看django 版本正常: import django print(django.__v ...
- canvas实现七巧板图案和粒子时钟
canvas实现七巧板 <canvas id="canvas" width="800" height="800"></ ...
- linux学习(五)用户与组管理命令,以及用户信息文件解释
目录 (1)/etc/passwd文件 (2)/etc/shadow passwd命令 userdel命令 usermod命令 groupadd @(用户与组管理命令) linux是一个多用户多任务的 ...