コードは以下のように表示されます
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例外を回避できますが、セキュリティ リスクがないわけではありません。
いくつかのセキュリティリスクを次に示します。
-
トラバーサル プロセス中に操作を追加または削除すると、エラーが発生する可能性があります。ListIterator を使用して要素を追加または削除する場合、トラバーサル プロセス中の列挙順序が影響を受ける可能性があるため、トラバーサル プロセス中の追加および削除操作はお勧めできません。
-
双方向トラバーサル: ListIterator は双方向トラバーサルをサポートしています。つまり、トラバーサル プロセス中に前後に移動できるため、トラバーサル プロセス中に誤ってコレクションを変更するとエラーが発生する可能性があります。
-
同時変更: ListIterator はシングルスレッド ツールであり、同時変更をサポートしていないため、複数のスレッドが同時にコレクションを変更すると、不整合の問題が発生する可能性があります。
したがって、 ListIteratorを使用する場合でも、プログラムの正確性を確保するために、トラバーサル プロセス中のコレクション操作に注意を払う必要があります。