Java List 集合深度解析(ArrayList / LinkedList 原理详解)

一、什么是 List

在 Java 集合框架中,List 是一个有序集合,允许存储重复元素。

特点:

  1. 元素有顺序

  2. 允许重复

  3. 支持索引访问

示例:

java 复制代码
List<String> list = new ArrayList<>();

list.add("Java");
list.add("Python");
list.add("Java");

System.out.println(list.get(0));

输出:

复制代码
Java

说明:

复制代码
List 可以重复

二、List 集合体系结构

Java List 主要实现类:

复制代码
Collection
    │
    └── List
         │
         ├── ArrayList
         │
         ├── LinkedList
         │
         └── Vector
               │
               └── Stack

常用实现类:

特点
ArrayList 查询快
LinkedList 插入删除快
Vector 线程安全(过时)
Stack 栈结构

日常开发中:

复制代码
90% 使用 ArrayList

三、ArrayList 底层结构

ArrayList 本质:

复制代码
动态数组

源码:

java 复制代码
transient Object[] elementData;

结构:

复制代码
elementData
│
├─ [0] Java
├─ [1] Python
├─ [2] C++

特点:

复制代码
连续内存

优点:

复制代码
随机访问快

四、ArrayList 扩容机制(重点)

默认容量:

复制代码
10

源码:

java 复制代码
private static final int DEFAULT_CAPACITY = 10;

初始化:

java 复制代码
List list = new ArrayList();

第一次 add:

复制代码
容量 = 10

扩容规则

扩容公式:

java 复制代码
newCapacity = oldCapacity + oldCapacity >> 1

即:

复制代码
1.5倍扩容

示例:

复制代码
10 → 15 → 22 → 33 → 49

源码:

java 复制代码
int newCapacity = oldCapacity + (oldCapacity >> 1);

扩容流程

复制代码
1 创建新数组
2 复制旧数组数据
3 指向新数组

源码:

java 复制代码
Arrays.copyOf(elementData, newCapacity);

五、ArrayList 时间复杂度

操作 时间复杂度
get O(1)
add(尾部) O(1)
add(中间) O(n)
remove O(n)

原因:

复制代码
数组需要移动元素

示例:

复制代码
[1,2,3,4]

删除 2

变成

[1,3,4]

需要移动:

复制代码
n-1 次

六、LinkedList 底层结构

LinkedList 本质:

复制代码
双向链表

源码:

java 复制代码
Node<E> first;
Node<E> last;

节点结构:

java 复制代码
private static class Node<E> {
    E item;
    Node<E> next;
    Node<E> prev;
}

结构:

复制代码
null <- A <-> B <-> C -> null

每个节点包含:

复制代码
prev
data
next

七、LinkedList 特点

优点:

复制代码
插入删除快

缺点:

复制代码
查询慢

时间复杂度:

操作 时间复杂度
get O(n)
add O(1)
remove O(1)

八、LinkedList 查询优化

LinkedList 会判断:

复制代码
index < size/2

如果:

复制代码
index < size/2

从头遍历:

复制代码
first

否则:

复制代码
last

从尾遍历。

源码:

java 复制代码
if (index < (size >> 1)) {
    Node<E> x = first;
} else {
    Node<E> x = last;
}

优化查询效率。


九、ArrayList vs LinkedList

对比 ArrayList LinkedList
底层结构 数组 双向链表
查询
插入
删除
内存占用

选择建议:

复制代码
查询多 → ArrayList
增删多 → LinkedList

但现实开发:

复制代码
几乎都用 ArrayList

原因:

复制代码
CPU缓存友好

十、Vector 原理

Vector 和 ArrayList 类似:

复制代码
动态数组

区别:

复制代码
线程安全

源码:

java 复制代码
public synchronized boolean add(E e)

所有方法:

复制代码
synchronized

缺点:

复制代码
性能差

所以:

复制代码
基本不用

十一、fail-fast 机制

Java 集合有一个重要机制:

复制代码
fail-fast

意思:

复制代码
快速失败

示例:

java 复制代码
for(String s : list){
    list.remove(s);
}

会抛异常:

复制代码
ConcurrentModificationException

原因:

复制代码
modCount 变化

源码:

java 复制代码
if (modCount != expectedModCount)
    throw new ConcurrentModificationException();

十二、Iterator 迭代器原理

迭代器作用:

复制代码
遍历集合

示例:

java 复制代码
Iterator<String> it = list.iterator();

while(it.hasNext()){
    System.out.println(it.next());
}

结构:

复制代码
Iterator
   │
hasNext()
next()
remove()

如果需要删除:

必须用:

复制代码
it.remove();

不能:

复制代码
list.remove()

否则触发:

复制代码
fail-fast

十三、List 常用方法

java 复制代码
add(E e)

add(int index,E e)

get(int index)

set(int index,E e)

remove(int index)

size()

clear()

示例:

java 复制代码
list.add("Java");
list.add("Python");

list.remove(1);

list.set(0,"C++");

十四、List 遍历方式

1 for循环

java 复制代码
for(int i=0;i<list.size();i++){
    System.out.println(list.get(i));
}

适合:

复制代码
ArrayList

2 增强for

java 复制代码
for(String s:list){
    System.out.println(s);
}

3 Iterator

java 复制代码
Iterator<String> it = list.iterator();

适合:

复制代码
删除元素

4 forEach

复制代码
list.forEach(System.out::println);

十五、ArrayList 面试高频问题

1 ArrayList 底层结构

复制代码
动态数组

2 ArrayList 默认容量

复制代码
10

3 ArrayList 扩容多少倍

复制代码
1.5倍

4 为什么 ArrayList 查询快

因为:

复制代码
数组连续存储

可以:

复制代码
随机访问

5 ArrayList 为什么线程不安全

原因:

复制代码
多个线程同时修改 elementData

可能导致:

复制代码
数据覆盖

6 ArrayList 和 Vector 区别

ArrayList Vector
线程安全
性能
是否推荐

十六、总结

Java List 核心结构:

复制代码
List
 │
 ├─ ArrayList
 │     动态数组
 │
 ├─ LinkedList
 │     双向链表
 │
 └─ Vector
       线程安全数组

核心知识点:

复制代码
ArrayList扩容
LinkedList结构
fail-fast机制
Iterator原理
时间复杂度
相关推荐
郝学胜-神的一滴2 小时前
一序平衡,括号归真:单括号匹配算法的优雅美学
java·前端·数据结构·c++·python·算法
清水白石0082 小时前
Python 方法绑定机制深度解析:bound method、三种方法类型与代码评审实战
开发语言·网络·python
吃着火锅x唱着歌2 小时前
PHP7内核剖析 学习笔记 第十章 扩展开发(3)
java·笔记·学习
CSDN_kada2 小时前
杭电网安复试编程Day19
开发语言·c++·算法
ok_hahaha2 小时前
java从头开始-苍穹外卖-day11-数据统计与展示
java
MyY_DO2 小时前
继承+代码复用使用方法说人话
java·开发语言
@国境以南,太阳以西2 小时前
从0实现OnCall基于Python语言框架
开发语言·python
qq5680180762 小时前
一个基于Spring Boot的简单网吧管理系统
java·spring boot·后端
每天被梦想叫醒的程序员2 小时前
Windows 11 系统部署 OpenClaw 完整指南:从零到一的 AI 助手搭建
人工智能·windows