前面八篇我们学完了Java基础语法、面向对象、抽象类、接口、异常、常用工具类。到这里,你已经具备了Java基础全部能力。
但是!数组根本无法用于真实开发。
为什么?
-
数组长度固定,不能扩容
-
删除元素需要手动前移,代码极其麻烦
-
无法快速查找、判断元素是否存在
-
真实业务数据数量不确定
所以Java给我们提供了一套集合框架,用来替代数组,存储、管理、操作一组数据。

本篇是集合第一篇 ,专门讲解最常用、工作必写、面试必考的 List 集合:ArrayList、LinkedList。全程通俗易懂、手绘逻辑、直白案例、无难懂源码,新手零基础也能看懂。
本篇核心目标:
-
明白集合是什么、集合和数组区别
-
看懂Java集合大家族架构图
-
精通List接口通用方法(增删改查)
-
透彻理解ArrayList底层、扩容机制
-
透彻理解LinkedList底层、链表结构
-
分清两者使用场景、面试高频区别
一、为什么要用集合?数组有什么缺点?
1.1 数组痛点直观举例
java
// 数组长度固定为3
String[] arr = new String[3];
arr[0] = "张三";
arr[1] = "李四";
arr[2] = "王五";
// 想再加一个人?报错!数组满了,不能扩容
arr[3] = "赵六";
数组致命缺点:长度不可变、增删麻烦、方法太少。
1.2 集合优势
-
长度可变,自动扩容
-
自带增、删、改、查、遍历、判断方法
-
支持任意数量的数据存储
-
提供丰富的数据结构:数组、链表、哈希表、树
二、Java集合大家族(架构图必看)
Java集合主要分为两大根接口:Collection(单列集合) 、Map(双列集合)。
2.1 集合整体架构(通俗总结)
-
Collection 单列集合(存一个一个元素)
-
List:有序、可重复、有索引(ArrayList、LinkedList、Vector)
-
Set:无序、不可重复(HashSet、TreeSet)
-
-
Map 双列集合(存键值对 key-value)
- HashMap、TreeMap
本篇只讲 List,下一篇讲 Set,后面讲 Map,循序渐进不蹦级。
三、List接口特点(必须背熟)
List 是所有单列有序集合的父接口。
3.1 List三大特点
-
有序:存入顺序和取出顺序一致
-
有索引:可以像数组一样通过下标取值
-
可重复:允许存放重复元素
3.2 List通用常用方法(全部实现类通用)
java
add() // 添加元素
remove() // 删除元素
set() // 修改元素
get() // 根据下标获取元素
size() // 获取集合长度
contains() // 判断是否包含元素
clear() // 清空集合
isEmpty() // 判断是否为空
四、ArrayList:最常用的动态数组
ArrayList = 动态扩容的数组,日常开发使用频率最高,占业务代码80%。
4.1 ArrayList底层原理
-
底层维护一个 Object[] 数组
-
默认初始容量:10
-
扩容机制:原容量1.5倍扩容
-
查询快、增删慢
4.2 ArrayList基础代码演示
java
import java.util.ArrayList;
public class Demo {
public static void main(String[] args) {
// 创建集合,存放字符串
ArrayList<String> list = new ArrayList<>();
// 新增
list.add("张三");
list.add("李四");
list.add("王五");
// 修改
list.set(1,"李老四");
// 删除
list.remove(2);
// 查询
System.out.println(list.get(0));
// 遍历
for (String s : list) {
System.out.println(s);
}
}
}
4.3 ArrayList扩容机制(面试高频)
新手通俗易懂版:
-
第一次创建集合,底层数组为空
-
添加第一个元素,数组初始化长度为10
-
装满10个之后,触发扩容
-
扩容:新建一个长度1.5倍的新数组
-
复制旧数组全部元素到新数组
-
丢弃旧数组,使用新数组
优点:查询极快(连续内存)
缺点:中间、头部增删极慢,需要大量移位、复制
五、LinkedList:双向链表集合
LinkedList 底层不是数组,是双向链表。
5.1 链表通俗理解
数组:所有人紧紧排成一排,站在一起,内存连续。
链表:每个人分散站,每个人手里拿着上一个人地址、下一个人地址。
5.2 LinkedList底层特点
-
底层:双向链表
-
内存不连续,每个节点保存:数据、前驱、后继
-
无需扩容,无限添加
-
增删快、查询慢
5.3 LinkedList代码演示
java
import java.util.LinkedList;
public class Demo {
public static void main(String[] args) {
LinkedList<String> list = new LinkedList<>();
list.add("A");
list.add("B");
list.add("C");
// 头部添加(LinkedList特有优势)
list.addFirst("头部元素");
// 尾部添加
list.addLast("尾部元素");
System.out.println(list);
}
}
5.4 链表优缺点总结
-
优点:头部、中间增删元素极快,不需要移位
-
缺点:查询慢,必须从头节点挨个遍历
六、ArrayList vs LinkedList(面试必背)
| 对比维度 | ArrayList | LinkedList |
|---|---|---|
| 底层结构 | 动态数组 | 双向链表 |
| 查询速度 | 极快(随机访问) | 慢(顺序遍历) |
| 增删速度 | 慢(需要移位、复制) | 极快(修改节点指向) |
| 内存占用 | 紧凑、连续 | 占用大(保存前驱后继) |
| 线程安全 | 不安全 | 不安全 |
| 使用场景 | 查询多、增删少(90%业务) | 频繁增删、头尾操作 |
开发口诀:无脑用ArrayList,频繁增删再换LinkedList。
七、List三种遍历方式(工作必写)
7.1 普通for循环(带索引)
java
for (int i = 0; i < list.size(); i++) {
System.out.println(list.get(i));
}
7.2 增强for循环(最简、最常用)
java
for (String s : list) {
System.out.println(s);
}
7.3 迭代器遍历(集合通用)
java
Iterator<String> it = list.iterator();
while(it.hasNext()){
System.out.println(it.next());
}
八、新手高频易错坑(避坑指南)
-
集合只能存引用类型,不能存基本类型(int存为Integer)
-
ArrayList默认初始容量为10,不是0
-
ArrayList扩容1.5倍,Vector扩容2倍(过时)
-
不要在for循环遍历中删除元素,会报并发修改异常
-
LinkedList不要用来大量查询,效率极低
九、本篇总结
本篇是集合框架开山第一篇,你必须牢牢记住以下核心:
-
数组长度固定,集合长度可变,开发全部用集合
-
List特点:有序、可重复、有索引
-
ArrayList:底层数组、查询快、扩容1.5倍、无脑首选
-
LinkedList:底层双向链表、增删快、查询慢
-
遍历三种方式:普通for、增强for、迭代器