- 例如我们要完成以下需求:
- 在一个存储字符串的集合中,如果存在字符串"Java",则添加一个"Android"
- 示范代码如下:
[Java] 纯文本查看 复制代码public class Test {
public static void main(String[] args){
ArrayList<String> list = new ArrayList<String>();
list.add("Java");
list.add("Hello");
list.add("World");
Iterator<String> it = list.iterator();//获取迭代器对象
while(it.hasNext()){ //如果迭代器判断集合中还有下一个元素则继续循环
String str = it.next();//获取集合中迭代器所指向的元素
if(str.equals("Java")) {//如果这个元素内容是"Java"
list.add("Android");//则在集合中添加一个"Android"
}
}
}
}
- 控制台输出:
[Java] 纯文本查看 复制代码Exception in thread "main" java.util.ConcurrentModificationException
at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:859)
at java.util.ArrayList$Itr.next(ArrayList.java:831)
at com.itheima.day02.Test5.main(Test5.java:17)
2. 异常是如何产生的
控制台显示的ConcurrentModificationException,即并发修改异常 下面我们就以ArrayList集合中出现的并发修改异常为例来分析异常产生的原因。
final void checkForComodification() {
if (modCount != expectedModCount)
throw new ConcurrentModificationException();
}The number of times this list has been structurally modified
private class Itr implements Iterator<E> {
int cursor;
int lastRet = -1;
int expectedModCount = modCount;
....
- 每删除一个元素,modCount的值会自增一次
public E remove(int index) {
rangeCheck(index);
modCount++;
...//此处省略代码
E oldValue = elementData(index);
return oldValue;
}private void ensureExplicitCapacity(int minCapacity) {
modCount++;
if (minCapacity - elementData.length > 0)
grow(minCapacity);
}private class Itr implements Iterator<E> {
int cursor; // index of next element to return
int lastRet = -1; // index of last element returned; -1 if no such
int expectedModCount = modCount;
.....//此处省略下方其他源码
}public boolean hasNext() {
return cursor != size;
}分析:
public E next() {
checkForComodification();
int i = cursor;
if (i >= size)
throw new NoSuchElementException();
Object[] elementData = ArrayList.this.elementData;
if (i >= elementData.length)
throw new ConcurrentModificationException();
cursor = i + 1;
return (E) elementData[lastRet = i];
}
//在next方法的第一行调用了此方法
final void checkForComodification() {
if (modCount != expectedModCount)
throw new ConcurrentModificationException();
}分析:
public void remove() {
if (lastRet < 0)
throw new IllegalStateException();
checkForComodification();
try {
ArrayList.this.remove(lastRet);
cursor = lastRet;
lastRet = -1;
expectedModCount = modCount;
} catch (IndexOutOfBoundsException ex) {
throw new ConcurrentModificationException();
}
}public void add(E e) {
checkForComodification();
try {
int i = cursor;
ArrayList.this.add(i, e);
cursor = i + 1;
lastRet = -1;
expectedModCount = modCount;
} catch (IndexOutOfBoundsException ex) {
throw new ConcurrentModificationException();
}
}public static void main(String[] args){
ArrayList<String> list = new ArrayList<String>();
list.add("Java");
list.add("Hello");
list.add("World");
for (int i = 0; i < list.size(); i++) {
String element = list.get(i);
if(element.equals("Java")){
/* 注意:
* 当集合中增删元素后 i 索引的指向元素有可能发生变化,
* 我们通常会在增删元素的同时让i变量也随之变化,
* 从而使 i 能正确指向下一个元素:list.remove(i--);
*/
list.remove(i);
}
}
}public static void main(String[] args){
ArrayList<String> list = new ArrayList<String>();
list.add("Java");
list.add("Hello");
list.add("World");
for (String s : list) {
System.out.println(s);//在此行代码打上断点,然后开启debug运行程序
}
}public static void main(String[] args){
ArrayList<String> list = new ArrayList<String>();
list.add("Java");
list.add("Hello");
list.add("World");
for (String s : list) {
if(s.equals("Hello")){
list.remove("Java");
}
}
System.out.println(list);//控制台输出:[Hello, World]
}
| 欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) | 黑马程序员IT技术论坛 X3.2 |