Skip to content
Java 集合与容器 · 第 1 篇 / 共 4 篇
领域编程与框架
专题Java 专题
当前序列Java 集合与容器
阅读位置第 1 篇 / 共 4 篇当前专题第 2 个序列 / 共 10 个序列

Java 集合怎么选:List、Set、Map 与常见实现的取舍

Java 集合最容易踩的坑,不是不会写,而是选型太随手。

很多项目里集合都能跑,但一旦数据量变大、并发上来或者顺序要求变复杂,问题就会慢慢出现。

先说结论

先记住一套够用的默认判断:

  • 需要按下标访问、读多写少,优先 ArrayList
  • 需要去重,优先 HashSet
  • 需要键值映射,优先 HashMap
  • 需要保留插入顺序,优先 LinkedHashMap
  • 需要排序,考虑 TreeMap
  • 并发读写共享 Map,优先 ConcurrentHashMap

真正需要 LinkedList 的业务场景,其实远比想象中少。

一、先按接口理解集合

集合大致先分三类:

  • List:有序、可重复
  • Set:无重复
  • Map:键值对映射

先定接口,再选具体实现,通常会更清楚。

二、List 怎么选

1. ArrayList

大多数情况下,它都是默认首选。

优点:

  • 连续内存,随机访问快
  • 遍历性能通常更好
  • API 直观,使用成本低

注意点:

  • 中间位置插入和删除,需要搬移元素
  • 扩容会带来数组复制成本

适合:

  • 读多写少
  • 结果集、分页数据、内存列表处理

2. LinkedList

很多教程会说它“增删快”,但这句话很容易让人误解。

更准确地说:

  • 只有在你已经拿到目标节点位置时,局部插入删除才更有优势
  • 如果还是要先遍历定位,整体不一定比 ArrayList 更快

再加上:

  • 随机访问慢
  • 节点对象额外占内存
  • CPU 缓存友好性差

所以普通业务里,它并不是默认优选。

更适合:

  • 需要双端队列语义
  • 频繁头尾插入删除

三、Set 怎么选

1. HashSet

本质上底层依赖 HashMap

适合:

  • 去重
  • 判断元素是否存在

不保证顺序。

2. LinkedHashSet

如果你既想去重,又希望保留插入顺序,可以用它。

3. TreeSet

如果你需要元素自动排序,可以考虑 TreeSet

代价是:

  • 插入、删除、查询成本通常高于哈希结构
  • 元素需要可比较,或者提供比较器

四、Map 怎么选

1. HashMap

默认首选。

适合:

  • 绝大多数普通键值映射场景

注意:

  • 无序
  • 线程不安全

2. LinkedHashMap

如果你需要保留插入顺序,或者做简单 LRU 思路的缓存容器,它很实用。

3. TreeMap

按 key 排序。

适合:

  • 范围查询
  • 有序输出

4. ConcurrentHashMap

并发环境下共享 Map 的默认优选。

相比老的 Hashtable

  • 并发性能更好
  • 锁粒度更细
  • 更适合高并发读写

五、几个高频误区

1. 线程安全就直接用 Hashtable

现在大多数场景下,更该优先考虑 ConcurrentHashMap

2. 觉得 LinkedList 一定更适合增删

如果你的操作模式还是“查到位置再增删”,它未必更快。

3. 把集合当缓存,但不考虑上限

很多内存问题,最后根源就是一个 Map 一直塞数据却没有淘汰策略。

4. 需要有序,却默认用了 HashMap

如果顺序真有业务意义,要显式使用 LinkedHashMapTreeMap

六、工程里更实用的选择方式

如果只是做普通业务开发,可以先用这套默认思路:

  • List 默认 ArrayList
  • Set 默认 HashSet
  • Map 默认 HashMap
  • 需要顺序用 LinkedHashMap
  • 需要并发用 ConcurrentHashMap
  • 需要排序再考虑 TreeMap

只有当数据结构语义真的明确匹配时,再选 LinkedListTreeSet 这类更特殊的实现。

一句话总结

集合选型最重要的不是背实现细节,而是先想清楚业务到底要什么:

  • 要不要重复
  • 要不要顺序
  • 要不要排序
  • 会不会并发访问

把这四件事想清楚,绝大多数集合选型都不会太偏。

延伸阅读相关文章优先当前专题,再补跨专题关联。
同一序列 · 顺着当前主线继续读ArrayList 为什么仍然是默认首选适合把集合选型、ArrayList、HashMap 和 ConcurrentHashMap 放在一条线上理解。Java 专题 · Java 集合与容器同一序列 · 顺着当前主线继续读HashMap 和 ConcurrentHashMap 怎么选适合把集合选型、ArrayList、HashMap 和 ConcurrentHashMap 放在一条线上理解。Java 专题 · Java 集合与容器同专题其他序列 · 共享标签:集合、选型对比Collections.synchronizedList 和 CopyOnWriteArrayList 怎么选适合把链表、集合、有序结构、并发容器和迭代语义放到同一条集合主线里看。Java 专题 · Java 集合边界与容器取舍同专题其他序列 · 共享标签:选型对比锁与 CAS 怎么选适合沿着 JUC、volatile、CAS、AQS 和锁实现这条主线往下看。Java 专题 · Java 并发与锁机制跨专题关联 · 同场景:方案选型半同步复制和异步复制怎么选适合把 next-key lock、一致性读、复制延迟和分库分表边界放回同一条一致性主线上判断。MySQL 专题 · MySQL 事务、锁与高可用边界跨专题关联 · 同场景:方案选型分词器、Tokenizer 和 IK 到底怎么选适合把分词、复杂查询和深分页放到一起深入看。Elasticsearch 专题 · Elasticsearch 查询与分析细节
继续阅读Java 集合与容器当前序列第 1 篇 / 共 4 篇当前专题第 2 个序列 / 共 10 个序列
往前看
上一序列Java 语言基础与运行时从第 1 篇开始:String 到底能有多长
往后看
下一篇ArrayList 为什么仍然是默认首选继续当前序列下一章下一序列Java 并发与锁机制从第 1 篇开始:JUC 总览

把零散经验整理成可查、可复用、可持续更新的企业级知识门户