核心区别
- List (列表)
- 核心特性:有序集合,允许重复元素。
- 行为: 用户可以根据元素的整数索引(位置)访问元素。可以精确控制每个元素在列表中的位置。支持在指定位置插入和删除元素。
- 典型实现:
ArrayList,LinkedList,Vector。
- Set (集合)
- 核心特性:无序集合,不允许重复元素(唯一性)。
- 行为: 不保证元素的顺序(某些特定实现如
LinkedHashSet或TreeSet会维护某种顺序)。最重要的操作是检查一个元素是否存在于集合中(contains)。 - 典型实现:
HashSet,LinkedHashSet,TreeSet。
- Map (映射)
- 核心特性:键值对(Key-Value Pair)的集合。键(Key)唯一,值(Value)可重复。
- 行为: 通过键来访问值。一个映射不能包含重复的键。每个键最多只能映射到一个值。
- 典型实现:
HashMap,LinkedHashMap,TreeMap,Hashtable。
简单对比表:
| 接口 | 元素特性 | 顺序保证 | 元素唯一性 | 访问方式 |
|---|---|---|---|---|
| List | 单个对象 | 有序 | 可重复 | 索引 (get(int)) |
| Set | 单个对象 | 无序 | 唯一 | 元素本身 |
| Map | 键值对 (K, V) |
键无序/有序 | 键唯一 | 键 (get(K)) |
主要实现类
- List 实现类
ArrayList- 底层: 基于动态数组实现。
- 特点:
- 支持随机访问(通过索引快速访问元素,时间复杂度 O(1))。
- 在列表尾部插入和删除元素效率较高(接近 O(1))。
- 在列表中间插入和删除元素效率较低(需要移动元素,时间复杂度 O(n))。
- 非线程安全。
LinkedList- 底层: 基于双向链表实现。
- 特点:
- 不支持高效的随机访问(需要遍历链表,时间复杂度 O(n))。
- 在任意位置插入和删除元素效率较高(时间复杂度 O(1),只需修改节点指针)。
- 实现了
Deque接口,可用作队列或双端队列。 - 非线程安全。
Vector- 底层: 基于动态数组实现。
- 特点:
- 是 Java 早期集合类。
- 所有方法默认使用
synchronized修饰,是线程安全的。 - 性能通常不如
ArrayList(因为同步开销)。 - 有一个子类
Stack(栈)。
- Set 实现类
HashSet- 底层: 基于
HashMap实现(值存储在一个HashMap的键上)。 - 特点:
- 无序(不保证迭代顺序)。
- 添加、删除、判断元素是否存在(
contains)效率很高(时间复杂度接近 O(1))。 - 非线程安全。
- 底层: 基于
LinkedHashSet- 底层: 继承自
HashSet,内部使用LinkedHashMap实现。 - 特点:
- 维护了一个双向链表来记录元素的插入顺序。
- 迭代时按照元素的插入顺序访问。
- 性能略低于
HashSet(因为要维护链表)。 - 非线程安全。
- 底层: 继承自
TreeSet- 底层: 基于
TreeMap实现(值存储在一个TreeMap的键上)。 - 特点:
- 元素会根据自然排序 或指定的
Comparator进行排序。 - 迭代时按照排序后的顺序访问。
- 添加、删除、判断元素是否存在(
contains)基于红黑树,时间复杂度为 O(\\log n)。 - 非线程安全。
- 元素会根据自然排序 或指定的
- 底层: 基于
- Map 实现类
HashMap- 底层: 基于哈希表(数组+链表/红黑树)实现。
- 特点:
- 键无序(不保证迭代顺序)。
- 添加、删除、获取键值对效率很高(时间复杂度接近 O(1))。
- 允许
null作为键和值。 - 非线程安全。
- 重要: JDK 1.8 引入了链表长度超过阈值转红黑树的优化。
LinkedHashMap- 底层: 继承自
HashMap,内部维护了一个双向链表。 - 特点:
- 可以维护键的插入顺序 或访问顺序(LRU 缓存常用)。
- 迭代时按照链表的顺序访问(插入顺序或访问顺序)。
- 性能略低于
HashMap(因为要维护链表)。 - 非线程安全。
- 底层: 继承自
TreeMap- 底层: 基于红黑树(一种自平衡二叉搜索树)实现。
- 特点:
- 键会根据自然排序 或指定的
Comparator进行排序。 - 迭代时按照键排序后的顺序访问。
- 添加、删除、获取键值对基于红黑树,时间复杂度为 O(\\log n)。
- 不允许
null作为键(如果使用自然排序)。 - 非线程安全。
- 键会根据自然排序 或指定的
Hashtable- 底层: 基于哈希表实现。
- 特点:
- 是 Java 早期集合类,与
Vector类似。 - 所有方法默认使用
synchronized修饰,是线程安全的。 - 性能通常不如
HashMap(因为同步开销)。 - 不允许
null作为键或值。 - 现在通常更推荐使用
ConcurrentHashMap替代它来实现线程安全。
- 是 Java 早期集合类,与
线程安全注意事项
ArrayList,LinkedList,HashSet,LinkedHashSet,TreeSet,HashMap,LinkedHashMap,TreeMap都是非线程安全的。Vector,Hashtable是线程安全的(但通常性能较低)。- 对于
List和Set,可以使用Collections.synchronizedList()或Collections.synchronizedSet()包装非线程安全的集合来获得线程安全版本。 - 对于
Map,可以使用Collections.synchronizedMap()包装非线程安全的Map,或者更推荐使用ConcurrentHashMap(它是专门设计的高并发Map实现)。