콘텐츠로 이동

순회

순회 (Iteration)

  • 자료구조마다 데이터를 접근하는 방법이 달라 내부 구조를 알아야 했다.
  • 모든 자료구조를 일관성 있는 방법으로 접근하기 위해 Iterable, Iterator 인터페이스를 제공한다.

왜 사용하는가?

  • 자료구조의 내부 구현과 무관하게 동일한 방식으로 요소를 순회하기 위해
  • 배열, 리스트, 셋 등 다양한 컬렉션을 동일한 코드로 처리 가능 → 유지보수 용이
  • for-each 문법 지원을 위한 기반

특이점

  • Iterable을 구현하면 for-each 사용 가능
  • Iteratorremove() 메서드로 순회 중 안전한 삭제 가능
  • MapIterable을 구현하지 않으므로 entrySet(), keySet() 등을 통해 순회

Iterable

  • [반복 가능한]이라는 뜻
  • "나는 반복될 수 있다"는 능력 선언
  • Collection의 최상위 인터페이스
public interface Iterable<T> {
    Iterator<T> iterator(); // Iterator 반복자를 반환
}

Iterator

  • [반복자]라는 뜻
  • 실제로 요소를 하나씩 꺼내는 도구
public interface Iterator<E> {
    boolean hasNext(); // 다음 요소가 있는지 확인
    E next();          // 다음 요소 반환 (내부 커서 이동)
    default void remove(); // 현재 요소 안전 삭제
}
메서드 설명
hasNext() 다음 요소가 있으면 true, 없으면 false
next() 다음 요소 반환 및 커서 이동
remove() 마지막으로 반환된 요소 삭제 (선택적 구현)

Iterable vs Iterator 관계

Iterable (컬렉션이 구현)
    └─ iterator() → Iterator 반환

Iterator (실제 순회 담당)
    ├─ hasNext()
    └─ next()

어떻게 사용하는가?

향상된 반복문 (for-each) - 가장 많이 사용

List<String> list = List.of("A", "B", "C");
for (String s : list) {
    System.out.println(s);
}

// 배열도 사용 가능
int[] arr = {1, 2, 3};
for (int n : arr) {
    System.out.println(n);
}

Iterator 직접 사용 (순회 중 삭제 시)

List<String> list = new ArrayList<>(List.of("A", "B", "C"));
Iterator<String> it = list.iterator();
while (it.hasNext()) {
    String s = it.next();
    if (s.equals("B")) {
        it.remove(); // 안전한 삭제 (ConcurrentModificationException 방지)
    }
}

for-each 내부 구조 (컬렉션의 경우)

// for-each는 컴파일 시 아래로 변환됨
for (Iterator<String> it = list.iterator(); it.hasNext(); ) {
    String s = it.next();
}

Map 순회

Map<String, Integer> map = new HashMap<>();
map.put("A", 1);
map.put("B", 2);

// keySet 순회
for (String key : map.keySet()) {
    System.out.println(key + " = " + map.get(key));
}

// entrySet 순회 (성능상 권장)
for (Map.Entry<String, Integer> entry : map.entrySet()) {
    System.out.println(entry.getKey() + " = " + entry.getValue());
}

어떨 때 많이 쓰는가?

상황 방법
단순 순회 for-each
순회 중 요소 삭제 Iterator.remove()
인덱스가 필요한 경우 일반 for문 또는 IntStream
Map 전체 순회 entrySet() + for-each
커스텀 자료구조에 for-each 지원 Iterable 직접 구현