2
for(Element e : elementList)

for (Iterator<Element> itr = elementList.iterator(); itr.hasNext();)

最初のものははるかに簡単です。2つ目をやりたい理由や利点はありますか?

4

5 に答える 5

4

内部的にはどちらもイテレータを使用していますが、唯一の違いは、強化された for ループを使用すると、コードがより明確で短くなることです。両方についてjavadocが言っていることは次のとおりです。

コレクションの反復処理は、必要以上に醜いものです。タイマー タスクのコレクションを取得し、それらをキャンセルする次のメソッドを検討してください。

void cancelAll(Collection<TimerTask> c) {
    for (Iterator<TimerTask> i = c.iterator(); i.hasNext(); )
        i.next().cancel();
}

イテレータは雑然としています。さらに、それはエラーの機会でもあります。iterator 変数は各ループで 3 回発生します。つまり、2 回間違える可能性があります。for-each コンストラクトは、混乱とエラーの可能性を取り除きます。for-each コンストラクトを使用した場合の例を次に示します。

void cancelAll(Collection<TimerTask> c) {
    for (TimerTask t : c)
        t.cancel();
}

コロン (:) がある場合は、「in」と読みます。上記のループは、「c の各 TimerTask t に対して」と読みます。ご覧のとおり、for-each コンストラクトはジェネリックと見事に組み合わされています。残りの混乱を取り除きながら、すべての型の安全性を維持します。イテレータを宣言する必要がないため、イテレータのジェネリック宣言を提供する必要はありません。(コンパイラはこれをあなたの背後で行いますが、気にする必要はありません。)

イテレータではなく for-each ループを使用する理由の完全な説明については、次を参照してください。

http://docs.oracle.com/javase/1.5.0/docs/guide/language/foreach.html

于 2013-06-06T01:27:17.680 に答える
2

最初の形式は Java 5 で導入され、2 番目の形式はほとんどが以前のバージョンの言語のレガシー コードに見られます。それでもなお、2 番目の形式を使用する必要がある状況がいくつかあります。たとえば、ループが繰り返されるときに要素の一部 (またはすべて) を削除できる必要がある場合は、そのメソッドitrを呼び出すことができるようにする必要があります。remove

于 2013-06-06T01:27:36.767 に答える
1

イテレーターは collection から要素をremove()できますが、これは for each ループを使用して行うことはできません

于 2013-06-06T01:29:08.857 に答える
0

それらは非常に同じです。このコードを検討してください

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

public class IteratorTest {

  public static void main(String[] args){

    ArrayList<Object> list = new ArrayList();
    list.add(new Object());
    list.add(new Object());

    for(Object o : list) 
      System.out.println(o);

    for(Iterator<Object> itr = list.iterator();itr.hasNext();) 
      System.out.println(itr.next());


  }
}

次に、それをコンパイルして逆アセンブルします。

javap -c IteratorTest

メインメソッドの次のバイトコードを取得します

  public static void main(java.lang.String[]);
    Code:
       0: new           #2                  // class java/util/ArrayList
       3: dup           
       4: invokespecial #3                  // Method java/util/ArrayList."<init>":()V
       7: astore_1      
       8: aload_1       
       9: new           #4                  // class java/lang/Object
      12: dup           
      13: invokespecial #1                  // Method java/lang/Object."<init>":()V
      16: invokevirtual #5                  // Method java/util/ArrayList.add:(Ljava/lang/Object;)Z
      19: pop           
      20: aload_1
      21: new           #4                  // class java/lang/Object
      24: dup           
      25: invokespecial #1                  // Method java/lang/Object."<init>":()V
      28: invokevirtual #5                  // Method java/util/ArrayList.add:(Ljava/lang/Object;)Z
      31: pop           
      32: aload_1       
      33: invokevirtual #6                  // Method java/util/ArrayList.iterator:()Ljava/util/Iterator;
      36: astore_2      
      37: aload_2       
      38: invokeinterface #7,  1            // InterfaceMethod java/util/Iterator.hasNext:()Z
      43: ifeq          63
      46: aload_2       
      47: invokeinterface #8,  1            // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
      52: astore_3      
      53: getstatic     #9                  // Field java/lang/System.out:Ljava/io/PrintStream;
      56: aload_3       
      57: invokevirtual #10                 // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
      60: goto          37
      63: aload_1       
      64: invokevirtual #11                 // Method java/util/ArrayList.iterator:()Ljava/util/Iterator;
      67: astore_2      
      68: aload_2       
      69: invokeinterface #7,  1            // InterfaceMethod java/util/Iterator.hasNext:()Z
      74: ifeq          92
      77: getstatic     #9                  // Field java/lang/System.out:Ljava/io/PrintStream;
      80: aload_2       
      81: invokeinterface #8,  1            // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
      86: invokevirtual #10                 // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
      89: goto          68
      92: return        
}

行 32 から 60 は最初のループで、行 63 から 89 は 2 番目のループです。一部のローカルの名前が変更され、わずかに並べ替えられているだけで、ほとんど同じであることがわかります。

したがって、コンパイラは 2 つの式に対して同じバイトコードを生成するため、それらは同じです。

于 2013-06-06T07:54:52.803 に答える
0

性能差はありません。しかし、反復子を使用することで、より多くの機能を使用できるようになります。たとえば、ループ内で Iterator を参照できます。これにより、コレクション アイテムを削除してConcurrentModificationException.

以下を使用できます

for (Iterator<Element> itr = elementList.iterator(); itr.hasNext();){
     if(o meets some condition){
          itr.remove();
     }
}

しかし、これではありません

   for(Element e : elementList){
         if(o meets some condition){
              elementList.remove(e);
         }
    }

ただし、この違いが気にならない場合は、快適なものを使用できます。

似たような質問

于 2013-06-06T01:35:55.823 に答える