为什么foreach中不允许对元素进行add和remove?
阅读本文大概需要 5 分钟。
来自:网络
读者遇到了一个比较经典的面试题,也就是标题上说的,为什么 foreach 中不允许对元素进行 add 和 remove。就这个问题深入分析一下为什么不让使用 add 和 remove,并且实际运行一下,我们来看一下。
ArrayList
public static void main(String[] args) {
Listlist = new ArrayList<>();
//把元素放到list里面去
for (int i = 0 ; i < 10 ; i++ ) {
list.add(i + "");
}
for (String s: list) {
if ("5".equals(s)){
list.remove(5);
}
System.out.println(s);
}
}
Exception in thread "main" java.util.ConcurrentModificationException
at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:911)
at java.util.ArrayList$Itr.next(ArrayList.java:861)
public static void main(String[] args) {
Listlist = new ArrayList<>();
//把元素放到list里面去
for (int i = 0 ; i < 10 ; i++ ) {
list.add(i);
}
Iteratoriterator = list.iterator();
while(iterator.hasNext()){
Integer integer = iterator.next();
if(integer==5){
list.remove(); //注意这个地方
}
}
}
Exception in thread "main" java.util.ConcurrentModificationException
at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:911)
at java.util.ArrayList$Itr.next(ArrayList.java:861)
final void checkForComodification() {
if (modCount != expectedModCount)
throw new ConcurrentModificationException();
}
public E remove(int index) {
rangeCheck(index); //检查index是否合法
modCount++; //modCout直接++
E oldValue = elementData(index);
int numMoved = size - index - 1;
if (numMoved > 0)
System.arraycopy(elementData, index+1, elementData, index,
numMoved);
elementData[--size] = null; // clear to let GC do its work
return oldValue;
}
public boolean remove(Object o) {
if (o == null) {
for (int index = 0; index < size; index++)
if (elementData[index] == null) {
fastRemove(index);
return true;
}
} else {
for (int index = 0; index < size; index++)
if (o.equals(elementData[index])) {
fastRemove(index);
return true;
}
}
return false;
}
private void fastRemove(int index) {
modCount++;
int numMoved = size - index - 1;
if (numMoved > 0)
System.arraycopy(elementData, index+1, elementData, index,
numMoved);
elementData[--size] = null; // 设置为null方便GC
}
int expectedModCount = modCount;
final int expectedModCount = modCount;
public static void main(String[] args) {
Listlist = new ArrayList<>();
//把元素放到list里面去
for (int i = 0 ; i < 10 ; i++ ) {
list.add(i);
}
System.out.print("没有删除元素前"+list.toString());
Iteratoriterator = list.iterator();
while(iterator.hasNext()){
Integer integer = iterator.next();
if(integer==5){
iterator.remove(); //注意这个地方
}
}
System.out.print("删除元素后"+list.toString());
}
没有删除元素前[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
删除元素后[0, 1, 2, 3, 4, 6, 7, 8, 9]
public static void main(String[] args) {
CopyOnWriteArrayListlist = new CopyOnWriteArrayList<>();
//把元素放到list里面去
for (int i = 0 ; i < 10 ; i++ ) {
list.add(i);
}
System.out.print("没有删除元素前"+list.toString());
Iteratoriterator = list.iterator();
while(iterator.hasNext()){
Integer integer = iterator.next();
if(integer==5){
list.remove(5); //注意这个地方
}
}
System.out.print("删除元素后"+list.toString());
}
没有删除元素前[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
删除元素后[0, 1, 2, 3, 4, 6, 7, 8, 9]
推荐阅读:
Spring Boot + Vue + Shiro 实现前后端分离,写得太好了!
最近面试BAT,整理一份面试资料《Java面试BATJ通关手册》,覆盖了Java核心技术、JVM、Java并发、SSM、微服务、数据库、数据结构等等。
朕已阅