在 Java 集合框架中,Collection 接口提供了多种通用遍历方法,适用于所有实现了该接口的集合类(如 ArrayList、HashSet、LinkedList 等)。
一.迭代器遍历
1.迭代器
(1). 迭代器(Iterator)的核心概念
- 设计模式:迭代器是一种行为设计模式,提供顺序访问聚合对象元素的方法,无需暴露其内部结构
- 解耦遍历:将遍历逻辑从集合实现中分离,实现遍历与数据结构的解耦
- 统一接口:为不同集合提供一致的遍历方式(如数组、链表、树等)
(2). 迭代器基本操作
方法 | 功能描述 |
---|---|
hasNext() |
检查是否还有下一个元素可用(返回boolean) |
next() |
返回下一个元素并移动指针 |
remove() |
删除最后访问的元素(可选操作,部分实现不支持) |
forEachRemaining() |
Java 8新增,对剩余元素执行操作(接收Consumer函数式接口) |
2.Java Collection 迭代器遍历详解
底层实现原理:
- 游标控制:迭代器内部维护一个隐式游标(cursor),初始位置在集合第一个元素之前
- 状态追踪:通过
modCount
机制记录集合的结构修改次数(添加/删除操作) - 双向校验:
hasNext()
:检查游标是否到达集合末尾(基于当前集合大小)next()
:移动游标并返回元素,同时校验modCount
是否变化(检测并发修改)- 删除操作:
remove()
方法删除当前元素后,会同步更新迭代器的expectedModCount
和集合的modCount
- 数据结构适配:不同集合有专属迭代器实现(如ArrayList.Itr,HashMap.EntryIterator)
(1). 获取迭代器的方式
// 所有Collection子类通用方式
Iterator<T> it = collection.iterator();
// List专用(支持双向遍历)
ListIterator<T> listIt = list.listIterator();
// Java 1.5+ 增强for循环(底层使用迭代器)
for (T item : collection) { ... }
(2).基础遍历示例
List<String> fruits = Arrays.asList("Apple", "Banana", "Cherry");
Iterator<String> it = fruits.iterator();
while (it.hasNext()) {
System.out.println(it.next());
}
最传统的遍历方式,支持在遍历过程中安全删除元素
(3).迭代器注意事项
- 迭代器遍历完毕后指针不会自动复位
- 循环中只能用一次next方法
- 迭代器遍历时,不能用集合的方法进行增加或者删除
(4).迭代器删除
Collection<String> fruits = new ArrayList<>();
fruits.add("Apple");
fruits.add("Banana");
fruits.add("Orange");
Iterator<String> iterator = fruits.iterator();
while (iterator.hasNext()) {
String fruit = iterator.next();
System.out.println(fruit);
// 安全删除当前元素
if ("Banana".equals(fruit)) {
iterator.remove();
}
}
System.out.println("移除香蕉后: " + fruits);
二.增强for遍历
1. 基本概念
- 引入版本:Java 5(JDK 1.5)
- 设计目的:简化数组和集合的遍历语法
- 语法结构:
for (元素类型 局部变量 : 遍历对象) {
// 循环体
}
2.底层实现原理
数组转换:
// 源码
for (String item : arr) { ... }
// 编译器转换后
for (int i=0; i < arr.length; i++) {
String item = arr[i];
...
}
集合转换:
// 源码
for (String item : list) { ... }
// 编译器转换后
Iterator<String> it = list.iterator();
while (it.hasNext()) {
String item = it.next();
...
}
三.Lambda表达式遍历
1. 核心概念
- 函数式编程:将函数作为参数传递
- 核心接口:
java.util.function.Consumer
- 语法本质:
collection.forEach(元素 -> { 处理逻辑 })
2. 底层实现原理
3. 基本用法示例
List<String> languages = Arrays.asList("Java", "Python", "Go");
// 1. 基础Lambda
languages.forEach(lang -> System.out.println(lang));
// 2. 方法引用
languages.forEach(System.out::println);
// 3. 多行处理
languages.forEach(lang -> {
String upper = lang.toUpperCase();
System.out.print(upper + " ");
});
// 输出: JAVA PYTHON GO
自定义可遍历对象
要让自定义对象支持 Lambda 表达式遍历,需实现 Iterable<T>
接口并重写 forEach()
方法。核心是提供可迭代元素集合和元素消费逻辑,通过实现 iterator()
方法返回迭代器,并在 forEach()
中应用 Consumer
处理每个元素。
class SensorNetwork implements Iterable<Sensor> {
private List<Sensor> sensors = new ArrayList<>();
public void addSensor(Sensor s) {
sensors.add(s);
}
@Override
public void forEach(Consumer<? super Sensor> action) {
sensors.forEach(action);
}
@Override
public Iterator<Sensor> iterator() {
return sensors.iterator();
}
}
// 使用Lambda遍历
SensorNetwork network = new SensorNetwork();
network.forEach(sensor ->
System.out.println(sensor.readValue())
);