Java 集合框架:List 体系与实现类深度解析
Java-day13
引入
Java 集合框架是处理“批量数据”的核心工具,其中 **List 体系**以“有序、可重复”的特性,成为日常开发中最常用的集合类型。本文将围绕 List 接口的两大实现类 `ArrayList` 和 `LinkedList`,以及遗留类 `Vector` 展开,从**底层数据结构**、**核心方法**到**适用场景**,全面解析 List 集合的设计逻辑与实战技巧,帮助读者掌握“何时用何集合”的选型能力。
一、Java 集合框架概述
Java 集合框架主要分为四大体系:
- **Set**:无序、不可重复的集合;
- **List**:有序、可重复的集合(本文核心);
- **Map**:具有键值映射关系的集合;
- **Queue**:队列式集合(先进先出)。
其中,**List 是 Collection 接口的子接口**,它保证元素“按插入顺序排序”,支持通过索引直接操作元素,且允许元素重复。
二、ArrayList 集合:基于动态数组的 List 实现
2.1 ArrayList 底层原理与特点
- **数据结构**:内部封装了一个 `Object[]` 类型的**动态数组**,初始长度为 10,当数组容量不足时会**扩容(默认扩容为原容量的 1.5 倍)**;
- **核心特点**:
- 查询快(基于数组的索引随机访问),增删慢(增删元素需移动数组元素);
- 线程不安全,执行效率高;
- 元素类型为 `Object`,支持向上转型(如存储 `Cat`、`Dog` 等子类对象,体现多态)。
2.2 ArrayList 核心方法与实战
```java
import java.util.ArrayList;public class ArrayListDemo {public static void main(String[] args) {// 创建 ArrayList 集合(泛型指定为 String)ArrayList<String> list = new ArrayList<>();// 1. 添加元素:add()list.add("青城");list.add("博雅");System.out.println("添加元素后:" + list); // 输出:[青城, 博雅]// 2. 在指定位置插入元素:add(int index, Object element)list.add(1, "教育");System.out.println("指定位置插入后:" + list); // 输出:[青城, 教育, 博雅]// 3. 获取元素数量:size()System.out.println("元素数量:" + list.size()); // 输出:3// 4. 获取指定索引元素:get(int index)System.out.println("索引1的元素:" + list.get(1)); // 输出:教育// 5. 修改元素:set(int index, Object element)list.set(1, "QC");System.out.println("修改元素后:" + list); // 输出:[青城, QC, 博雅]// 6. 删除指定索引元素:remove(int index)list.remove(2);System.out.println("删除索引2后:" + list); // 输出:[青城, QC]// 7. 删除指定元素:remove(Object element)list.remove("青城");System.out.println("删除元素'青城'后:" + list); // 输出:[QC]// 8. 清空集合:clear()list.clear();System.out.println("清空后是否为空:" + list.isEmpty()); // 输出:true// 9. 遍历集合(三种方式)list.add("A");list.add("B");list.add("C");// 方式1:for 循环 + 索引for (int i = 0; i < list.size(); i++) {System.out.print(list.get(i) + " "); // 输出:A B C}System.out.println();// 方式2:增强 for 循环for (String s : list) {System.out.print(s + " "); // 输出:A B C}System.out.println();// 方式3:迭代器java.util.Iterator<String> it = list.iterator();while (it.hasNext()) {System.out.print(it.next() + " "); // 输出:A B C}}}```
2.3 ArrayList 适用场景
- 适合**查询操作频繁**、**增删操作较少**的场景(如数据展示、报表导出);
- 不适合多线程环境(需手动加锁或改用 `Vector`)。
三、LinkedList 集合:基于双向链表的 List 实现
3.1 LinkedList 底层原理与特点
- **数据结构**:内部封装了一个**双向链表**,每个节点包含“前驱节点引用”“元素值”“后继节点引用”;
- **核心特点**:
- 增删快(只需修改节点的引用指向),查询慢(需从链表头/尾遍历);
- 线程不安全;
- 除了 List 接口的方法,还提供了**操作链表头尾**的特有方法(如 `addFirst()`、`getLast()` 等)。
3.2 LinkedList 核心方法与实战
```java
import java.util.LinkedList;public class LinkedListDemo {public static void main(String[] args) {// 创建 LinkedList 集合(泛型指定为 Integer)LinkedList<Integer> list = new LinkedList<>();// 1. 添加元素:add()、addFirst()、addLast()list.add(1);list.add(2);list.addFirst(0);list.addLast(3);System.out.println("添加元素后:" + list); // 输出:[0, 1, 2, 3]// 2. 在指定位置插入元素:add(int index, Object element)list.add(2, 9);System.out.println("指定位置插入后:" + list); // 输出:[0, 1, 9, 2, 3]// 3. 获取元素:get(int index)、getFirst()、getLast()System.out.println("索引2的元素:" + list.get(2)); // 输出:9System.out.println("第一个元素:" + list.getFirst()); // 输出:0System.out.println("最后一个元素:" + list.getLast()); // 输出:3// 4. 修改元素:set(int index, Object element)list.set(2, 8);System.out.println("修改元素后:" + list); // 输出:[0, 1, 8, 2, 3]// 5. 删除元素:remove()、remove(int index)、removeFirst()、removeLast()list.remove(); // 删除第一个元素list.remove(2); // 删除索引2的元素System.out.println("删除后:" + list); // 输出:[1, 8, 3]// 6. 清空集合:clear()list.clear();System.out.println("清空后是否为空:" + list.isEmpty()); // 输出:true}}```
3.3 LinkedList 适用场景
- 适合**增删操作频繁**、**查询操作较少**的场景(如消息队列、历史记录);
- 利用其“链表头尾操作”的特性,可作为**栈(Stack)**或**队列(Queue)**的实现。
---
四、Vector 集合:遗留的线程安全 List 实现
4.1 Vector 底层原理与特点
- **数据结构**:基于**数组**实现,与 `ArrayList` 类似;
- **核心特点**:
- 线程安全(所有方法加了 `synchronized` 同步锁),执行效率低;
- 扩容机制为“原容量的 2 倍”(`ArrayList` 是 1.5 倍);
- 属于 Java 早期遗留类,**不建议在新代码中使用**(可改用 `ArrayList` 加手动锁,或使用 `ConcurrentArrayList`)。
4.2 Vector 核心方法示例
```java
import java.util.Vector;public class VectorDemo {public static void main(String[] args) {// 创建 Vector 集合Vector<String> vector = new Vector<>();// 添加元素vector.add("Apple");vector.addElement("Banana"); // 与 add() 功能类似,为遗留方法System.out.println("添加后:" + vector); // 输出:[Apple, Banana]// 访问元素System.out.println("索引1的元素:" + vector.get(1)); // 输出:BananaSystem.out.println("索引1的元素(遗留方法):" + vector.elementAt(1)); // 输出:Banana// 修改元素vector.set(1, "Cherry");System.out.println("修改后:" + vector); // 输出:[Apple, Cherry]// 删除元素vector.remove(1);vector.removeElement("Apple");System.out.println("删除后:" + vector); // 输出:[]}}```
五、List 集合选型与对比
| 集合类 | 底层结构 | 线程安全 | 查询效率 | 增删效率 | 适用场景 |
|---|---|---|---|---|---|
| ArrayList | 动态数组 | 不安全 | 高 | 低 | 查询多、增删少的场景 |
| LinkedList | 双向链表 | 不安全 | 低 | 高 | 增删多、查询少的场景 |
| Vector | 动态数组 | 安全 | 高 | 低 | 遗留系统维护、多线程(不推荐) |
六、总结:List 集合的核心要点
1. **ArrayList**:
- 基于动态数组,查询快、增删慢,线程不安全;
- 掌握 `add()`、`get()`、`set()`、`remove()` 等核心方法,以及三种遍历方式。
2. **LinkedList**:
- 基于双向链表,增删快、查询慢,线程不安全;
- 除 List 通用方法外,还需掌握 `addFirst()`、`getLast()` 等链表头尾操作方法。
3. **Vector**:
- 线程安全但效率低,属于遗留类,新代码中尽量避免使用。
4. **选型建议**:
- 优先考虑 `ArrayList`(性能优、使用广泛);
- 增删频繁场景选 `LinkedList`;
- 多线程场景需结合锁机制或改用并发集合(如 `CopyOnWriteArrayList`)。
通过本文的学习,相信你已对 Java List 集合的实现类有了全面理解。在实际开发中,需根据“查询/增删频率”“线程安全需求”等因素选择合适的集合,以达到最优性能。后续文章将解析 Set、Map 等其他集合体系,敬请关注。
