ArrayList / HashMap / ConcurrentHashMap

这三大集合是 Java 面试和实际开发的必考点。下面我用面试视角 + 源码本质帮你快速理清它们的核心差异和底层原理。

一、ArrayList:动态数组的本质

核心:数组 + 扩容机制

1️⃣ 底层结构

transient Object\[\] elementData;

• 本质是 Object 数组

• size ≠ length(size 是实际元素个数)

2️⃣ 扩容机制(重点)

• 初始容量:

• new ArrayList<>() → 空数组(懒加载)

• 第一次 add 才扩容为 10

• 扩容公式:

int newCapacity = oldCapacity + (oldCapacity >> 1); // 1.5 倍

• 扩容代价高:要拷贝数组(System.arraycopy)

✅ 最佳实践

List list = new ArrayList<>(1000); // 预估容量,减少扩容

二、HashMap:Java 中最复杂的集合

核心:数组 + 链表 + 红黑树(JDK 8+)

1️⃣ 底层结构

Node<K,V>\[\] table

├── Node(链表)

└── TreeNode(红黑树)

2️⃣ 核心参数

参数 含义

默认容量 16

负载因子 0.75

树化阈值 链表长度 ≥ 8

树退化 ≤ 6

3️⃣ put 流程(高频面试题)

  1. 计算 hash:(h = key.hashCode()) ^ (h >>> 16)

  2. 判断 table 是否为空 → 初始化

  3. 计算下标:(n - 1) & hash

  4. 无冲突 → 直接插入

  5. 有冲突:

    • 链表 → 追加

    • 链表过长 → 树化

  6. size > threshold → 扩容(2 倍)

4️⃣ 为什么线程不安全?

• 并发 put 可能:

• 数据覆盖

• 死循环(JDK 7 及以前)

• size 不准

✅ 线程安全替代

• Collections.synchronizedMap

• ConcurrentHashMap

三、ConcurrentHashMap:高并发下的王者

核心目标:高并发 + 高吞吐

1️⃣ JDK 7 vs JDK 8(重点)

版本 实现

JDK 7 Segment 分段锁(16 把锁)

JDK 8+ CAS + synchronized(锁粒度更细)

2️⃣ JDK 8 实现原理

Node<K,V>\[\] table

├── 链表

└── 红黑树

• 锁粒度:只锁当前桶(头节点)

• 读操作:完全无锁(volatile + Unsafe)

3️⃣ put 核心流程

  1. 定位桶
  2. 桶为空 → CAS 插入
  3. 桶不为空 → synchronized 锁头节点
  4. 链表 / 红黑树插入
  5. 判断是否树化

4️⃣ size() 怎么实现的?

• 不用全局锁

• 使用 CounterCell + baseCount

• 最终值 ≈ 近似值(高并发下允许误差)

四、三者对比总结(面试必背)

对比项 ArrayList HashMap ConcurrentHashMap

数据结构 数组 数组 + 链表 + 红黑树 数组 + 链表 + 红黑树

线程安全 ❌ ❌ ✅

扩容 1.5 倍 2 倍 2 倍

锁 无 无 CAS + synchronized

适用场景 顺序存储 KV 存储 高并发 KV

五、面试高频追问(你可以提前准备)

✅ HashMap 为什么长度是 2 的幂?

→ 位运算 (n - 1) & hash 分布更均匀

✅ 为什么负载因子是 0.75?

→ 时间与空间的平衡(泊松分布)

✅ ConcurrentHashMap 能完全替代 Hashtable 吗?

→ 几乎可以,但 size() 不是强一致

✅ 为什么不用 synchronized 锁整个 Map?

→ 并发度太低,性能差

相关推荐
CRMEB系统商城1 分钟前
家电零售的供应商协同与物流提效
java·开发语言·人工智能·小程序·1024程序员节
jason.zeng@15022075 分钟前
Nginx 配置详解(静态 HTML、下载目录、API 反向代理三套场景)
java·vue.js·1024程序员节
鬼手点金6 分钟前
从 API 消息到模型 Token:Chat Template
java·前端·javascript·数据库·人工智能·深度学习·1024程序员节
Shadow(⊙o⊙)10 分钟前
LangChain 自定义工具全解析:从 @tool 到 bind_tools 的完整调用链路
java·服务器·前端·1024程序员节
王大师王文峰14 分钟前
Java+AI 面试题(二):业务场景设计 10 例【客服机器人、合同审查、Text2SQL、告警降噪、成本优化】场景题答法与追问链路
java·开发语言·人工智能
言乐623 分钟前
Python实现三轴联动根据数据自动打磨镜片模型
开发语言·python
CHHH_HHH40 分钟前
【Linux网络篇】初识网络与Socket编程基础
linux·服务器·c语言·开发语言·网络·后端·1024程序员节
弦儿41 分钟前
后端 Web 实战:员工管理(新增员工 + 事务管理 + 文件上传)
java·后端
jimy11 小时前
C++ 中 xvalue 的 identity 存在哪里?和 lvalue 的 identity 有什么区别?
开发语言·c++·1024程序员节
yujunl1 小时前
U9 无授权的模式WebAPI开发的总结
开发语言·1024程序员节