• 普通 for 循环
  • 增强 for 循环(for-each 循环)
  • Iterator 迭代器
  • ListIterator 列表迭代器
  • 使用 forEach 方法
  • Stream API

可以用同一个 List 来对比这 6 种遍历方式,这样最容易看懂。

假设:

List<String> list = new ArrayList<>();
 
list.add("Java");
list.add("MySQL");
list.add("Redis");

里面的数据就是:

["Java", "MySQL", "Redis"]

1. 普通 for 循环

通过下标 index 获取元素:

for (int i = 0; i < list.size(); i++) {
    System.out.println(list.get(i));
}

输出:

Java
MySQL
Redis

核心是:

list.get(i)

所以这种方式比较适合 ArrayList 这种支持快速随机访问的集合。

如果需要下标,这种方式尤其方便:

for (int i = 0; i < list.size(); i++) {
    System.out.println("第" + i + "个元素:" + list.get(i));
}

**2. 增强 for 循环(for-each)

这是日常开发中非常常见的:

for (String str : list) {
    System.out.println(str);
}

可以理解:

依次从 list 中拿出元素
          ↓
     放到 str 中
          ↓
       执行代码

第一次:

str = "Java"

第二次:

str = "MySQL"

第三次:

str = "Redis"

相比普通 for:

for (int i = 0; i < list.size(); i++)

更加简洁。


3. Iterator 迭代器 ⭐⭐⭐⭐⭐

创建迭代器:

Iterator<String> iterator = list.iterator();
 
while (iterator.hasNext()) {
    String str = iterator.next();
    System.out.println(str);
}

这里要理解两个方法。

hasNext():

后面还有没有元素?

next():

获取下一个元素。

所以过程:

Iterator
   ↓
hasNext() → 有吗?
   ↓ yes
next() → Java
   ↓
hasNext() → 有吗?
   ↓ yes
next() → MySQL
   ↓
hasNext() → 有吗?
   ↓ yes
next() → Redis
   ↓
hasNext() → false
   ↓
结束

Iterator 很重要的一点是:遍历过程中需要安全删除元素时,可以使用迭代器自己的 remove() **。

例如删除 "MySQL":

Iterator<String> iterator = list.iterator();
 
while (iterator.hasNext()) {
    String str = iterator.next();
 
    if ("MySQL".equals(str)) {
        iterator.remove();
    }
}

不要直接:

for (String str : list) {
    if ("MySQL".equals(str)) {
        list.remove(str); // ❌ 可能抛 ConcurrentModificationException
    }
}

这是集合八股的高频知识点。


4. ListIterator 列表迭代器

ListIterator 可以理解成:

专门给 List 使用的增强版 Iterator。

例如:

ListIterator<String> iterator = list.listIterator();
 
while (iterator.hasNext()) {
    String str = iterator.next();
    System.out.println(str);
}

看起来和 Iterator 很像。

但是它有一个重要能力:

可以双向遍历。

正向:

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

反向:

while (iterator.hasPrevious()) {
    System.out.println(iterator.previous());
}

例如:

正向:
 
Java
MySQL
Redis
 
反向:
 
Redis
MySQL
Java

而且 ListIterator 还支持:

add()
set()
remove()

所以:

Iterator
   ↓
通用迭代器
主要向前遍历
 
ListIterator
   ↓
专门用于 List
可以前后遍历
支持更多修改操作

5. forEach()方法

Java 8 之后可以:

list.forEach(str -> {
    System.out.println(str);
});

这里其实就用到了你前面学的 Lambda 表达式:

str -> System.out.println(str)

如果只是调用 println,还可以使用方法引用:

list.forEach(System.out::println);

所以:

list.forEach(str -> System.out.println(str));

和:

list.forEach(System.out::println);

作用一样。

这也把你前面学的 Java 8 新特性串起来了:

Java8新特性 > **一、Lambda 表达式 ⭐⭐⭐⭐⭐**

Lambda
   ↓
forEach()
   ↓
方法引用 ::

6. Stream API

使用 Stream:

list.stream()
    .forEach(str -> {
        System.out.println(str);
    });

也可以:

list.stream()
    .forEach(System.out::println);

但如果仅仅为了遍历打印,通常没必要特意创建 Stream,直接:

list.forEach(System.out::println);

更加简单。

Stream 真正强大的地方是可以边处理边遍历。

比如只输出名字长度大于 4 的:

list.stream()
    .filter(str -> str.length() > 4)
    .forEach(System.out::println);

例如:

Java
MySQL
Redis
 ↓
filter(str -> str.length() > 4)
 ↓
MySQL
Redis
 ↓
forEach
 ↓
输出

还可以:

list.stream()
    .filter(str -> str.length() > 4)
    .map(String::toUpperCase)
    .forEach(System.out::println);

体现的就是:

数据
 ↓
过滤 filter
 ↓
转换 map
 ↓
遍历 forEach

六种方式放在一起看

List<String> list =
        Arrays.asList("Java", "MySQL", "Redis");
 
// 1. 普通 for
for (int i = 0; i < list.size(); i++) {
    System.out.println(list.get(i));
}
 
// 2. 增强 for
for (String str : list) {
    System.out.println(str);
}
 
// 3. Iterator
Iterator<String> it = list.iterator();
 
while (it.hasNext()) {
    System.out.println(it.next());
}
 
// 4. ListIterator
ListIterator<String> lit = list.listIterator();
 
while (lit.hasNext()) {
    System.out.println(lit.next());
}
 
// 5. forEach + Lambda
list.forEach(str -> System.out.println(str));
 
// 6. Stream
list.stream()
    .forEach(System.out::println);

八股层面可以这样总结:

方式最大特点
普通 for可以使用下标,适合 List,尤其 ArrayList
增强 for写法简单,底层对 Iterable 通常使用 Iterator
Iterator通用迭代方式,遍历时可通过迭代器安全删除
ListIteratorList 专用,可双向遍历和修改
forEach()Java 8,常配合 Lambda / 方法引用
Stream适合过滤、转换、聚合等流水线处理