HashMap 详解二

简介: tableSizeFor 方法 初始化 HashMap 的长度大小, 会调用 tableSizeFor 方法赋值给 threshold // 构造函数 public HashMap(int initialCapacity, float loadFactor) { if (initialC.

tableSizeFor 方法

初始化 HashMap 的长度大小, 会调用 tableSizeFor 方法赋值给 threshold.

// 构造函数
public HashMap(int initialCapacity, float loadFactor) {
    if (initialCapacity < 0)
        throw new IllegalArgumentException("Illegal initial capacity: " +
                                           initialCapacity);
    if (initialCapacity > MAXIMUM_CAPACITY)
        initialCapacity = MAXIMUM_CAPACITY;
    if (loadFactor <= 0 || Float.isNaN(loadFactor))
        throw new IllegalArgumentException("Illegal load factor: " +
                                           loadFactor);
    this.loadFactor = loadFactor;

    //主要看这个
    this.threshold = tableSizeFor(initialCapacity);
}


// HashMap 要求长度是 2 的幂, 这个方法目的是返回大于等于 cap 的最小 2 的幂
// cap=0, 结果返回 1
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;
}

假设不减一

int n = cap - 1 目的是防止 cap 开始值就为 2 的幂, 结果就返回 cap 的 2 倍了, 实际应该返回 cap 才对,比如 cap = 0000 0001 0000 0000, 不执行减一就操作下面右移:
第一次右移
n |= n >>> 1;
n = 0000 0001 1000 0000
第二次右移
n |= n >>> 2;
n = 0000 0001 1110 0000
第三次右移
n |= n >>> 4;
n = 0000 0001 1111 1110
第四次右移
n |= n >>> 8;
n = 0000 0001 1111 1111
第五次右移
n |= n >>> 16;
n = 0000 0001 1111 1111

最后返回
n = n + 1 = 0000 0010 0000 0000 = 2 * cap


对于非 2 次幂

对于其他大小, 可以假设执行减一后是: 001x xxxx xxxx xxxx, 那么一系列右移后结果变成: 0011 1111 1111 1111, 然后执行加一操作就变成: 0100 0000 0000 0000 0000, 这个就是大于 cap 的最小 2 次幂了.


tableSizeFor 返回

关于这个方法的返回直接赋值给 threshold, 而不是乘以加载因子, 这个可以去看 resize 方法, 因为这里开始并没有初始化数组, 所以数组还是空, 当新增元素时就会调用 resize 方法, 里面会把 threshold 作为新的长度大小来初始化数组, 同时长度 * 加载因子会赋值给 threshold, 关于 resize 方法具体可以看下一 part.


相关文章
|
4天前
|
云安全 人工智能 安全
AI被攻击怎么办?
阿里云提供 AI 全栈安全能力,其中对网络攻击的主动识别、智能阻断与快速响应构成其核心防线,依托原生安全防护为客户筑牢免疫屏障。
|
13天前
|
域名解析 人工智能
【实操攻略】手把手教学,免费领取.CN域名
即日起至2025年12月31日,购买万小智AI建站或云·企业官网,每单可免费领1个.CN域名首年!跟我了解领取攻略吧~
|
8天前
|
安全 Java Android开发
深度解析 Android 崩溃捕获原理及从崩溃到归因的闭环实践
崩溃堆栈全是 a.b.c?Native 错误查不到行号?本文详解 Android 崩溃采集全链路原理,教你如何把“天书”变“说明书”。RUM SDK 已支持一键接入。
545 206
|
3天前
|
编解码 Linux 数据安全/隐私保护
教程分享免费视频压缩软件,免费视频压缩,视频压缩免费,附压缩方法及学习教程
教程分享免费视频压缩软件,免费视频压缩,视频压缩免费,附压缩方法及学习教程
220 138
|
存储 人工智能 监控
从代码生成到自主决策:打造一个Coding驱动的“自我编程”Agent
本文介绍了一种基于LLM的“自我编程”Agent系统,通过代码驱动实现复杂逻辑。该Agent以Python为执行引擎,结合Py4j实现Java与Python交互,支持多工具调用、记忆分层与上下文工程,具备感知、认知、表达、自我评估等能力模块,目标是打造可进化的“1.5线”智能助手。
746 54
|
6天前
|
人工智能 移动开发 自然语言处理
2025最新HTML静态网页制作工具推荐:10款免费在线生成器小白也能5分钟上手
晓猛团队精选2025年10款真正免费、无需编程的在线HTML建站工具,涵盖AI生成、拖拽编辑、设计稿转代码等多种类型,均支持浏览器直接使用、快速出图与文件导出,特别适合零基础用户快速搭建个人网站、落地页或企业官网。
989 157
|
4天前
|
存储 Linux iOS开发
最新学习教程,电脑剪贴板不够用!这几个方法教你更多复制粘贴超高效方法,并附上几个扩展工具供你学习
最新学习教程,电脑剪贴板不够用!这几个方法教你更多复制粘贴超高效方法,并附上几个扩展工具供你学习
216 136
下一篇
oss云网关配置