For-Each 루프 - xrath.com 에서 번역됨

# 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