在 Java 中,遍历 List
可以使用 for 循环 和 Iterator 两种方式。它们各有优缺点,适用于不同的场景。以下是它们的区别和适用场景:
1. 语法和使用方式
for 循环:
-
使用索引遍历列表。
-
示例:
java
List<String> list = Arrays.asList("A", "B", "C");
for (int i = 0; i < list.size(); i++) {
System.out.println(list.get(i));
}
//或者
List<String> list = Arrays.asList("A", "B", "C");
for (String str:list) {
System.out.println(str);
}
Iterator:
-
使用
Iterator
对象遍历列表。 -
示例:
java
List<String> list = Arrays.asList("A", "B", "C");
Iterator<String> iterator = list.iterator();
while (iterator.hasNext()) {
System.out.println(iterator.next());
}
2. 性能
-
for 循环:
-
对于
ArrayList
等基于数组实现的列表,for
循环性能较好,因为get(i)
是常数,时间复杂度(O(1))。 -
对于
LinkedList
等基于链表实现的列表,get(i)
的时间复杂度是 O(n),性能较差。
-
-
Iterator:
-
对于所有
List
实现,Iterator
的性能都较好,因为它内部会优化遍历方式。-
对于
ArrayList
,Iterator
通过索引直接访问元素。 -
对于
LinkedList
,Iterator
通过链表指针遍历,避免重复计算。
-
-
3. 并发修改
-
for 循环:
-
在遍历过程中修改列表(如删除元素)会导致
ConcurrentModificationException
。 -
示例:
-
java
List<String> list = new ArrayList<>(Arrays.asList("A", "B", "C"));
for (int i = 0; i < list.size(); i++) {
if (list.get(i).equals("B")) {
list.remove(i); // 可能抛出 ConcurrentModificationException
}
}
Iterator:
-
使用
Iterator
的remove()
方法可以在遍历时安全地删除元素,不会抛出异常。 -
示例:
java
List<String> list = new ArrayList<>(Arrays.asList("A", "B", "C"));
Iterator<String> iterator = list.iterator();
while (iterator.hasNext()) {
String item = iterator.next();
if (item.equals("B")) {
iterator.remove(); // 安全删除
}
}
4. 功能扩展
-
for 循环:
-
只能用于遍历,功能较为单一。
-
如果需要删除元素,需要额外处理索引。
-
-
Iterator:
-
提供了
remove()
方法,支持在遍历时删除元素。 -
可以通过
ListIterator
实现双向遍历(向前和向后)以及修改元素。
-
5. 代码可读性
-
for 循环:
-
代码直观,适合简单的遍历场景。
-
对于复杂的操作(如删除元素),代码可能变得冗长。
-
-
Iterator:
-
代码稍显复杂,但功能更强大。
-
适合需要删除元素或复杂操作的场景。
-
6. 适用场景
-
for 循环:
-
适合遍历
ArrayList
等基于数组实现的列表。 -
适合不需要修改列表的场景。
-
-
Iterator:
-
适合遍历所有类型的
List
,尤其是LinkedList
。 -
适合需要在遍历时删除或修改元素的场景。
-
从上面的比较中可以看出,当list为**LinkedList或者需要对元素进行修改删除操作时,从性能和安全性考虑,Iterator可适合。
**