4

質問はかなり漠然としているかもしれません。しかし、私がこれを尋ねる理由は、クラスが何らかの考えを念頭に置いて作成されたに違いないからです.

この質問は、SO でいくつかの質問を閲覧しているときに頭に浮かびました。

次のコードを検討してください。

class A
{

    private int myVar;

    A(int varAsArg)
    {
          myVar = varAsArg;
    }

   public static void main(String args[])
   {

      List<A> myList = new LinkedList<A>();
      myList.add(new A(1));
      myList.add(new A(2));
      myList.add(new A(3));

      //I can iterate manually like this:
      for(A obj : myList)
                 System.out.println(obj.myVar);

      //Or I can use an Iterator as well:
      for(Iterator<A> i = myList.iterator(); i.hasNext();)
      {
         A obj = i.next();
         System.out.println(obj.myVar);
      }
   }
}

上記のコードからわかるように、forループを使用して反復する代わりに、IteratorクラスhasNext()next()メソッドを使用して同じことを行うことができます。remove()同様に、メソッドの例があります。また、経験豊富なユーザーは、ループをIterator使用して. なんで?forList

さらに混乱しているのは、Iteratorクラスに3 つのメソッドしかないことです。また、これらの機能は、少し異なるコードを記述することでも実現できます。

class一部の人々は、多くのクラスの機能は、目的のために作成されたものを使用する代わりに、独自のコードを作成することによって実現できると主張するかもしれません。そうですね。しかし、私が言ったように、Iteratorクラスには 3 つのメソッドしかありません。複雑すぎて理解できない単純なコード ブロックで同じジョブを実行できるのに、余分なクラスを作成する手間がかかるのはなぜでしょうか。


編集:

私が取り組んでいる間、答えの多くは、を使用しないと削除機能を実現できないと言っているのでIterator、次のことが間違っているかどうか、または望ましくない結果になるかどうかを知りたいだけです。

for(A obj : myList)
{
           if(obj.myVar == 1)
                 myList.remove(obj);
}

上記のコード スニペットは と同じことをしremove()ませんか?

4

7 に答える 7

7

IteratorforあなたがJavaの進化で示す声明のずっと前に来ました。だからそれがそこにある理由です。また、何かを削除したい場合は、を使用することが唯一の方法です(そのためのステートメントをIterator.remove()使用することはできません)。for

于 2012-05-25T07:35:54.950 に答える
3

まず第一に、for-eachコンストラクトは実際には内部のIteratorインターフェースを使用します。ただし、基になるIteratorインスタンスをユーザーコードに公開しないため、そのインスタンスでメソッドを呼び出すことはできません。

Iteratorこれは、インターフェイスを明示的に使用する必要があり、for-eachループを使用しても実現できないことがいくつかあることを意味します。

現在の要素を削除することは、そのようなユースケースの1つです。

その他のアイデアについては、ListIteratorインターフェースを参照してください。これは、要素の挿入とカーソルの下の要素の変更をサポートする双方向イテレータです。これは、for-eachループでは実行できません。

for(A obj : myList)
{
           if(obj.myVar == 1)
                 myList.remove(obj);
}

上記のコードスニペットはremove()と同じことをしませんか?

いいえ、違います。私が知っているすべての標準コンテナは、ConcurrentModificationExceptionこれを行おうとするとスローされます。動作が許可されたとしても、あいまいであり(objリストに2回表示された場合はどうなりますか?)、非効率的です(リンクリストの場合、一定時間ではなく線形が必要になります)。

于 2012-05-25T07:37:41.247 に答える
3

foreach コンストラクト ( for (X x: list)) は、実際にはIterator内部でその実装として使用します。Iterable要素のソースとして任意にフィードできます。

そして、他の人がすでに述べているように、Java ではイテレータは foreach よりも長く、remove().

また、他にどのように独自のプロバイダー クラスを実装myListしますか (あなたの例では)? それIterableを作成し、 を作成するメソッドを実装しますIterator

于 2012-05-25T07:40:29.560 に答える
2

一つには、 foreachループ(上記のコードサンプルに示されている)がJavaに導入されるIterator前に作成されました。(前者はJava2で提供され、後者はJava5でのみ提供されました)。

Java5以降、実際、foreachループは、最も一般的なシナリオで推奨されるイディオムです(一度Iterableに単一をデフォルトの順序で反復し、要素を削除したりインデックスを付けたりする必要がない場合)。ただし、foreachは、標準のコレクションクラスのバックグラウンドでイテレータを使用することに注意してください。言い換えれば、それは単なる構文糖衣です。

于 2012-05-25T07:36:25.087 に答える
1

IteratorとlistIteratorはどちらも、ユーザーに異なる権限を許可するために使用されます。たとえば、list iteratorには9つのメソッドがありますが、iteratorには3つのメソッドしかありませんが、forループでは実現できない削除機能があります。列挙は、読み取り権限のみを与えるためにも使用されるもう1つのものです。

于 2012-05-25T07:37:49.517 に答える
0

Iteratorは、従来のGoFデザインパターンの実装です。このようにして、反復する「技術コード」(イテレーター)とビジネスコードから明確な動作の分離を実現できます。

'next'の動作を変更する必要があると想像してください(たとえば、次の要素ではなく、次のEVEN要素を取得することによって)。ループのみに依存している場合forは、次のように、すべてのforループを手動で変更する必要があります。

for (int i; i < list.size(); i = i+2)

一方、イテレータを使用する場合は、「next()」メソッドと「hasNext()」メソッドをオーバーライド/書き換えるだけで、アプリケーションのどこにでも変更が表示されます。

于 2012-05-25T07:42:49.767 に答える
0

あなたの質問への答えは抽象化だと思います。イテレータは、異なるコレクションのセットに対する反復を抽象化するために書かれています。

すべてのコレクションには、要素を反復処理するためのさまざまなメソッドがあります。ArrayList にはインデックス アクセスがあります。Queues には poll メソッドと peek メソッドがあります。スタックにはポップ アンド ピークがあります。

通常、要素を反復処理する必要があるだけなので、Iterator が機能します。どのタイプの Collection を反復する必要があるかは気にしません。これを行うには、 iterator() メソッドとユーザー Iterator オブジェクト自体を呼び出すだけです。

コレクションインターフェイスに同じメソッドを配置して、余分なオブジェクトの作成を削除しない理由を尋ねると。コレクション内の現在の位置を知る必要があるため、次のメソッドを別の場所で使用できないため、別の場所では使用できないため、コレクション内の現在の位置を知る必要があります。異なる場所で同じコレクションを使用すると、いくつかのオブジェクトがスキップされます。また、コレクションが同時実行をサポートしている場合、マルチスレッド セーフな next() メソッドをコレクションに記述できません。

通常、反復子以外の方法で反復するコレクションからオブジェクトを削除することは安全ではありません。Iterator.remove() メソッドが最も安全な方法です。ArrayList の例: for(int i=0;i

于 2012-05-25T08:10:47.443 に答える