전통적인 for 문은 while 문보다는 낫지만 가장 좋은 방법은 아니다.
// 컬렉션 순회
for (Iterator<Element> i = c.iterator(); i.hasNext(); ) {
Element e = i.next();
...
}
// 배열 순회
for (int i = 0; i < a.length; i++) {
...
}
// 컬렉션 중첩 순회 - 실수하기 쉽고, 보기 좋지 않다.
for (Iterator<Suit> i = suits.iterator(); i.hasNext(); ) {
Suit suit = i.next();
for (Iterator<Rank> j = ranks.iterator(); j.hasNext(); )
deck.add(new Card(suit, j.next()));
}
// 컬렉션 혹은 배열 순회
for (Element e : elements) {
...
}
// 컬렉션이나 배열의 중첩 순회
for (Suit suit : suits)
for (Rank rank : ranks)
deck.add(new Card(suit, rank));
위에서 언급한 문제들은 for-each 문을 사용하면 모두 해결된다.
Iterable
인터페이스를 구현한 객체는 모두 순회 가능하다.컬렉션을 순회하면서 선택된 원소를 제거해야 한다면, 반복자의 remove 메서드를 호출해야 한다.
자바 8부터는 Collection의 removeIf 메서드를 사용해 컬렉션을 명시적으로 순회하는 일을 피할 수 있다.
리스트나 배열을 순회하면서 그 원소의 값 일부 혹은 전체를 교체해야 한다면, 리스트의 반복자나 배열의 인덱스를 사용해야 한다.
여러 컬렉션을 병렬로 순회해야 한다면, 각각의 반복자와 인덱스 변수를 사용해 엄격하고 명시적으로 제어해야 한다.
📌 핵심 정리
- 전통적인 for 문과 비교했을 때 for-each 문은 명료하고, 유연하고, 버그를 예방해준다.
- 성능 저하도 없다.
- 가능한 모든 곳에서 for 문이 아닌 for-each 문을 사용하자.