【HashMap】由tableSizeFor想到的一个算法

简介: 【HashMap】由tableSizeFor想到的一个算法
最近在看hashmap的源码,看到一个很有意思的函数,tableSizeFor,不禁想问,这个函数到底做了什么?
    static final int tableSizeFor(int var0) {
        int var1 = var0 - 1;
        var1 |= var1 >>> 1;
        var1 |= var1 >>> 2;
        var1 |= var1 >>> 4;
        var1 |= var1 >>> 8;
        var1 |= var1 >>> 16;
        return var1 < 0 ? 1 : (var1 >= 1073741824 ? 1073741824 : var1 + 1);
    }

我们先把函数源码摆上来,里面出现了几个关键的java运算符
\>>>:按位右移补零操作符。左操作数的值按右操作数指定的位数右移,移动得到的空位以零填充。
| :如果相对应位都是 0,则结果为 0,否则为 1。
清楚了运算符的作用,我们举例来说明:

var0为7
7的二进制: 0000 0111
var0-1=6 : 0000 0110
var1>>>1 : 0000 0011
var1 |= var1 >>> 1 : 0000 0110
var1 |= var1 >>> 2 : 0000 0111
后续操作结果一样
var1+1 = 8

从这个例子中,我们得出一个结论,这个函数做了以下操作:将原操作数-1,然后将二进制的第一个1之后的所有数变为1,最后返回,操作数+1
那这到底完成了什么功能呢?从上面的分析来看,是为了找出大于等于本身的值的最近的一个2的幂次方值,那为什么刚开始要减去一个1呢?稍等,我们通过另外一个例子说明一下

cap 8
0000 1000

0000 0100 n>>>1

0000 1100 n|n>>>1
0000 0011 n>>>2

0000 1100

0000 1111 n|n>>>2 低位全为1,后续操作结果一样

0000 0001 n+1

0001 0000 16
cap = 15 + 1 = 16

从这个例子上看到,如果原先操作数本身就是2的幂次方,不减去1,直接进行后续操作,那么最后+1之后,肯定会得到大于本身值的下一个2的幂次方。

总结

说到这里,其实大家已经看明白了,这个函数的作用就是为了找出大于等于每个输入值的,最接近的2的幂次方值。不得不说,JDK这里的这个小算法,还是设计挺巧妙的。

目录
相关文章
|
7月前
|
设计模式 算法 Java
面试官:JDK1.8 HashMap扩容rehash算法是如何优化的?
本文跟大家聊一聊一个常见的面试题,那就是JDK1.8 HashMap扩容rehash算法是如何优化的?
|
算法 Java 程序员
Java HashMap 在获得 Key 的 Hash 值的时候用的是什么算法
Java 在 HashMap Key 的 Hash 值的时候用的的是自己 Object 中的 hashCode() 算法。
141 0
|
存储 机器学习/深度学习 算法
算法系列(2)—— 简答一波 HashMap 常见八股面试题
算法系列(2)—— 简答一波 HashMap 常见八股面试题
139 0
算法系列(2)—— 简答一波 HashMap 常见八股面试题
|
存储 算法 容器
数据结构算法 - HashMap 源码解析
数据结构算法 - HashMap 源码解析
129 2
数据结构算法 - HashMap 源码解析
|
存储 算法 程序员
漫画:什么是HashMap? | 算法必看系列二十三
众所周知,HashMap是一个用于存储Key-Value键值对的集合,每一个键值对也叫做Entry。这些个键值对(Entry)分散存储在一个数组当中,这个数组就是HashMap的主干。那你知道HashMap默认的初识长度是多少?为什么这么规定?高并发情况下,为什么HashMap可能会出现死锁?在Java8当中,HashMap的结构有什么样的优化?本文将为你深度解读HashMap的灵魂三问!
漫画:什么是HashMap? | 算法必看系列二十三
|
算法
由HashMap哈希算法引出的求余%和与运算&转换问题
1、引出问题   在前面讲解 HashMap  的源码实现时,有如下几点:   ①、初始容量为 1>16   第三步:取模运算:(n-1) & hash 1 static final int hash(Object key) { 2 int h; 3 return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16); 4 } 5 6 tab[i = (n - 1) & hash];   ps:第 6 行代码是我自己加的。
1374 0
|
算法 Java
leetcode算法题解(Java版)-3-广搜+HashMap
题目很简单,考到了一个知识点——异或:比较两个操作数的二进制的各个位置,相同则为0不同则为1。所以,1.与0异或是本身2.与和自己一样的异或是0.
2040 0
|
存储 算法
Hash算法,及HashMap使用
为什么要Hash? 哈希表是基于数组实现的,哈希算法就是如何将键值(key)转换成数组小标的方法,哈希化可以提供非常高的操作(插入、删除、查询)效率,因为对有序数组的查询,即使是二分查找也只能做到O(logN),因为哈希可以直接将要查询的key转化为数组小标,所以可以达到O(1)的时间级。 Hash算法:将key做hash后的值叫hashcode,hashcode的值范围可能很大,
1348 0
|
6天前
|
算法 数据安全/隐私保护 计算机视觉
基于二维CS-SCHT变换和LABS方法的水印嵌入和提取算法matlab仿真
该内容包括一个算法的运行展示和详细步骤,使用了MATLAB2022a。算法涉及水印嵌入和提取,利用LAB色彩空间可能用于隐藏水印。水印通过二维CS-SCHT变换、低频系数处理和特定解码策略来提取。代码段展示了水印置乱、图像处理(如噪声、旋转、剪切等攻击)以及水印的逆置乱和提取过程。最后,计算并保存了比特率,用于评估水印的稳健性。