Javaコレクションフレームワーク編-44-ListIterator同時修正異常エラー解決

3413 ワード

本編ではまず,異常の同時修正とは何かを引き出し,この問題を解決するための案を示す練習問題を提示する.同時修正異常とは何ですか?集合要素を巡回して追加操作を行うと、例外エラーの同時修正が報告されます.次に例を挙げます.
 
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というクラスを検索すると、メソッドがオブジェクトの同時修正を検出したが、このような修正が許可されていない場合、この異常を投げ出すという言葉が見られます.
上で通俗的な言語で分析すると、リストという集合があり、現在は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()は連絡が取れず、前述した削除要素や修正要素と同じ機能です.