java基础——java集合list详解
目录
一、引言
二、List接口概述
1.常用方法
2.实现List的主要类
2.1ArrayList
2.2LinkedList
2.3Vector
3.三者对比
三、List的遍历与去重
1.List 的三种主要遍历方式
1.1.普通 for 循环
1.2.增强型 for 循环
1.3.使用 Iterator
2.List去重方法
2.1.利用 HashSet 或 LinkedHashSet
2.2.Java 8+ 使用 Stream.distinct()
四、结语
一、引言
在Java中,List是java.util包下的一个接口,属于Java集合框架的一部分。它允许存储和操作有序的、可重复的对象序列。本文将详细介绍List接口、常用的方法、以及实现List接口的几个主要类(如ArrayList、LinkedList、Vector)。
以下是一个展示Java中List集合的思维导图:

二、List接口概述
List接口继承自Collection接口,提供了额外的功能来处理索引位置上的元素。与Set、Map不同,List允许包含重复的元素,并且可以通过索引来访问或修改特定位置的元素。
1.常用方法
add(E e):添加指定元素到列表末尾。
add(int index, E element):在指定索引处插入指定元素。
remove(int index):移除指定索引处的元素。
get(int index):获取指定索引处的元素。
set(int index, E element):替换指定索引处的元素。
size():返回列表中的元素数量。
isEmpty():判断列表是否为空。
contains(Object o):检查列表是否包含指定元素。
indexOf(Object o):返回指定元素首次出现的索引,如果不存在则返回-1。
lastIndexOf(Object o):返回指定元素最后一次出现的索引,如果不存在则返回-1。
subList(int fromIndex, int toIndex):获取从fromIndex(包括)到toIndex(不包括)之间的子列表
// 创建一个ArrayList实例
List list = new ArrayList<>();
// 添加元素
list.add("Apple");
list.add("Banana");
list.add("Cherry");
// 插入元素
list.add(1, "Apricot");
// 移除元素
list.remove(2);
// 获取元素
System.out.println(list.get(0)); // 输出: Apple
// 替换元素
list.set(0, "Avocado");
System.out.println(list.get(0)); // 输出: Avocado
// 其他方法示例
System.out.println(list.size()); // 输出: 3
System.out.println(list.isEmpty()); // 输出: false
System.out.println(list.contains("Banana")); // 输出: true
System.out.println(list.indexOf("Cherry")); // 输出: 2
System.out.println(list.lastIndexOf("Cherry")); // 输出: 2
System.out.println(list.subList(0, 2)); // 输出: [Avocado, Banana]
2.实现List的主要类
2.1ArrayList
ArrayList是最常用的List实现之一,它基于动态数组实现,支持随机访问,查询效率高,但插入和删除效率较低。
特点
支持快速随机访问。
非线程安全。
初始容量为10,每次扩容时增长50%。
使用场景
适用于频繁读取而不经常修改的数据集合。
示例代码
// 创建并初始化ArrayList
List numbers = new ArrayList<>();
numbers.add(1);
numbers.add(2);
numbers.add(3);
// 访问元素
for (int i = 0; i < numbers.size(); i++) {
System.out.println(numbers.get(i));
}
// 修改元素
numbers.set(1, 20);
System.out.println(numbers); // 输出: [1, 20, 3]
// 删除元素
numbers.remove(2);
System.out.println(numbers); // 输出: [1, 20]
2.2LinkedList
LinkedList是另一个重要的List实现,它基于双向链表实现,对于插入和删除操作具有较高的性能,但对于随机访问效率较低。
特点
支持高效的插入和删除操作。
非线程安全。
可以作为堆栈、队列或双端队列使用。
使用场景
适用于频繁进行插入和删除操作的数据集合。
示例代码
// 创建并初始化LinkedList
LinkedList characters = new LinkedList<>();
characters.add('A');
characters.add('B');
characters.add('C');
// 访问元素
for (char c : characters) {
System.out.print(c + " ");
}
System.out.println(); // 输出: A B C
// 在头部插入元素
characters.addFirst('Z');
System.out.println(characters); // 输出: [Z, A, B, C]
// 在尾部插入元素
characters.addLast('D');
System.out.println(characters); // 输出: [Z, A, B, C, D]
// 删除元素
characters.removeFirst();
characters.removeLast();
System.out.println(characters); // 输出: [A, B, C]
2.3Vector
早期线程安全集合类,通过方法级synchronized实现同步。默认扩容增长一倍。
特点
线程安全
同步锁导致并发效率低下(方法都使用了 synchronized)
性能低(主要用于同步开销)
遗留类,不推荐使用
示例代码
// 创建 Vector
List vector = new Vector<>();
// 添加元素
vector.add("Java");
vector.add("Python");
vector.add("C++");
// 插入元素
vector.add(1, "JavaScript");
// 输出结果
System.out.println(vector); // 输出: [Java, JavaScript, Python, C++]
// 删除元素
vector.remove(2);
// 遍历
for (String lang : vector) {
System.out.println(lang);
}
3.三者对比


