Java の基礎 (2) - イテレーターを使用すると ConcurrentModificationException が発生する

コードは以下のように表示されます

Listコレクションを走査し、特定の条件が満たされた場合にコレクションを変更します。コードは次のとおりです。

public class MyListDemo {
    
    
  public static void main(String[] args) {
    
    
  
    List<String> list = Lists.newArrayList("a", "b", "c", "d");

    Iterator<String> iterator = list.iterator();
    while (iterator.hasNext()) {
    
    
      String next =  iterator.next();
      if (next.equals("d")) {
    
    
        iterator.set("f");
      }
    }
    System.out.println("list = " + list);
  }
}

最終的な入力結果は次のようになります。

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)
	at org.apache.ibatis.gwmtest.current.MyListDemo.main(MyListDemo.java:19)

Process finished with exit code 1

ConcurrentModificationException がスローされることがわかりましたが、どのように変更すればよいでしょうか? Iterator インターフェイスのサブクラスを使用して操作できますListIterator。コードは次のとおりです。

public class ListDemo {
    
    
  public static void main(String[] args) {
    
    
    List<String> list = Lists.newArrayList("a", "b", "c", "d");

    ListIterator<String> iterator = list.listIterator();

    while (iterator.hasNext()) {
    
    
      String next =  iterator.next();
      if (next.equals("d")) {
    
    
        iterator.set("f");
        iterator.add("g");
      }
    }
    System.out.println("list = " + list);
  }
}

出力結果:

list = [a, b, c, f, g]

コレクションに対する操作は、 List自体ではなく、ListIteratorオブジェクトを通じて行われます

ListIteratorを使用するとConcurrentModificationException例外を回避できますが、セキュリティ リスクがないわけではありません。

いくつかのセキュリティリスクを次に示します。

  1. トラバーサル プロセス中に操作を追加または削除すると、エラーが発生する可能性があります。ListIterator を使用して要素を追加または削除する場合、トラバーサル プロセス中の列挙順序が影響を受ける可能性があるため、トラバーサル プロセス中の追加および削除操作はお勧めできません。

  2. 双方向トラバーサル: ListIterator は双方向トラバーサルをサポートしています。つまり、トラバーサル プロセス中に前後に移動できるため、トラバーサル プロセス中に誤ってコレクションを変更するとエラーが発生する可能性があります。

  3. 同時変更: ListIterator はシングルスレッド ツールであり、同時変更をサポートしていないため、複数のスレッドが同時にコレクションを変更すると、不整合の問題が発生する可能性があります。

したがって、 ListIteratorを使用する場合でも、プログラムの正確性を確保するために、トラバーサル プロセス中のコレクション操作に注意を払う必要があります。

おすすめ

転載: blog.csdn.net/qq_35971258/article/details/129028008