ArrayList的遍历方法与删除中的异常情况分析
package com.test;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
/**
* @author yuhao
**/
public class Test {
private static List<Integer> list = new ArrayList<>(10);
static {
for (int i = 0; i < 10; i++) {
list.add(i);
}
}
public static void main(String[] args) {
//遍历
traverse();
//删除元素
remove();
}
private static void traverse() {
//遍历的4种方式
System.out.println("遍历开始");
for (int i = 0; i < list.size(); i++) {
System.out.print(list.get(i));
}
System.out.println();
Iterator<Integer> iterator = list.iterator();
while (iterator.hasNext()) {
System.out.print(iterator.next());
}
System.out.println();
list.forEach(System.out::print);
System.out.println();
for (Integer ls : list) {
System.out.print(ls);
}
System.out.println();
System.out.println("遍历结束");
}
/**
* ArrayList的迭代器使用的是其内部类Itr完成的
* java.util.ConcurrentModificationException 分析
*/
private static void remove() {
System.out.println("删除开始");
//集合增删
//结果正常:[0, 1, 3, 4, 5, 6, 7, 8, 9]
//remove1();
//结果正常:[0, 1, 3, 4, 5, 6, 7, 8, 9]
//remove2();
//异常
//remove3();
//异常
//remove4();
//异常
//remove5();
//推荐使用这种方法删除
list.removeIf(Test::ok);
System.out.println(list);
System.out.println("删除结束");
}
/**
* modCount和expectedModCount的目的就是保证只有迭代期间只有一个迭代器对集合进行迭代
* 而此处就是因为由多个迭代器一起执行造成的异常
*/
private static void remove5() {
List<Integer> list3 = new ArrayList<>(list);
Iterator<Integer> iterator1 = list3.iterator();
Iterator<Integer> iterator2 = list3.iterator();
while (iterator1.hasNext()) {
Integer next = iterator1.next();
Integer next1 = iterator2.next();
if (ok(next)) {
iterator1.remove();
}
}
System.out.println(list3);
}
/**
* Itr.lastRet的值是-1,导致的异常,只有用next方法取过一次值,lastRet的值才不是初始化的-1
*/
private static void remove4() {
List<Integer> list1 = new ArrayList<>(list);
Iterator<Integer> iterator1 = list1.iterator();
while (iterator1.hasNext()) {
iterator1.remove();
}
System.out.println(list1);
}
/**
* modCount的值在调用ArrayList.remove的时候,会++
* 然后调用next的方法的时候,modCount和expectedModCount便不等了,导致的异常
*/
private static void remove3() {
List<Integer> list3 = new ArrayList<>(list);
Iterator<Integer> iterator1 = list3.iterator();
while (iterator1.hasNext()) {
Integer next = iterator1.next();
if (ok(next)) {
list3.remove(next);
}
}
System.out.println(list3);
}
private static void remove2() {
List<Integer> list2 = new ArrayList<>(list);
Iterator<Integer> iterator = list2.iterator();
while (iterator.hasNext()) {
Integer next = iterator.next();
if (ok(next)) {
iterator.remove();
}
}
System.out.println(list2);
}
private static void remove1() {
List<Integer> list1 = new ArrayList<>(list);
for (int i = 0; i < list1.size(); i++) {
if (ok(list1.get(i))) {
list1.remove(list1.get(i));
}
}
System.out.println(list1);
}
private static boolean ok(int i) {
return i == 2;
}
}
CopyOnWriteArrayList(线程安全的):
List<Integer> list = new CopyOnWriteArrayList<>();
list.add(2);
list.add(1);
Iterator<Integer> iterator = list.iterator();
while (iterator.hasNext()) {
Integer student = iterator.next();
if (student == 1) {
iterator.remove();
}
}
使用以上代码的时候,会报
java.lang.UnsupportedOperationException
翻看源码,CopyOnWriteArrayList实现的迭代器COWInterator不支持add、set、remove操作,
不过可以直接用其remove方法或者removeAll方法来删除。
CopyOnWriteArraySet:
其增删改操作使用的是其内部维护的CopyOnWriteArrayList来实现的。