Java·关于List

List 是 Java 集合框架(java.util 包)中核心的有序、可重复 集合接口,继承自 Collection 接口,支持通过索引(下标)快速访问、修改元素,是日常开发中最常用的集合类型之一。

一、什么是 List?

1. 核心定义

List 是 Collection 接口的子接口,用于存储有序、可重复的元素集合,其核心特征是:

  • 有序性:元素的插入顺序与存储顺序一致,支持通过索引(0 起始)访问元素;
  • 可重复性:允许存储多个相同的元素(包括 null);
  • 索引操作:提供了基于索引的增删改查方法(这是 List 与 Set 最核心的区别)。

2. 与其他核心集合的区别

二、List 接口核心方法(含继承 + 独有)

List 继承了 Collection 接口的基础方法(如 add(E)remove(Object)size()isEmpty() 等),同时新增了基于索引的操作方法,核心方法如下:

1. 新增元素(基于索引)

java 复制代码
// 1. 在列表末尾添加元素(继承自Collection)
boolean add(E e);

// 2. 在指定索引index处插入元素,后续元素后移(List独有)
void add(int index, E element);

// 3. 将另一个集合的所有元素添加到当前列表末尾
boolean addAll(Collection<? extends E> c);

// 4. 将另一个集合的所有元素插入到指定索引处
boolean addAll(int index, Collection<? extends E> c);

2. 删除元素(基于索引 / 元素)

java 复制代码
// 1. 删除指定索引处的元素,返回被删除的元素(List独有)
E remove(int index);

// 2. 删除第一个匹配的元素(继承自Collection)
boolean remove(Object o);

// 3. 清空所有元素
void clear();

3. 修改元素(基于索引)

java 复制代码
// 替换指定索引处的元素,返回被替换的旧元素(List独有)
E set(int index, E element);

4. 查询元素(基于索引 / 元素)

java 复制代码
// 1. 获取指定索引处的元素(List独有)
E get(int index);

// 2. 返回第一个匹配元素的索引,无则返回-1(List独有)
int indexOf(Object o);

// 3. 返回最后一个匹配元素的索引,无则返回-1(List独有)
int lastIndexOf(Object o);

// 4. 判断集合是否包含指定元素(继承自Collection)
boolean contains(Object o);

5. 其他常用方法

java 复制代码
// 1. 返回List的子列表(左闭右开区间),注意:子列表是原列表的视图,修改会相互影响
List<E> subList(int fromIndex, int toIndex);

// 2. 将List转为数组
Object[] toArray();
<T> T[] toArray(T[] a);

// 3. 获取迭代器(支持遍历)
Iterator<E> iterator();

// 4. Java 8+ 新增:forEach遍历(函数式接口)
void forEach(Consumer<? super E> action);

三、List 的主要实现类(重点)

List 是接口,无法直接实例化,需使用其实现类。日常开发中最常用的实现类有 4 个,核心差异在于底层数据结构性能特性

关键补充:

  • ArrayList 扩容机制:初始容量为 10,负载因子 0.75,当元素个数达到 容量×负载因子 时,扩容为原容量的 1.5 倍(避免频繁扩容,可初始化时指定容量优化);
  • LinkedList 除了 List 方法,还实现了 Deque 接口,支持 addFirst()addLast()pollFirst()pop() 等队列 / 栈操作;
  • CopyOnWriteArrayList 适合读多写少(如配置缓存),写操作(add/remove)会复制原数组,开销较大,不适合频繁写的场景。

四、List 的使用(实战示例)

1. 实例化 List

推荐使用接口引用 + 实现类实例的方式(面向接口编程):

java 复制代码
import java.util.*;
import java.util.concurrent.CopyOnWriteArrayList;

public class ListDemo {
    public static void main(String[] args) {
        // 1. ArrayList(默认容量10)
        List<String> arrayList = new ArrayList<>();
        // 初始化指定容量(优化扩容)
        List<Integer> arrayList2 = new ArrayList<>(20);

        // 2. LinkedList
        List<String> linkedList = new LinkedList<>();

        // 3. 线程安全的CopyOnWriteArrayList
        List<String> safeList = new CopyOnWriteArrayList<>();

        // 4. 不可变List(Java 9+,元素不可增删改)
        List<String> immutableList = List.of("a", "b", "c");
    }
}

2. 核心操作(增删改查)

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

// 增
list.add("Java");       // 末尾添加:[Java]
list.add(0, "Python");  // 索引0插入:[Python, Java]
list.addAll(Arrays.asList("C++", "Go"));  // 末尾添加集合:[Python, Java, C++, Go]

// 查
String elem = list.get(1);  // 获取索引1元素:Java
int index = list.indexOf("C++");  // 查找元素索引:2
boolean contains = list.contains("Go");  // 是否包含:true

// 改
String oldElem = list.set(2, "Rust");  // 替换索引2元素:[Python, Java, Rust, Go],oldElem=C++

