web-dev-qa-db-ja.com

Javaの拡張forループとイテレータの利点は何ですか?

Java +5のEnhancedforループとイテレータの利点を教えてください。

22
Mahmoud Saleh

長所と短所はStephen Colebourne(Joda-Time、JSR-310など)でかなりよくまとめられています 各ループ反復制御のために拡張 Java 7で拡張する提案:

機能の概要:

Java 5 for-eachループを拡張して、これが最初または最後の反復であるかどうかに関係なく、ループインデックスへのアクセスを許可し、現在のアイテムを削除します。

主な利点

For-eachループは、ほぼ間違いなくJava 5の最も新しい人気のある機能です。これは、低レベルを表現する代わりに、抽象化レベルを上げるために機能します。リストまたは配列(インデックスまたはイテレーター付き)をループする方法の詳細については、開発者は単にループすることを宣言し、残りは言語が処理します。ただし、開発者がインデックスにアクセスするか、アイテムを削除する必要があるとすぐに、すべての利点が失われます

各作業の元のJava 5は、80%のケースに取り組むことを目的とした、いくつかの問題に対して比較的保守的なスタンスを取りました。ただし、ループはコーディングにおいて非常に一般的な形式であり、対処されなかった残りの20%は重要なコード本体を表します。

ループをforeachからインデックスベースまたはイテレータベースに変換するプロセスは面倒です。これは、古いループスタイルが大幅に低レベルの場合、がより冗長で明確でないためです。ほとんどのIDEはこの種の「リファクタリング解除」をサポートしていないため、これも苦痛です。

主なメリット:

一般的なコーディングイディオムは、現在よりも高い抽象度で表現されています。これは読みやすさと明瞭さに役立ちます。

.。

要約すると、拡張されたforループは、リストまたは配列をループするための簡潔で高レベルの構文を提供し、明快さと読みやすさを向上させます。ただし、インデックスループへのアクセスやアイテムの削除を許可するなど、一部の要素がありません。

も参照してください

21
Pascal Thivent

私にとっては、明らかなことですが、主な利点は読みやすさです。

for(Integer i : list){
   ....
}

のようなものよりも明らかに優れています

for(int i=0; i < list.size(); ++i){
  ....
}
12
sly7_7

私はそれを紹介しているドキュメントのページ here でかなり要約されていると思います。

コレクションの繰り返し処理は必要以上に醜い

仰るとおり..

イテレータはごちゃごちゃしています。さらに、それはエラーの機会です。イテレータ変数は、各ループで3回発生します。これは、間違ってしまう可能性が2回あります。 for-eachコンストラクトは、混乱とエラーの機会を取り除きます。

丁度

コロン(:)が表示されたら、「中」と読みます。上記のループは、「cの各TimerTask tについて」と読みます。ご覧のとおり、for-eachコンストラクトはジェネリックスと美しく組み合わされています。残りの雑然としたものを取り除きながら、すべてのタイプの安全性を維持します。イテレータを宣言する必要がないため、イテレータの一般的な宣言を提供する必要はありません。 (コンパイラーはあなたの後ろでこれを行いますが、あなたはそれを気にする必要はありません。)

もっとまとめたいのですが、そのページはほぼ完璧に機能していると思います。

4
Lee Jarvis

Iterableおよび配列である任意のコレクションを反復処理できます。また、パフォーマンスの違いは、何も心配する必要はありません。

読みやすさが重要です。

_Prefer this    
for (String s : listofStrings) 
    {
     ... 
    }

over

    for (Iterator<String> iter = listofStrings.iterator(); iter.hasNext(); )
    {
     String s = iter.next();
     ...
    }
_

繰り返しながら要素を削除する必要がある場合は、Iteratorを使用する必要があることに注意してください。

例えば、

_List<String> list = getMyListofStrings(); 

    for (Iterator<String> iter = list.iterator(); iter.hasNext(); ) 
    {
        String s = iter.next();
        if (someCondition) {
            iter.remove(); 
        }
    }
_

for(String s : myList)を使用してリスト内の要素を削除することはできません。
また、配列を反復処理する場合、foreach(または拡張)は要素を取得するためにのみ使用でき、配列内の要素を変更できないことにも注意してください。
詳細については、 this を参照してください。

3
Zaki

より明確な構文!これはプログラマーにとって便利なだけなので、パフォーマンスの観点からも違いはありません。

2
Gopi

他の人が言ったように、強化されたforループは、より簡潔な構文、読みやすいコードを提供し、型を減らします。

さらに、「インデックスが範囲外」のエラーシナリオも回避されます。たとえば、リストを手動で反復する場合、次のようにインデックス変数を間違った方法で使用する可能性があります。

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

例外をスローします。ただし、強化されたforループの場合、反復作業はコンパイラーに任せます。エラーケースを完全に回避します。

1
Veera

主な欠点は、インデックスベースのループにはないイテレータの作成です。通常は問題ありませんが、パフォーマンスが重要なセクション(たとえば、リアルタイムアプリケーションでは、1秒間に数百回実行する必要がある場合)では、GCの大きな介入が発生する可能性があります...

1
Gyscos

より簡潔です。問題はnullチェックのみです。

for (String str : strs) {  // make sure strs is not null here
    // Do whatever
}
0
fastcodejava

他の人がすでに答えているように、それはクリーナーのためのシンタックスシュガーです。クラスIteratorループと比較すると、宣言する必要のある変数が1つ少なくなっています。

0
Dennis C

Foreach/enhanced for/forループは、カーソルをデータオブジェクトに提供する役割を果たします。これは、実装が簡単で簡単なため、「ファイルを1行ずつウォークする」または「結果セットをレコードごとにウォークする」という観点から考える場合に特に便利です。

これにより、呼び出し元(forループ)が値のフェッチ方法やコレクションサイズ、その他の実装の詳細を知る必要がなくなるため、インデックスベースのメソッドと比較して、より一般的で改善された反復方法も提供されます。

0
user268396