基础
之前写过一个比较粗糙的版本:Java集合概述
本文章补充了Java集合体系当中的一些细节
Collection接口的方法
List接口,Set接口都会继承这些方法
List接口
特点:存取顺序有序(因为有下标),可重复(元素之间由下标区分)
List的中间插入/删除方法会导致后续元素移动
ListIterator相比于Iterator高级的地方是可以反向遍历(因为list有下标),而且可以执行add并发操作(但是add的结果本次遍历不生效,下一次可以)
Java 中的集合框架(Collection Framework)是 Java 标准库的一部分,提供了用于存储和操作一组对象的统一架构。集合框架的核心接口是 java.util.Collection
,它是所有集合类的基础接口。以下是 Collection
接口及其主要实现类的详细介绍。
Collection 接口
Collection
是集合框架的根接口,定义了集合的基本操作,如添加、删除、遍历等。它继承自 Iterable
接口,因此所有集合类都支持迭代操作。
主要方法
- 添加元素:
boolean add(E e)
: 添加一个元素。boolean addAll(Collection<? extends E> c)
: 添加一个集合中的所有元素。
- 删除元素:
boolean remove(Object o)
: 删除指定元素。boolean removeAll(Collection<?> c)
: 删除与指定集合中相同的所有元素。void clear()
: 清空集合。
- 查询操作:
boolean contains(Object o)
: 判断集合是否包含指定元素。boolean containsAll(Collection<?> c)
: 判断集合是否包含指定集合中的所有元素。boolean isEmpty()
: 判断集合是否为空。int size()
: 返回集合中元素的数量。
- 遍历操作:
Iterator<E> iterator()
: 返回一个迭代器,用于遍历集合。
- 其他操作:
Object[] toArray()
: 将集合转换为数组。<T> T[] toArray(T[] a)
: 将集合转换为指定类型的数组。boolean retainAll(Collection<?> c)
: 仅保留与指定集合中相同的元素。
Collection 的子接口
Collection
接口有三个主要的子接口:
List
: 有序集合,允许重复元素。Set
: 无序集合,不允许重复元素。Queue
: 队列,支持先进先出(FIFO)或其他特定顺序的操作。
List 接口
List
是一个有序集合,允许存储重复元素。它通过索引访问元素,支持按位置插入、删除和修改元素。
主要实现类
-
ArrayList
:- 基于动态数组实现。
- 支持快速随机访问(通过索引)。
- 插入和删除元素效率较低(需要移动元素)。
- 线程不安全。
- 适用场景: 需要频繁访问元素的场景。
-
LinkedList
:- 基于双向链表实现。
- 插入和删除元素效率高(只需修改指针)。
- 随机访问效率低(需要遍历链表)。
- 实现了
Deque
接口,可以用作队列或栈。 - 适用场景: 需要频繁插入和删除元素的场景。
-
Vector
:- 基于动态数组实现,与
ArrayList
类似。 - 线程安全(方法使用
synchronized
修饰)。 - 性能较低(由于同步开销)。
- 适用场景: 需要线程安全的场景(已被
Collections.synchronizedList
取代)。
- 基于动态数组实现,与
-
Stack
:- 继承自
Vector
,实现栈数据结构(后进先出,LIFO)。 - 提供了
push
、pop
、peek
等栈操作。 - 适用场景: 需要栈操作的场景(推荐使用
Deque
替代)。
- 继承自
Set 接口
Set
是一个无序集合,不允许存储重复元素。它通常用于去重或判断元素是否存在。
主要实现类
-
HashSet
:- 基于哈希表实现。
- 插入、删除和查找操作的时间复杂度为 O(1)。
- 不保证元素的顺序。
- 适用场景: 需要快速查找和去重的场景。
-
LinkedHashSet
:- 继承自
HashSet
,基于哈希表和链表实现。 - 保留元素的插入顺序。
- 适用场景: 需要去重且保留插入顺序的场景。
- 继承自
-
TreeSet
:- 基于红黑树实现。
- 元素按自然顺序或自定义比较器排序。
- 插入、删除和查找操作的时间复杂度为 O(log n)。
- 适用场景: 需要有序集合的场景。
Queue 接口
Queue
是一个队列接口,支持先进先出(FIFO)或其他特定顺序的操作。
主要实现类
-
LinkedList
:- 实现了
Queue
和Deque
接口。 - 可以用作队列或双端队列。
- 适用场景: 需要队列或双端队列操作的场景。
- 实现了
-
PriorityQueue
:- 基于优先级堆实现。
- 元素按自然顺序或自定义比较器排序。
- 队首元素总是优先级最高的元素。
- 适用场景: 需要优先级队列的场景。
-
ArrayDeque
:- 基于动态数组实现的双端队列。
- 性能优于
LinkedList
。 - 适用场景: 需要高效的双端队列操作的场景。
其他集合类
除了 Collection
接口及其子接口的实现类,Java 集合框架还提供了一些其他重要的类和接口:
Map
接口:- 存储键值对(key-value pairs)。
- 主要实现类:
HashMap
、LinkedHashMap
、TreeMap
。
Collections
工具类:- 提供了对集合进行操作的工具方法,如排序、查找、同步等。
Arrays
工具类:- 提供了对数组进行操作的工具方法。
总结
List
: 有序集合,允许重复元素。常用实现类:ArrayList
、LinkedList
。Set
: 无序集合,不允许重复元素。常用实现类:HashSet
、LinkedHashSet
、TreeSet
。Queue
: 队列,支持 FIFO 或其他顺序。常用实现类:LinkedList
、PriorityQueue
、ArrayDeque
。
选择合适的集合类取决于具体的需求,如是否需要有序、是否允许重复、是否需要线程安全等。
Java中的Map
接口是java.util
包的一部分,用于存储键值对(Key-Value)。每个键(Key)唯一对应一个值(Value),键不可重复,但值可以重复。以下是Map
接口及其所有实现类的详细介绍:
一、Map接口核心方法
方法 | 说明 |
---|---|
put(K key, V value) | 插入键值对,若键已存在则覆盖旧值 |
get(Object key) | 根据键获取值,键不存在返回null |
containsKey(Object key) | 判断是否包含指定键 |
containsValue(Object value) | 判断是否包含指定值 |
remove(Object key) | 根据键删除键值对 |
keySet() | 返回所有键的集合(Set<K> ) |
values() | 返回所有值的集合(Collection<V> ) |
entrySet() | 返回所有键值对的集合(Set<Map.Entry<K, V>> ) |
size() | 返回键值对的数量 |
clear() | 清空所有键值对 |
二、Map的实现类及特点
1. HashMap
- 数据结构:基于哈希表(数组 + 链表/红黑树,Java 8优化)。
- 特点:
- 允许
null
键和null
值。 - 无序,不保证插入顺序。
- 线程不安全(需外部同步或使用
Collections.synchronizedMap
)。 - 查找、插入、删除操作的时间复杂度接近O(1)。
- 允许
- 适用场景:快速访问键值对,无需排序。
2. LinkedHashMap
- 数据结构:哈希表 + 双向链表。
- 特点:
- 继承自
HashMap
,保留插入顺序或访问顺序(通过构造参数accessOrder
控制)。 - 性能略低于
HashMap
,但迭代效率高(直接遍历链表)。
- 继承自
- 适用场景:需要保留插入顺序或LRU缓存(通过覆盖
removeEldestEntry
实现)。
3. TreeMap
- 数据结构:基于红黑树(自平衡二叉搜索树)。
- 特点:
- 键按自然顺序或自定义
Comparator
排序。 - 支持导航方法(如
firstKey()
,ceilingKey()
,floorEntry()
等)。 - 查找、插入、删除的时间复杂度为O(log n)。
- 键按自然顺序或自定义
- 适用场景:需要有序键的场景。
4. Hashtable
- 数据结构:类似
HashMap
的哈希表。 - 特点:
- 线程安全(方法用
synchronized
修饰),但性能较低。 - 不允许
null
键或null
值。 - 已过时,推荐使用
ConcurrentHashMap
替代。
- 线程安全(方法用
- 适用场景:遗留代码或需要同步的Map(不推荐新项目使用)。
5. ConcurrentHashMap
- 数据结构:分段锁(Java 7)或CAS +
synchronized
(Java 8优化)。 - 特点:
- 高并发线程安全,性能优于
Hashtable
。 - 不允许
null
键或null
值。 - Java 8后采用更细粒度的锁(每个桶单独锁)。
- 高并发线程安全,性能优于
- 适用场景:高并发环境下的键值存储。
6. WeakHashMap
- 数据结构:哈希表,键为弱引用。
- 特点:
- 当键不再被强引用时,键值对会被自动回收。
- 适合缓存临时数据。
- 适用场景:内存敏感的缓存,如临时对象映射。
7. EnumMap
- 数据结构:数组存储,键为枚举类型。
- 特点:
- 键必须为枚举类型,内部用枚举顺序优化存储。
- 性能高效,内存紧凑。
- 适用场景:枚举键的映射。
8. IdentityHashMap
- 数据结构:哈希表,使用
==
代替equals()
比较键。 - 特点:
- 键通过引用相等性(内存地址)判断唯一性。
- 适用于需要区分对象实例的场景。
- 适用场景:序列化、深拷贝等特殊场景。
9. Properties(特殊实现)
- 继承自:
Hashtable
,键值均为String
。 - 特点:
- 专用于读取
.properties
配置文件。 - 提供
load()
和store()
方法操作文件流。
- 专用于读取
- 适用场景:配置文件读写。
三、实现类对比表
实现类 | 线程安全 | 允许null键/值 | 排序 | 数据结构 | 时间复杂度 |
---|---|---|---|---|---|
HashMap | 否 | 是/是 | 无序 | 哈希表+链表/红黑树 | O(1) |
LinkedHashMap | 否 | 是/是 | 插入/访问顺序 | 哈希表+双向链表 | O(1) |
TreeMap | 否 | 否/是 | 自然或Comparator | 红黑树 | O(log n) |
Hashtable | 是 | 否/否 | 无序 | 哈希表 | O(1) |
ConcurrentHashMap | 是 | 否/否 | 无序 | 分段锁或CAS | O(1) |
WeakHashMap | 否 | 是/是 | 无序 | 哈希表(弱引用键) | O(1) |
EnumMap | 否 | 否/是 | 枚举顺序 | 数组 | O(1) |
IdentityHashMap | 否 | 是/是 | 无序 | 哈希表(引用相等) | O(1) |
四、选择建议
- 快速访问:
HashMap
(默认选择)。 - 有序键:
TreeMap
(自然排序)或LinkedHashMap
(插入/访问顺序)。 - 高并发:
ConcurrentHashMap
(替代Hashtable
)。 - 内存敏感缓存:
WeakHashMap
。 - 枚举键:
EnumMap
。 - 特殊相等性:
IdentityHashMap
。
通过理解各实现类的特性,可以更高效地选择合适的Map
实现以满足需求。