13

昨日、イテレータと削除の使用中に ConcurrentModificationException エラーが発生するという質問に答えていたときに、その通知を追加しました

ArrayList がある場合に反復子を使用するのは得策ではありません。

その質問に答えるために、その質問を深く理解する必要はありません。

そこで、私が間違っているというコメントを 2 つ受け取りました。

私の主張:

  1. イテレータを使用すると、コードの可読性が大幅に低下します。

  2. デバッグが困難な ConcurrentModificationException が発生する可能性があります。

説明していただけますか?

質問: ArrayList でイテレータを使用する必要はありますか?

UPD

これは、Iterator を明示的に使用することに関するものです。

4

6 に答える 6

25

ArrayLists でのイテレータの主な使用例は、反復中に要素を削除する場合です。安全な解決策は 3 つだけです。

  • イテレータとそのremoveメソッドを使用する
  • 保持したい要素を別のリストにコピーします
  • インデックスのあるジャングル

反復中にそうしないと仮定するとadd、反復子を使用することConcurrentModificationException.

読みやすさの議論は主観的なものです。個人的には、きれいに宣言されたイテレータが読みにくいとは思いません。そして、反復子は反復と削除を同時に行う安全な方法であるため、実際には問題ではありません。

于 2013-04-05T06:58:40.167 に答える
15

イテレータの理由を説明する答えはないようです。イテレータ デザイン パターンが作成されたのは、オブジェクトが独自の状態を制御する必要があるためです (パブリック プロパティのみを持つ値オブジェクトを除く)。

配列を含むオブジェクトがあり、そのオブジェクトにその配列にアイテムを追加するためのインターフェイスがあるとしましょう。しかし、あなたは次のようなことをしました:

class MyClass
{
    private ArrayList<Item> myList;

    public MyClass()
    {
        myList = new ArrayList();
    }

    public addItem( Item item )
    {
         item.doSomething(); // Lets say that this is very important before adding the item to the array.
         myList.add( item );
    }
}

上記のクラスにこのメソッドがあった場合:

public ArrayList getList()
{
    return myList;
}

item.doSomething(); を呼び出さに、誰かがこのメソッドを介して myList への参照を取得し、配列にアイテムを追加することができます。そのため、配列への参照を返すのではなく、その反復子を返す必要があります。配列から任意の項目を取得できますが、元の配列を操作することはできません。そのため、MyClass オブジェクトはまだ独自の状態を制御しています。

これがイテレータが発明された本当の理由です。

于 2015-01-16T13:17:40.190 に答える