들어가며
전통적인 for문보다 for-each문이 간결할 때가 많다. for-each문은 Iterable 인터페이스를 구현한 객체라면 무엇이든 순회할 수 있다. 다음 코드를 보자. 다음 코드는 주사위 원소를 순회하며 주사위를 두번 던졌을 때 조합할 수 있는 숫자를 출력한다. 이 코드에는 버그가 있다.
1 | enum Face { ONE, TWO, THREE, FOUR, FIVE, SIZ } |
i.next()
를 계속 호출하니 원하는 대로 동작하지 않는다. 위 코드를 전통적인 for문으로 바꾸려면 다음과 같다.
1 | for(Iterator<Face> i = faces.iterator(); i.hasNext(); ) { |
이를 for-each로 고치면 다음과 같다.
1 | for(Face face1 : faces) |
하지만 for-each문을 사용할 수 없는 상황도 존재한다.
- 파괴적인 필터링(destructive filtering)
- 컬렉션을 순회하면서 선택된 원소를 제거해야 한다면 반복자의 remove 메소드를 호출해야 한다. 자바 8부터는 Collection의 removeIF 메소드를 통해 컬렉션을 명시적으로 순회하는 일을 피할 수 있다.
- 변형(transforming)
- 리스트나 배열을 순회하면서 그 원소의 값 일부 혹은 전체를 교체해야 한다면 리스트의 반복자나 배열의 인덱스를 사용해야 한다.
- 병렬 반복(parallel iteration)
- 여러 컬렉션을 병렬로 순회해야 한다면 각각의 반복자와 인덱스 변수를 사용해 엄격하고 명시적으로 제어해야 한다.