// 删
list.remove(3);  // 删除索引3元素:[Python, Java, Rust]
list.remove("Python");  // 删除元素:[Java, Rust]

System.out.println(list);  // 输出:[Java, Rust]

3. 遍历 List(5 种常用方式)

java 复制代码
List<String> list = new ArrayList<>(Arrays.asList("a", "b", "c"));

// 1. 普通for循环(基于索引)
for (int i = 0; i < list.size(); i++) {
    System.out.print(list.get(i) + " ");  // a b c
}

// 2. 增强for循环(foreach,推荐)
for (String s : list) {
    System.out.print(s + " ");
}

// 3. 迭代器(Iterator)- 支持遍历中删除元素
Iterator<String> iterator = list.iterator();
while (iterator.hasNext()) {
    String s = iterator.next();
    if (s.equals("b")) {
        iterator.remove();  // 安全删除(避免ConcurrentModificationException)
    }
    System.out.print(s + " ");  // a b c(删除后list变为[a, c])
}

// 4. Java 8+ forEach(函数式接口)
list.forEach(s -> System.out.print(s + " "));

// 5. Java 8+ Stream流遍历
list.stream().forEach(System.out::print);

4. 排序 List

List 支持自定义排序,核心用 Collections.sort()(旧版)或 List.sort()(Java 8+,推荐):

java 复制代码
List<Integer> numList = new ArrayList<>(Arrays.asList(3, 1, 4, 2));

// 1. 自然排序(元素需实现Comparable接口,如Integer、String)
numList.sort(Comparator.naturalOrder());  // 升序:[1, 2, 3, 4]

// 2. 逆序排序
numList.sort(Comparator.reverseOrder());  // 降序:[4, 3, 2, 1]

// 3. 自定义对象排序(以User为例)
class User {
    String name;
    int age;
    // 构造器、getter省略
}
List<User> userList = new ArrayList<>(Arrays.asList(
    new User("张三", 25),
    new User("李四", 20)
));
// 按年龄升序排序
userList.sort((u1, u2) -> u1.getAge() - u2.getAge());
// 或用Comparator.comparing(更简洁)
userList.sort(Comparator.comparingInt(User::getAge));

5. List 去重(保留顺序)

List 允许重复元素,去重常用 2 种方式:

java 复制代码
List<String> list = new ArrayList<>(Arrays.asList("a", "b", "a", "c"));

// 方式1:LinkedHashSet(保留插入顺序,去重)
List<String> distinctList1 = new ArrayList<>(new LinkedHashSet<>(list));
System.out.println(distinctList1);  // [a, b, c]

// 方式2:Java 8+ Stream.distinct()(保留顺序)
List<String> distinctList2 = list.stream().distinct().collect(Collectors.toList());

6. 并发安全问题与解决

ArrayListLinkedList 是线程不安全的,多线程修改时会抛 ConcurrentModificationException,解决方式:

java 复制代码
// 方式1:使用Collections.synchronizedList(加锁,效率一般)
List<String> syncList = Collections.synchronizedList(new ArrayList<>());

// 方式2:使用CopyOnWriteArrayList(读多写少,推荐)
List<String> safeList = new CopyOnWriteArrayList<>();

// 多线程操作示例
new Thread(() -> safeList.add("a")).start();
new Thread(() -> safeList.forEach(System.out::print)).start();

五、常见注意事项

  1. subList 视图特性subList(from, to) 返回原列表的子视图,修改子列表或原列表都会相互影响,且子列表依赖原列表存在(原列表被销毁后子列表不可用);
  2. 迭代器安全删除使用增强 for 循环或迭代器遍历的同时,不能用 list.remove()(会触发 fail-fast 机制抛异常),需用 Iterator.remove()
  3. 不可变 ListList.of() 创建的列表不可增删改,否则抛 UnsupportedOperationException
  4. ArrayList 初始化优化 :已知元素个数时,指定初始容量(如 new ArrayList<>(100)),避免频繁扩容
相关推荐
散峰而望7 分钟前
C++数组(二)(算法竞赛)
开发语言·c++·算法·github
靠沿19 分钟前
Java数据结构初阶——Collection、List的介绍与ArrayList
java·数据结构·list
程序猿小蒜21 分钟前
基于springboot的的学生干部管理系统开发与设计
java·前端·spring boot·后端·spring
子不语18038 分钟前
Python——函数
开发语言·python
q***56381 小时前
Spring容器初始化扩展点:ApplicationContextInitializer
java·后端·spring
ndjnddjxn1 小时前
Rust学习
开发语言·学习·rust
q***51891 小时前
SpringCloud系列教程:微服务的未来(十四)网关登录校验、自定义过滤器GlobalFilter、GatawayFilter
java·spring cloud·微服务
月光技术杂谈1 小时前
实战:C驱动框架嵌入Rust模块的互操作机制与完整流程
c语言·开发语言·rust·ffi·跨语言·bindgen·互操作
t198751281 小时前
基于MATLAB的指纹识别系统完整实现
开发语言·matlab