![]() |
For-Each ループ |
Language の目次
|
void cancelAll(Collection<TimerTask> c) { for (Iterator<TimerTask> i = c.iterator(); i.hasNext(); ) i.next().cancel(); }
反復子を使用しても複雑になるだけです。さらに、エラーが発生する恐れもあります。反復子変数は各ループで 3 回発生しています。つまり、失敗する可能性は 2 回あることになります。for-each 構造を使用すれば複雑さやエラーの危険性は排除されます。for-each 構造の例を次に示します。
void cancelAll(Collection<TimerTask> c) { for (TimerTask t : c) t.cancel(); }
コロン (:
) は「in (~の中の)」という意味です。上記のループは「c
内の TimerTask t
ごと」ということになります。見てのとおり、for-each 構造は、総称ときれいに結びついています。この構造により、すべての型は安全に保たれ、複雑さは取り除かれます。反復子を宣言する必要がないため、反復子の総称宣言を行う必要もありません。プログラマに見えない所でコンパイラが総称宣言を行いますが、プログラマはそのことを認識する必要はありません。
入れ子にされた反復を、2 つのコレクションに対して行おうとするときに犯しがちな、一般的な誤りを次に示します。
List suits = ...; List ranks = ...; List sortedDeck = new ArrayList(); // BROKEN - throws NoSuchElementException! for (Iterator i = suits.iterator(); i.hasNext(); ) for (Iterator j = ranks.iterator(); j.hasNext(); ) sortedDeck.add(new Card(i.next(), j.next()));
どこにバグがあるのかわかりますか。経験豊富なプログラマの多くがこの間違いを経験しているので、わからなくても心配する必要はありません。問題は、next
メソッドが「外側の」コレクション suits
で何度も呼び出されていることです。外側と内側両方のコレクションのために、内側のループで next
メソッドが呼び出されていますが、これが誤りです。修正するには、外側のループのスコープに変数を追加して、suit を保持させます。
// Fixed, though a bit ugly for (Iterator i = suits.iterator(); i.hasNext(); ) { Suit suit = (Suit) i.next(); for (Iterator j = ranks.iterator(); j.hasNext(); ) sortedDeck.add(new Card(suit, j.next())); }
それでは、上記の例は for-each 構造と何の関係があるのでしょうか。入れ子になった反復があらかじめ用意されているのです。次の例を見てください。
for (Suit suit : suits) for (Rank rank : ranks) sortedDeck.add(new Card(suit, rank));
for-each 構造は、配列にも使用できます。 この場合、反復子ではなくインデックス変数を隠すことができます。次のメソッドは、int
配列内の値の和を返します。
// Returns the sum of the elements of a int sum(int[] a) { int result = 0; for (int i : a) result += i; return result; }
for-each ループは、いつでも使用できます。使用すればコードが分かりやすくなりますが、どこにでも使用できるわけではありません。たとえば、expurgate
メソッドについて考えてみましょう。現在の要素を削除するには、反復子にアクセスする必要があります。for-each ループでは反復子が隠されるため、remove
メソッドを呼び出すことができません。そのため、for-each ループをフィルタリングに使用することはできません。同様に、リストや配列内の要素をたどりながら置き換えるときには for ループを使用できません。また、複数のコレクションにまたがって並列に反復しなければならない for ループも使用できません。ほとんどの場合に使用できる、整理された単純な構造を意図的に採用した設計者にとって、これらの短所は既知の事項です。
Copyright © 2004 Sun Microsystems, Inc. All Rights Reserved. |
![]() Java Software |