惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

GbyAI
GbyAI
博客园 - 三生石上(FineUI控件)
S
Securelist
U
Unit 42
The Cloudflare Blog
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
Simon Willison's Weblog
Simon Willison's Weblog
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
B
Blog
T
Tenable Blog
The Hacker News
The Hacker News
The Register - Security
The Register - Security
IT之家
IT之家
博客园 - 【当耐特】
Spread Privacy
Spread Privacy
P
Privacy & Cybersecurity Law Blog
博客园_首页
T
Tailwind CSS Blog
人人都是产品经理
人人都是产品经理
C
Cybersecurity and Infrastructure Security Agency CISA
Know Your Adversary
Know Your Adversary
NISL@THU
NISL@THU
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
阮一峰的网络日志
阮一峰的网络日志
T
Tor Project blog
C
CERT Recently Published Vulnerability Notes
Apple Machine Learning Research
Apple Machine Learning Research
Stack Overflow Blog
Stack Overflow Blog
T
Threat Research - Cisco Blogs
T
The Exploit Database - CXSecurity.com
V
Vulnerabilities – Threatpost
A
Arctic Wolf
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
V
V2EX
aimingoo的专栏
aimingoo的专栏
大猫的无限游戏
大猫的无限游戏
Scott Helme
Scott Helme
L
LINUX DO - 热门话题
Cyberwarzone
Cyberwarzone
V
Visual Studio Blog
月光博客
月光博客
爱范儿
爱范儿
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
美团技术团队
G
GRAHAM CLULEY
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
H
Heimdal Security Blog
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO

咸糖 - 自律者自由

2025 年终总结:降噪、重构与长期主义 在新加坡和新山吃过最好的食物(持续更新) 写给还在迷茫的你:我的三本大学回忆 2024 年终总结 Neovim: No Crash Incremental Selection 2022 年终总结 使用 neovim 作为 PDE(个性化开发环境) shell 是一个不错的生产力工具 使用二八法则省力地学习 awk 肉身翻墙新加坡安顿指南 使用 Docker Compose 建立你自己的开发环境 关于编写可维护的代码的一些实践与想法 我为什么使用双向链接做笔记? 关于焦虑和拖延症 Golang: 如何处理日渐膨胀的 interface 使用番茄工作法来更好的利用你的时间 Unix 如何杀死一个进程和它的子孙进程? Golang: 让你的零值更有用 使用 Mock 和 Interface 进行 Golang 单测 关于 Golang Slice 的一些细节 总结一些计算机常用的原则 重新学习英语语法 上班族近期小半年入门投资基金组合的学习与实践经历 疫情期间的肉身翻墙新加坡指南 About me 软技能:大厂底层员工打工指南 软技能:我是如何获取知识与信息的? 分布式的令牌桶算法的实现 实现一个AtomicInteger GC root 在哪里? 什么是 Minor GC/Major GC 漏桶算法的设计与实现 剑指offer 单例模式 TCP 针对面试学习 Actor 如何处理阻塞消息 Akka 源码解析 How to learn scala AES 需要限制 SEED 长度 Java 如何区分==与.equals()方法 2018年年度总结
Java 集合扩容
xiantang · 2018-12-07 · via 咸糖 - 自律者自由

文章目录

【注意】最后更新于 December 29, 2025,文中内容可能已过时,请谨慎使用。

集合扩容

ArrayList

对于 ArrayList 他默认的容量为 10,所以如果需要对 ArrayList 进行大数据量的处理的时候的话,就需要使用显式制定容量的方式进行处理。这样可以减少不必要的扩容操作。

主要是因为 ArrayList 的扩容操作需要额外开辟空间,他采用的是 Arrays.copyOf 的方式进行拷贝:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
private void grow(int minCapacity) {
  // overflow-conscious code
  int oldCapacity = elementData.length;
  int newCapacity = oldCapacity + (oldCapacity >> 1);
  if (newCapacity - minCapacity < 0)
    newCapacity = minCapacity;
  if (newCapacity - MAX_ARRAY_SIZE > 0)
    newCapacity = hugeCapacity(minCapacity);
  // minCapacity is usually close to size, so this is a win:
  elementData = Arrays.copyOf(elementData, newCapacity);
}

Arrays.copyOf 的方式是采用开辟空间再复制的方式,很有可能会造成 OOM。

HashMap

HashMap 的默认容量为 16,并且他的容量一定是 2 的幂。

如果指定的容量不是 2 次幂,他也会求出距离当前容量最近的 2 次幂。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
    /**
     * Returns a power of two size for the given target capacity.
     */
    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;
    }

至于为什么是 2 的幂,是因为 SUN 的大师们发现,让容量为 2^n 时候,(length - 1) & hash 快于模运算。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
    @Test
    public void testModAndWith() {
        long currentTimeMillis = System.currentTimeMillis();
        for (int i = 0; i < 10000000; i++) {
            int i1 = 6666 % 16;
            assertEquals(10, i1);
        }
        long l = System.currentTimeMillis() - currentTimeMillis;
        System.out.println("使用%时间: " + l);
        long currentTimeMillis1 = System.currentTimeMillis();
        for (int i = 0; i < 10000000; i++) {
            int i1 = 6666 & (16-1);
            assertEquals(10, i1);
        }
        long l1 = System.currentTimeMillis() - currentTimeMillis1;
        System.out.println("使用&时间: " + l1);

    }

使用%时间:16 使用&时间:9

我们以 length 为 16 为例

当我们的 hash 为17时

原因是因为 16 - 1 的二进制为 01111 并且 17 的二进制为 1 0001
我们只需要计算低位,高位全部舍弃,低位进行 & 运算,得出结果是 1 与 17 % 16 的结果完全相同。

文章作者 xiantang

上次更新 2025-12-29 (4c152d04)

赞赏支持

微信打赏 支付宝打赏