在 Java 中,集合类提供了多种数据结构以满足不同的使用场景。以下是对常见集合类及其底层数据结构的详细解释。
一、 List 接口的实现类
1. ArrayList:
- 底层数据结构:ArrayList 使用一个可动态调整大小的 Object[] 数组作为其底层数据结构。
- 特点:ArrayList 适合快速随机访问,因为底层是数组,可以通过索引直接访问元素。然而,在中间位置插入和删除元素时,可能需要移动大量元素,性能较低。
2. Vector:
- 底层数据结构:Vector 也基于 Object[] 数组。
- 特点:与 ArrayList 类似,但 Vector 是线程安全的,所有方法都被 synchronized 修饰,因此适合在多线程环境中使用。
3. LinkedList:
- 底层数据结构:LinkedList 使用双向链表实现。
- 特点:LinkedList 适合频繁的插入和删除操作,因为这些操作只涉及链表节点的指针调整,性能较高。与 ArrayList 相比,随机访问性能较低。在 JDK1.6 之前,LinkedList 是循环链表,JDK1.7 之后改为普通双向链表。
二、Set 接口的实现类
1. HashSet:
- 底层数据结构:HashSet 基于 HashMap 实现,其底层使用 HashMap 来保存元素。
- 特点:HashSet 是无序且唯一的集合,不允许重复元素。
2. LinkedHashSet:
- **底层数据结构**:LinkedHashSet 基于 LinkedHashMap 实现。
- **特点**:LinkedHashSet 是有序且唯一的集合,保留元素的插入顺序。
3. TreeSet:
- **底层数据结构**:TreeSet 使用红黑树(自平衡的排序二叉树)实现。
- **特点**:TreeSet 是有序且唯一的集合,元素按照自然顺序或自定义比较器排序。
三、Queue 接口的实现类
1. PriorityQueue:
- 底层数据结构:PriorityQueue 基于 Object[] 数组实现二叉堆。
- 特点:PriorityQueue 是优先级队列,元素按照优先级排序,默认使用最小堆实现。
2. ArrayDeque:
- **底层数据结构**:ArrayDeque 使用 Object[] 数组加上双指针实现。
- **特点**:ArrayDeque 是双端队列,支持从两端进行高效的插入和删除操作。
四、 Map 接口的实现类
1. HashMap:
- 底层数据结构:HashMap 在 JDK1.8 之前由数组和链表组成。JDK1.8 之后,当链表长度超过阈值(默认为 8)时,链表转换为红黑树以优化性能。
- 特点:HashMap 是无序的,允许 null 键和 null 值。
2. LinkedHashMap:
- 底层数据结构:LinkedHashMap 基于 HashMap 实现,但增加了一条双向链表。
- 特点:LinkedHashMap 保留键值对的插入顺序或访问顺序,继承了 HashMap 的所有特性。
3. Hashtable:
- 底层数据结构:Hashtable 使用数组和链表实现。
- 特点:Hashtable 是线程安全的,不允许 null 键和 null 值,类似于旧版的 HashMap。
4. TreeMap:
- 底层数据结构:TreeMap 使用红黑树(自平衡的排序二叉树)实现。
- 特点:TreeMap 是有序的,键值对按照键的自然顺序或自定义比较器排序。
五、总结
Java 集合框架提供了多种数据结构,每种都有其独特的特点和适用场景。ArrayList 和 Vector 使用数组作为底层结构,适合快速随机访问。LinkedList 使用双向链表,适合频繁的插入和删除操作。HashSet 和 LinkedHashSet 基于 HashMap,提供无序和有序的集合。TreeSet 使用红黑树,实现有序集合。PriorityQueue 使用数组实现优先级队列,ArrayDeque 使用数组实现双端队列。HashMap 和 LinkedHashMap 提供无序和有序的键值对存储,而 TreeMap 使用红黑树实现有序键值对存储。Hashtable 提供线程安全的键值对存储。