Java集合框架篇-44-ListIterator解决并发修改异常报错

      本篇先来一个练习题,引出什么是并发修改异常,然后给出解决这个问题的方案。什么是并发修改异常呢?如果我们在遍历集合元素,并进行添加操作的时候,就会报并发修改异常错误,下面我们来举例一下。

 

1. 练习题

在一个集合中,如果找到一个元素是”world”,那么就添加一个“Java”的元素。下面,我们根据前面的集合知识,尝试写出代码应该如下面这样。

 

package list;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

public class Demo2_List {

   public static void main(String[] args) {

      List list= new ArrayList();
      list.add("a");
      list.add("b");
      list.add("world");
      list.add("c");
      list.add("d");

      //用迭代器遍历
      Iterator it = list.iterator();      //获取迭代器
      while(it.hasNext()) {
        if("world".equals(it.next())) {
           list.add("java");      //这个时候,我们只能想起用add方法
        }
      }

      System.out.println(list);

   }

}

运行输出:

Exception in thread "main" java.util.ConcurrentModificationException
   atjava.util.ArrayList$Itr.checkForComodification(Unknown Source)
   atjava.util.ArrayList$Itr.next(Unknown Source)
   atlist.Demo2_List.main(Demo2_List.java:20)

       在JAVA JDK 1.6 API中搜索ConcurrentModificationException这个类,可以看到这么一句话:当方法检测到对象的并发修改,但不允许这种修改时,抛出此异常。

       上面用通俗的语言来分析就是这样的,我们有list这个集合,当前是有5个元素。然后就把自己有5个元素信息传递给了迭代器。在遍历的过程中,又出现了需要添加元素,但是迭代器只认为有5个元素进行遍历,现在突然添加元素到集合,迭代器就不知道怎么办了,就抛出并发修改的异常。为了解决这个异常,我们下面学习一个新的类,叫ListIterator。

 

package list;

import java.util.ArrayList;
import java.util.List;
import java.util.ListIterator;

public class Demo2_List {

   public static void main(String[] args) {

      List list= new ArrayList();
      list.add("a");
      list.add("b");
      list.add("world");
      list.add("c");
      list.add("d");

      //用迭代器遍历
      ListIterator it = list.listIterator();    //获取迭代器
      while(it.hasNext()) {
        if("world".equals(it.next())) {
           it.add("java");     //注意是用listiterator迭代器添加元素
        }
      }
      System.out.println(list);
   }
}
 

输出:

[a, b, world, java, c, d]

 

      下面,我们在API找到ListIterator,看看有哪些方法,并写代码进行测试。上面解决并发修改异常,我们用到了这个接口的add()方法,下面看看其他方法的基本使用。

 

package list;

import java.util.ArrayList;
import java.util.List;
import java.util.ListIterator;

 
public class Demo3_ListIterator {

   public static void main(String[] args) {

      List list= new ArrayList();
      list.add("a");
      list.add("b");
      list.add("world");
      list.add("c");
      list.add("d");

      //用迭代器遍历
      ListIteratorl it= list.listIterator();   //获取迭代器
      //正向遍历
      while(lit.hasNext()) {

        System.out.println(lit.next());

      }

      System.out.println("----------------");

      //逆向遍历

      while(lit.hasPrevious()) {

        System.out.println(lit.previous());

      }
   }
}

输出:

a
b
world
c
d
----------------
d
c
world
b
a

       上面是hasPrevious()方法和previous(),这个刚好和前面集合学习的正向遍历方法相反,是把集合从后往前遍历的方法。这里需要注意一个问题,如果前面我们不写hasNext()遍历,直接使用hasPrevious(),输出的是空白,因为一开始指针指向是索引0的元素,0前面肯定没有其他的元素,索引hasPrevious()返回是false,就不会继续while循环。这种反向遍历,在实际工作中应该没有什么作用,使用机会不多。剩下的remove()set()就不联系,和前面的介绍的删除元素和修改元素一样的功能。

 

你可能感兴趣的:(Java集合框架篇-44-ListIterator解决并发修改异常报错)