正文
在 Java 集合框架中,List
是一个非常重要的接口,广泛用于存储有序的元素集合。本文将带你深入了解
List
接口的基本用法、常见实现类及其扩展,同时通过实际代码示例帮助你快速掌握这些知识。
1. 什么是 List?
List
是 Java 集合框架中的一个接口,它继承了 Collection
接口,用于存储一组有序的元素。与普通数组相比,List
提供了动态调整大小和丰富操作方法的功能。
特点:
- 元素有序,可通过索引访问。
- 允许存储重复的元素。
- 可以存储
null
值。
常用实现类:
ArrayList
LinkedList
Vector
CopyOnWriteArrayList
(线程安全)
2. List 的基本操作
以下是 List
接口的一些常用方法:
方法 | 描述 |
---|---|
add(E e) |
在列表末尾添加元素 |
add(int index, E e) |
在指定位置插入元素 |
get(int index) |
根据索引获取元素 |
set(int index, E e) |
修改指定索引的元素 |
remove(int index) |
移除指定索引的元素 |
size() |
返回列表中元素的数量 |
contains(Object o) |
判断列表是否包含指定元素 |
indexOf(Object o) |
返回元素的首次出现索引 |
isEmpty() |
判断列表是否为空 |
代码示例:
import java.util.*; public class ListDemo { public static void main(String[] args) { List<String> list = new ArrayList<>(); // 添加元素 list.add("Java"); list.add("Python"); list.add("C++"); // 插入元素 list.add(1, "JavaScript"); // 获取元素 System.out.println("元素:" + list.get(1)); // 修改元素 list.set(2, "C#"); // 删除元素 list.remove(3); // 遍历列表 for (String item : list) { System.out.println(item); } } }
3. 常用的 List 实现类
3.1 ArrayList
ArrayList
是基于动态数组实现的列表,适合频繁查询的场景。
特点:
- 随机访问效率高。
- 插入或删除时可能需要移动大量元素。
- 非线程安全。
代码示例:
import java.util.ArrayList; public class ArrayListExample { public static void main(String[] args) { ArrayList<Integer> numbers = new ArrayList<>(); numbers.add(1); numbers.add(2); numbers.add(3); System.out.println("ArrayList: " + numbers); } }
3.2 LinkedList
LinkedList
是基于双向链表实现的列表,适合频繁插入和删除的场景。
特点:
- 查询效率较低,需要从头开始遍历。
- 插入和删除效率高。
- 可以用作队列(
Queue
)或双端队列(Deque
)。
代码示例:
import java.util.LinkedList; public class LinkedListExample { public static void main(String[] args) { LinkedList<String> queue = new LinkedList<>(); queue.add("Alice"); queue.add("Bob"); queue.add("Charlie"); System.out.println("LinkedList: " + queue); // 模拟队列操作 System.out.println("Poll: " + queue.poll()); // 移除并返回队首元素 } }
3.3 Vector
Vector
是线程安全的动态数组,适合多线程场景。
特点:
- 每个方法都使用了同步机制。
- 性能比
ArrayList
较低,但线程安全。
代码示例:
import java.util.Vector; public class VectorExample { public static void main(String[] args) { Vector<String> vector = new Vector<>(); vector.add("Apple"); vector.add("Banana"); vector.add("Cherry"); System.out.println("Vector: " + vector); } }
3.4 CopyOnWriteArrayList
CopyOnWriteArrayList
是线程安全的 ArrayList
实现,适合多线程且读多写少的场景。
特点:
- 每次修改时都会复制底层数组。
- 读操作不需要锁,性能高。
- 写操作的性能较低。
代码示例:
import java.util.concurrent.CopyOnWriteArrayList; public class CopyOnWriteArrayListExample { public static void main(String[] args) { CopyOnWriteArrayList<String> list = new CopyOnWriteArrayList<>(); list.add("Thread-safe"); list.add("Example"); System.out.println("CopyOnWriteArrayList: " + list); } }
4. List 的扩展用法
4.1 排序操作
Collections.sort
方法可以对列表进行排序:
代码示例:
import java.util.*; public class SortExample { public static void main(String[] args) { List<Integer> numbers = Arrays.asList(5, 3, 8, 1); Collections.sort(numbers); System.out.println("排序后: " + numbers); } }
4.2 遍历方式
-
for-each 循环:
for (String item : list) { System.out.println(item); }
-
Iterator:
Iterator<String> iterator = list.iterator(); while (iterator.hasNext()) { System.out.println(iterator.next()); }
-
Stream API:
list.stream().forEach(System.out::println);
4.3 Stream 和 Lambda 表达式
利用 Stream
可以方便地对列表进行操作:
代码示例:
import java.util.*; public class StreamExample { public static void main(String[] args) { List<String> names = Arrays.asList("Alice", "Bob", "Charlie"); names.stream() .filter(name -> name.startsWith("A")) .forEach(System.out::println); } }
5. 面试中关于 List 的高频问题
-
ArrayList 和 LinkedList 的区别:
- ArrayList 基于数组,查询快,插入和删除慢。
- LinkedList 基于链表,插入和删除快,查询慢。
-
Vector 和 ArrayList 的区别:
- Vector 是线程安全的,ArrayList 是非线程安全的。
- Vector 性能相对较低。
-
线程安全的 List 实现有哪些?
Vector
CopyOnWriteArrayList
-
如何避免 ConcurrentModificationException?
- 使用
Iterator
的remove
方法。 - 使用线程安全的集合如
CopyOnWriteArrayList
。
- 使用
6. 总结
List
是 Java
集合框架中非常重要的一部分,其各种实现类在不同的场景下各有优势。掌握
List
的基本用法和实现类的特性,不仅有助于日常开发,还能应对 Java
面试中的高频考察。
希望本文对你理解 List
及其常用扩展有所帮助!