HOWTO · Java

Java Iterator remove() メソッド

この記事では、Iterator の remove メソッドが Java のコレクションから要素を削除する方法について説明します。

Java 開発者は、反復中に ArrayList から要素またはオブジェクトを削除する必要があることがよくあります。

ここで問題が発生するのは、元のコレクションからオブジェクトを削除しようとしたときにオブジェクトをループ処理しているときに、オブジェクトが ConcurrentModificationException をスローするためです。 この記事では、Iteratorremove() メソッドと Collectionremove() メソッドの動作の違いを学びます。

Collectionremove() メソッドの紹介

Java では、Collection は、ArrayListSet などのさまざまなデータ型を含むインターフェイスです。Collection から要素を削除するには、コレクションを取得して remove() メソッドを使用できます。 参考までに。

ユーザーは、次の構文に従って、コレクションで remove() メソッドを使用できます。

collection.remove(Ind);

Ind - remove() メソッドは、参照された collectionInd インデックスから要素を削除します。

Collectionremove() メソッドを使用する

以下の例では、コレクションを作成し、collectionremove() メソッドを使用して 2 番目と 4 番目のインデックスから要素を削除しています。

import java.util.ArrayList;
class Test {
  public static void main(String[] args) {
    // Create an ArrayList
    ArrayList<String> testList = new ArrayList<String>();
    // Add elements in the ArrayList
    testList.add("Apple");
    testList.add("Banana");
    testList.add("Cat");
    testList.add("Dog");
    testList.add("Fox");
    testList.add("Cow");
    // Removing the element at index 2 and 4
    System.out.println(testList.remove(2) + " removed\n");
    System.out.println(testList.remove(4) + " removed");
  }
}

出力:

Cat removed
Cow removed

上記の出力では、cat を 2 番目のインデックスから削除すると、ArrayList のすべての要素が 1つのインデックスだけシフトすることがわかります。

2 番目のインデックスから要素を削除した後、4 番目のインデックスから要素を削除しようとすると、remove() メソッドは、2 番目のインデックスの後のすべての要素が 1左。

Collectionremove() メソッドがどのように正常に機能するかを学びました。

Iteratorremove() メソッドの紹介

さて、問題は、Collection から要素を削除するため、IteratorCollectionremove() メソッドの違いは何ですか?

以下のコードを使用して問題を理解しましょう。

import java.util.ArrayList;
class Test {
  public static void main(String[] args) {
    // Create an ArrayList
    ArrayList<String> testList = new ArrayList<String>();
    // Add elements in the ArrayList
    testList.add("Apple");
    testList.add("Banana");
    testList.add("Cat");
    testList.add("Dog");
    testList.add("Fox");
    testList.add("Cow");
    for (String element : testList) {
      if (element.equals("Cat")) {
        testList.remove(element);
      }
    }
  }
}

上記の例では、異なる文字列の ArrayList を作成しました。 for ループを使用して ArrayList を反復処理し、要素が cat と等しいかどうかを確認し、collection.remove() メソッドを使用してそれを削除しようとします。

出力では、反復中に元のリストを変更すると、ConcurrentModificationException 例外がスローされることがわかります。

出力:

Exception in thread "main" java.util.ConcurrentModificationException

この問題を解決するには、iterator を使用して ArrayList を反復処理し、Iteratorremove() メソッドを使用して要素を削除します。

Iteratorremove() メソッドを使用する

以下の例では、文字列の ArrayList のイテレータ名 itr を作成しました。 for ループと itr を使用して ArrayList を反復処理しています。

また、反復処理中に ArrayList から Fox 要素を削除しています。

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

class Test {
  public static void main(String[] args) {
    // Create an ArrayList
    ArrayList<String> testList = new ArrayList<String>();
    // Add elements in the ArrayList
    testList.add("Apple");
    testList.add("Banana");
    testList.add("Cat");
    testList.add("Dog");
    testList.add("Fox");
    testList.add("Cow");
    // Removing the "Fox" while iterating through the `testList`
    Iterator<String> itr = testList.iterator();
    while (itr.hasNext()) {
      String element = itr.next();
      if (element.equals("Fox")) {
        testList.remove(element);
      }
    }
    System.out.println(testList);
  }
}

出力:

[Apple, Banana, Cat, Dog, Cow]

上記の出力で ArrayList を繰り返し処理しているときに、Fox が削除されていることがわかります。

Iteratorremove() メソッドのコードを理解する

以下の iteratorremove() メソッドの疑似コードは、Java の公式ドキュメントから取得しました。 ArrayListremove() メソッドも使用していることがわかりますが、ConcurrentModificationException 例外をスローしない expectedModCount も更新します。

ArrayList を反復処理するときは、常に次の要素を知る必要があります。 したがって、remove() メソッドを使用して元のリストを変更しようとすると、次のインデックスは更新されず、エラーがスローされます。この問題は、iteratorremove() メソッドで解決されます。

try {
  ArrayList.this.remove(lastRet);
  cursor = lastRet;
  lastRet = -1;
  expectedModCount = modCount;
} catch (IndexOutOfBoundsException ex) {
  throw new ConcurrentModificationException();
}

また、ユーザーはリストを複製して、新しいリストを反復処理できます。 新しいリストを繰り返し処理している間に、元のリストから要素を削除できます。