三、List的遍历与去重
1.List 的三种主要遍历方式
1.1.普通 for 循环
适用于需要访问索引的场景。
List list = new ArrayList<>();
list.add("A");
list.add("B");
list.add("C");
for (int i = 0; i < list.size(); i++) {
System.out.println("Index: " + i + ", Value: " + list.get(i));
}
优点:
可以灵活控制索引。
支持随机访问(适合 ArrayList)。
缺点:
对于 LinkedList 来说效率较低(因为每次都要从头开始查找元素)。
1.2.增强型 for 循环
语法简洁,适用于只需要获取元素的情况。
List list = new ArrayList<>();
list.add("A");
list.add("B");
list.add("C");
for (String item : list) {
System.out.println("Item: " + item);
}
优点:
简洁易读。
适用于所有实现了 Iterable 接口的集合类。
缺点:
无法获取索引。
不能修改集合结构(如删除元素会抛出异常)。
1.3.使用 Iterator
可以安全地在遍历时进行删除操作。
Iterator iterator = list.iterator();
while (iterator.hasNext()) {
String item = iterator.next();
if ("B".equals(item)) {
iterator.remove(); // 安全删除
}
}
优点:
支持在遍历过程中安全删除元素。
更加通用,适用于各种集合类型。
2.List去重方法
Java 中有多种方式可以实现 List 去重,下面是几种常见的方式:
2.1.利用 HashSet 或 LinkedHashSet
使用 HashSet(不保留顺序):
List list = Arrays.asList(1, 2, 2, 3, 4, 4, 5);
List uniqueList = new ArrayList<>(new HashSet<>(list));
System.out.println(uniqueList); // 输出顺序可能不同
使用 LinkedHashSet(保留插入顺序):
List list = Arrays.asList(1, 2, 2, 3, 4, 4, 5);
List uniqueList = new ArrayList<>(new LinkedHashSet<>(list));
System.out.println(uniqueList); // 输出: [1, 2, 3, 4, 5]
说明:
HashSet 和 LinkedHashSet 虽然常用于去重,但它们底层确实基于 HashMap 和 LinkedHashMap 实现的。也就是说,你给 List 去重时,实际上是借助了 Map 的特性来实现的。具体原因这里不做详细说明,需要的同学请关注我后续的文章。
2.2.Java 8+ 使用 Stream.distinct()
List list = Arrays.asList(1, 2, 2, 3, 4, 4, 5);
List uniqueList = list.stream().distinct().collect(Collectors.toList());
System.out.println(uniqueList);
说明:
distinct() 方法依赖于对象的 equals() 和 hashCode() 方法。
如果是自定义对象,请确保正确重写这两个方法。
四、结语
List 作为 Java 集合框架中最基础、最常用的数据结构之一,贯穿于几乎所有的 Java 应用开发中。掌握 List 的核心接口、常用实现类(如 ArrayList、LinkedList、Vector)、遍历方式和去重技巧,不仅有助于写出更高效、清晰的代码,也能帮助我们在面对复杂业务逻辑时做出更合理的技术选型。
在实际开发中,理解不同 List 实现的底层原理和适用场景,是写出高性能程序的关键。同时,结合 Set 和 Map 的使用,可以更好地处理唯一性、顺序性和映射关系等常见需求。
希望本文能为你深入理解 Java 中的 List 集合提供清晰的思路和实用的指导。无论你是刚入门的新手,还是有一定经验的开发者,集合框架始终是值得反复学习和实践的重要内容。持续深耕,才能在实际项目中游刃有余。

