一、遍历集合List的五种方法
测试数据
List<String> list = new ArrayList<>();
list.add("A");list.add("B");list.add("C");
1. 普通for循环
普通for循环,通过索引遍历
for (int i = 0; i < list.size(); i++) {System.out.println(list.get(i));
}
2. 增强for循环
增强for循环,数组以及所有Collection集合都可以使用增强for循环遍历。遍历集合的实际原理为获取集合的iterator迭代器对象进行迭代遍历。
for (String s : list) {System.out.println(s);
}
3. Iterator迭代器遍历
Collection接口继承自Iterable接口,所有Collection集合都必须实现iterator()方法返回一个Iterator迭代器对象。因此可以通过list的iterator()方法获取迭代器对象来进行遍历。并且可在迭代过程中调用iterator.remove()安全移除当前元素。
Iterator<String> iterator = list.iterator();
while (iterator.hasNext()) {String s = iterator.next();if (s.equals("B")) iterator.remove();System.out.println(s);
}
4. ListIterator迭代器遍历
所有List集合都必须实现一个listIterator()方法,返回一个ListIterator迭代器对象。ListIterator 是 Iterator 的子接口,除了可以从前往后遍历外,还可以反向遍历,即从后往前遍历。还可以在遍历过程中使用listIterator.add()方法在当前遍历位置之后插入元素,使用listIterator.set() 方法修改当前元素,以及使用listIterator.remove()移除当前元素。
ListIterator<String> listIterator = list.listIterator();
while (listIterator.hasNext()) {String element = listIterator.next();if (element.equals("B")) {// 修改当前元素listIterator.set("D");// 在当前元素后面插入一个新元素listIterator.add("E");//将迭代器指针移动到前一个元素,然后进行删除listIterator.previous();listIterator.remove();}
}
System.out.println(list); // 输出 [A, D, C]
5. list.forEach(lambda表达式)
list.forEach(element -> {// 使用 elementSystem.out.println(element);
});
二、如何在遍历集合过程中安全移除元素
如果在使用 Iterator 或 ListIterator 遍历集合的过程中,使用了list.remove() 方法来移除元素,而没有通过迭代器自身的 remove() 方法,就有可能导致 ConcurrentModificationException。这是因为list内部维护了一个修改计数器modCount, 记录list中添加和删除元素的次数,迭代器对象内部会维护一个迭代器修改计数器expectedModCount,如果被非迭代器方法修改了list,导致modCount增加了而expectedModCount没有增加,导致二者不想等于是在check时抛出异常。
- 因此在增强for循环中不能添加或移除元素。
- 需要使用Iterator 或 ListIterator 来迭代遍历集合,并且使用迭代器的方法来移除或添加元素。