news 2026/4/16 2:38:37

Java集合框架详解

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Java集合框架详解

Java 集合框架详解(Java Collections Framework)

Java 集合框架(JCF)是 Java SE 中最核心的部分之一,位于java.util包下。它提供了一套统一的接口、抽象类和实现类,用于存储、管理和操作对象的集合(如列表、集合、映射等)。集合框架的核心目标是:高效类型安全易扩展

本文将从基础到高级,系统详解集合框架,包括架构、核心接口/类、常用方法、线程安全、性能分析、源码要点、常见问题及最佳实践。基于 Java 17+(2026 主流版本)的视角,结合实际开发经验。

一、集合框架整体架构

集合框架分为两大体系:

  1. Collection 接口:单值集合(元素是单个对象)。
    • 子接口:List(有序、可重复)、Set(无序、不重复)、Queue(队列)、Deque(双端队列)。
  2. Map 接口:键值对集合(key-value pairs,不继承 Collection)。

抽象类(如 AbstractList、AbstractSet)提供骨架实现,方便自定义扩展。

核心类图简述(文字版):

Collection (接口) ├── List (接口) │ ├── ArrayList │ ├── LinkedList │ └── Vector (遗留) ├── Set (接口) │ ├── HashSet │ ├── LinkedHashSet │ └── TreeSet (SortedSet/NavigableSet) ├── Queue (接口) │ ├── PriorityQueue │ └── ArrayDeque (Deque 接口实现) └── Map (接口) ├── HashMap ├── LinkedHashMap ├── TreeMap (SortedMap/NavigableMap) └── Hashtable (遗留)
  • 辅助类:Collections(工具类,提供排序、同步等)、Arrays(数组工具)。

二、核心接口与实现类详解

1. List 接口(有序、可重复)

  • 特点:支持索引访问、允许重复元素。
  • 常用实现
    • ArrayList(首选):底层动态数组(Object[]),随机访问 O(1),扩容机制(1.5 倍增长)。
    • LinkedList:底层双向链表,支持 Queue/Deque 接口,头尾操作 O(1),随机访问 O(n)。
    • Vector:类似 ArrayList 但线程安全(synchronized),性能差,已过时。

2. Set 接口(无序、不重复)

  • 特点:不允许重复(equals 判断),无索引。
  • 常用实现
    • HashSet:底层 HashMap(key 存元素),O(1) 平均操作。
    • LinkedHashSet:HashSet + 双向链表,保持插入顺序。
    • TreeSet:底层红黑树(TreeMap),自动排序,支持 NavigableSet 接口(ceiling/floor 等)。

3. Queue 接口(先进先出 FIFO)

  • 特点:用于任务调度、缓冲。
  • 常用实现
    • PriorityQueue:底层堆(数组),按优先级出队 O(log n)。
    • ArrayDeque:底层循环数组,双端队列,性能优于 LinkedList。

4. Map 接口(键值对)

  • 特点:key 唯一(equals + hashCode),value 可重复。
  • 常用实现
    • HashMap(首选):JDK8+ 数组 + 链表 + 红黑树(链表 >8 转树),负载因子 0.75。
    • LinkedHashMap:HashMap + 双向链表,支持插入/访问顺序(LRU 缓存)。
    • TreeMap:底层红黑树,按 key 排序,支持 NavigableMap(subMap 等)。
    • Hashtable:线程安全版 HashMap,已过时。

Java 9+ 新增:不可变集合,如 List.of()、Set.of()、Map.of(),用于快速创建只读集合。

三、常用方法汇总(以 Collection 和 Map 为例)

Collection 接口方法

方法类别示例方法描述
添加add(E e), addAll(Collection c)添加元素/集合
删除remove(Object o), clear()删除元素/清空
查询contains(Object o), size(), isEmpty()检查包含/大小/空
遍历iterator(), forEach(Consumer)迭代器/函数式遍历(Java 8+)
转换toArray()转数组

Map 接口方法

方法类别示例方法描述
添加/修改put(K key, V value), putAll(Map m)插入/覆盖键值对
删除remove(Object key), clear()删除键/清空
查询get(Object key), containsKey(K key)获取值/检查键
遍历keySet(), values(), entrySet()获取键集/值集/键值对集
Java 8+ 新增computeIfAbsent, merge函数式操作(如默认值)

示例代码(ArrayList + HashMap):

