解析 hashMap 源码之位运算
时间:2022-07-24
本文章向大家介绍解析 hashMap 源码之位运算,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
计算索引
tab[i = (n - 1) & hash])
当 n == 2^x 的时候,(n - 1) & hash 与 hash % n 是等价的,但 (n - 1) & hash ( 位运算 )效率更高,因为 % 是通过 加法跟移位 来实现的
计算 hash 值
// 扰动函数
// 增加 hash 值的任意性,让高位参与到运算中来
static final int hash(Object key) {
int h;
return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
}
让高位参与运算,增加 hash 值的随意性
计算 tableSize
/**
* Returns a power of two size for the given target capacity.
*/
// 大于等于 cap 的 最小的 2 的幂次方
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;
}
什么意思呢? 我们假设 cap 分别为 3,127,5,64,*
3 0000 0011
-1 0000 0010
>>>1 0000 0001
| 0000 0011
>>>2 0000 0000
| 0000 0000
....
结果不变 1
127 0111 1111
-1 0111 1110
>>>1 0011 1111
| 0111 1111
>>>2 0001 1111
| 0111 1111
....
结果不变 128
5 0000 0101
-1 0000 0100
>>>1 0000 0010
| 0000 0110
>>>2 0000 0001
| 0000 0111
>>>3 0000 0000
| 0000 0111
....
结果不变 8
//这就是为什么要减一
64 0100 0000
-1 0011 1110
>>>1 0001 1111
| 0011 1111
>>>2 0000 1111
| 0011 1111
....
结果不变 64
更一般的
01** ****
-1 01** ****
>>>1 001* ****
| 011* ****
>>>2 0001 1***
| 0111 1***
>>>4 0000 0111
| 0111 1111
....
结果不变
0*** ****
-1 0*** ****
>>>1 00** ****
| 0*** ****
>>>2 000* ****
| 0*** ****
....
结果不变
其实最终的结果就是返回
大于等于 cap 的 最小的 2 的幂次方 此处一定为 2 的幂次方,与 (n - 1) & hash 相呼应
- hadoop压缩与解压
- cordova插件- Media
- JDK8之新特性扩展篇
- Java管理Cookie增删改查操作。
- Intellij Idea乱码解决方案都在这里了
- 神奇,教你用随机数打印hello world
- Mapreduce任务实现邮件监控
- Eclipse中Maven打包程序并在Linux中运行
- SDN开发笔记(七):L2switch源码分析(上)
- spark使用zipWithIndex和zipWithUniqueId为rdd中每条数据添加索引数据
- Spring Boot Server容器配置
- Spring Boot读取配置的几种方式
- 如何用TensorFlow构建RNN?这里有一份极简的教程
- (1024程序员节快乐)阿里祭出大器,Java代码检查插件
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- Python 基础(十五):枚举
- 一个老程序员的30年生涯回顾
- 经典 90 坦克大战 Python 版实现(支持单双人模式)
- Python 基础(十六):迭代器与生成器
- MySQL information_schema详解 COLUMNS
- MySQL information_schema详解 COLUMN_PRIVILEGES
- 一分钟学Python|Python的字典
- MySQL information_schema详解 ENGINES
- 一日一技:不用轮询,基于事件监控文件变动
- Python 基础(十七):装饰器
- XtraBackup工具详解 Part 10 使用innobackupex对数据库进行部分备份(指定表或数据库)
- Python 基础(十九):数学相关模块
- XtraBackup工具详解 Part 11 使用innobackupex对部分备份进行恢复
- XtraBackup工具详解 Part 12 流式和压缩备份
- 基于STM32+RT-Thread的新冠肺炎疫情监控平台