Java 集合
Java 集合用于组织对象、查找数据,并按指定规则取出元素。本栏目面向 Java 后端面试准备,第一轮先学习容器选择,再掌握 ArrayList 的操作成本和 HashMap 的查找机制。
Java 后端 · 核心阅读
按下面的范围阅读,能解释对应问题后,自行选择下一篇或深入内容。
- 01Java 集合框架
根据顺序、去重、键值查找和取出规则选择容器,并说明依据。
先读第 1—6 节,掌握接口语义与基本选型。 - 02ArrayList
解释随机访问、追加、扩容和中间插入的成本,区分单次操作与摊销复杂度。
先读第 1—5 节和第 7 节,掌握存储、操作成本和线程边界;subList 留到后续。 - 03HashMap
沿 put/get 解释定位与比较,说明键的相等性、扩容原因和共享修改限制。
先读第 1—5 节,掌握查找、键相等、冲突、扩容和使用边界;具体阈值与位运算推导后续再看。
代表题与停止条件
先尝试解释,再打开原文中的参考回答。能说明机制与边界即可继续。
List、Set、Map 分别适合什么场景?
根据顺序、去重、键值查找和取出规则选择容器,并说明依据。
ArrayList 怎样扩容,指定初始容量有什么作用?
解释随机访问、追加、扩容和中间插入的成本,区分单次操作与摊销复杂度。
说明 HashMap 的 put 和 get 路径。
沿 put/get 解释定位与比较,说明键的相等性、扩容原因和共享修改限制。
1. 关键结论
- 容器选择:List 保留元素位置并允许重复,Set 用于去重,Map 保存键值关联。需要按规则取出元素时,可以使用 Queue 或 Deque。因此,选择前要明确顺序、去重和查找要求,见Java 集合框架。
- ArrayList 的操作成本:数组支持按索引直接定位,容量足够时,尾部追加也无需移动已有元素。扩容要复制数组,中间插入则要搬移后续引用。所以,要区分单次操作的耗时和多次操作平均分摊的成本,见 ArrayList。
- HashMap 的查找机制:哈希先缩小候选范围,再通过相等性比较确认键。相同哈希可以对应不同键,自定义键中参与比较的字段也要保持稳定。平均查询性能依赖哈希分布,固定遍历顺序和并发写入则需要另选实现或增加同步,见 HashMap。
如果还不熟悉数组、链表或哈希表,可以先补充数据结构。需要理解键为什么相等时,回看对象相等性。
2. 后续复习
第二轮:常考与追问
- LinkedList:区分定位元素和修改节点的成本,说明已经持有迭代位置时的操作前提。
- TreeMap 与 TreeSet:补充有序查询、比较器与范围操作。
- 集合迭代器:补充遍历时修改、fail-fast、不可修改视图和不可变副本。
- HashMap:继续解释容量选择、树化条件和扩容后的节点迁移。
按场景补充:访问顺序与并发集合
项目需要按访问顺序遍历,或淘汰最久未访问的缓存条目时,阅读 LinkedHashMap。后者称为 LRU 淘汰策略。
需要多线程共享容器时,先学习Java 并发编程,再按读写需求选择:
- 需要并发查询和更新键值对时,阅读 ConcurrentHashMap。
- 列表较小、读取远多于更新,且允许遍历旧快照时,阅读 CopyOnWrite 容器。
- 需要在线程间传递任务,并在队空或队满时等待,阅读 BlockingQueue。