importjava.util.*;publicclassCollectionDemo{publicstaticvoidmain(String[]args){// List 示例List<String>list=newArrayList<>();list.add("apple");list.add("banana");list.add(1,"orange");// 插入到索引1System.out.println(list.get(0));// apple// Map 示例Map<Integer,String>map=newHashMap<>();map.put(1,"one");map.put(2,"two");System.out.println(map.get(1));// one// 遍历map.forEach((k,v)->System.out.println(k+": "+v));}}

四、线程安全与并发集合

标准集合(如 ArrayList、HashMap)非线程安全,多线程下可能 ConcurrentModificationException。

  • 遗留安全类:Vector、Hashtable(synchronized,全同步,性能低)。
  • 现代推荐(java.util.concurrent 包):
    • ConcurrentHashMap:分段锁 + CAS,读无锁,高并发首选。
    • CopyOnWriteArrayList:写时复制,读无锁,适合读多写少。
    • ConcurrentLinkedQueue:无锁队列,CAS 实现。
  • 同步包装:Collections.synchronizedList(list),但性能不如并发包。

示例

Map<String,String>safeMap=newConcurrentHashMap<>();safeMap.putIfAbsent("key","value");// 原子操作

五、性能分析与选择指南

性能对比表(平均复杂度)

集合类型添加删除查询遍历空间开销适用场景
ArrayListO(1) 摊销O(n)O(1)O(n)中等随机访问、尾部操作
LinkedListO(1)O(1)O(n)O(n)高(节点)频繁插入/删除
HashSet/MapO(1)O(1)O(1)O(n)中等快速查找、去重
TreeSet/MapO(log n)O(log n)O(log n)O(n)中等排序、范围查询
PriorityQueueO(log n)O(log n)O(1) peekO(n)中等优先级调度
  • HashMap 源码要点:hash = key.hashCode() ^ (h >>> 16),链表转树阈值 8,树转链表阈值 6。
  • 选择决策
    • 列表:99% 用 ArrayList,除非频繁头操作用 LinkedList/ArrayDeque。
    • 集合:去重用 HashSet,需要顺序用 LinkedHashSet,排序用 TreeSet。
    • 映射:普通用 HashMap,顺序用 LinkedHashMap,排序用 TreeMap。
    • 并发:一律 ConcurrentXXX。

六、常见问题与最佳实践

常见问题

  1. ConcurrentModificationException:遍历时修改集合。解决:用 Iterator.remove() 或 CopyOnWrite。
  2. Null 值:HashMap 允许 null key/value,TreeMap 不允许 null key。
  3. 扩容开销:ArrayList 默认容量 10,扩容 1.5 倍。建议预估大小:new ArrayList<>(100)
  4. equals 与 hashCode:自定义类做 key/set 元素,必须重写(否则不唯一)。
  5. 不可变集合:Java 9+ 用 List.of(),避免意外修改。

最佳实践(2026 主流)

  • 接口编程List<T> list = new ArrayList<>();(泛型 + 菱形运算符)。
  • 函数式:用 stream() 处理,如list.stream().filter(x -> x > 0).collect(Collectors.toList());
  • 大集合:用 Guava 或 Apache Commons 扩展(如 Multimap)。
  • 内存优化:大 Map 用 LinkedHashMap + removeEldestEntry 实现 LRU。
  • 避免遗留:别用 Vector/Hashtable,用并发包代替。
  • 测试:用 JUnit 测试集合行为,尤其是自定义 equals/hashCode。

七、扩展与高级主题

  • Java 8+ 增强:default 方法(如 Map.getOrDefault)、Stream API。
  • 自定义集合:继承 AbstractList 等,实现最小方法。
  • 序列化:集合实现 Serializable,但注意 transient 字段。
  • 与数组:Arrays.asList() 转 List,但固定大小。

集合框架是 Java 开发的基石,熟练掌握能显著提升代码效率和质量。如果想深入某个类源码(如 HashMap 的 resize)、具体示例代码,或与 Kotlin/Scala 集合对比,继续问我~

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/14 23:36:48

第 488 场周赛Q1——100985. 统计主导元素下标数

题目链接&#xff1a;100985. 统计主导元素下标数&#xff08;简单&#xff09; 算法原理&#xff1a; 解法&#xff1a;前缀和 1ms击败100.00% 时间复杂度O(N) 思路很简单&#xff0c;既然主导元素是看当前元素是否>后面所有数的平均数&#xff0c;那么我们只需要在遍历每个…

作者头像 李华
网站建设 2026/4/16 14:36:13

多TOA观测移动目标定位仿真:EKF、UKF、PF、EKPF解算比较

【19】多toa观测移动目标定位仿真 ekf ukf pf ekpf解算比较 在移动目标定位领域&#xff0c;基于到达时间&#xff08;TOA&#xff09;的定位方法是一种常见且有效的手段。今天咱们就来深入探讨一下使用扩展卡尔曼滤波&#xff08;EKF&#xff09;、无迹卡尔曼滤波&#xff08…

作者头像 李华
网站建设 2026/4/16 13:03:06

leetcode 困难题 927. Three Equal Parts 三等分-耗时100

Problem: 927. Three Equal Parts 三等分 耗时100%&#xff0c;可能存在前置0&#xff0c;所以逆向思考的&#xff0c;首先统计0、1频次&#xff0c;若1的个数不能被3整除则不可能返回-1&#xff0c;若没有1则返回{0, n-1}&#xff0c;每个二进制数字的1的个数都是ch[1]/3&…

作者头像 李华
网站建设 2026/4/16 13:04:42

照着用就行:专科生专属的降AI率网站 —— 千笔·降AI率助手

在AI技术迅速发展的今天&#xff0c;越来越多的学生开始借助AI工具辅助论文写作&#xff0c;提升效率与质量。然而&#xff0c;随着学术审查标准的不断提高&#xff0c;AI生成内容的痕迹越来越容易被查重系统识别&#xff0c;导致论文面临“AI率超标”的风险。这不仅影响论文通…

作者头像 李华
网站建设 2026/4/15 10:49:50

项目实践:XinServer 的备份恢复机制非常好用

项目实践&#xff1a;XinServer 的备份恢复机制非常好用 最近跟几个创业的朋友聊天&#xff0c;他们都在吐槽一件事&#xff1a;每次项目上线前&#xff0c;或者服务器要动点啥&#xff0c;心里就发毛。为啥&#xff1f;怕数据丢了呗。数据库备份这事儿&#xff0c;说大不大&am…

作者头像 李华