Java Iterator와 Iterable 완벽 이해하기
Java Collection을 공부하다 보면 반드시 등장하는 인터페이스가 바로:
Iterable
Iterator
입니다.
그리고 대부분 개발자는 매일 이것을 사용하고 있습니다.
예:
for (String s : list)
사실 내부적으로는:
Iterator
가 동작하고 있습니다.
또한 실무에서는:
- Collection 순회
- fail-fast
- ConcurrentModificationException
- Stream API
- enhanced for문
까지 전부 연결됩니다.
이번 글에서는:
- Iterable이란?
- Iterator란?
- foreach 내부 동작
- fail-fast 원리
- remove() 주의점
- Stream과 차이
까지 깊게 정리해보겠습니다.
1. 왜 Iterator가 필요할까?
예를 들어:
List<String> list
는 내부적으로:
배열 기반
일 수도 있고,
Set<String> set
은:
Hash 기반
일 수도 있습니다.
즉:
컬렉션마다 내부 구조 다름
입니다.
2. 그런데 우리는 공통 순회 원함
예:
for (...) {
}
처럼 동일하게 사용하고 싶음.
그래서 등장한 것이:
Iterator 패턴
입니다.
3. Iterable이란?
Iterable 은:
“반복 가능한 객체”를 나타내는 인터페이스
Collection<E>
extends Iterable<E>
public interface Collection<E>
extends Iterable<E> {
}
public interface Iterable<T> {
Iterator<T> iterator();
}
Collection 계열은 모두 Iterable을 상속한다.
그리고 Iterable은 Iterator를 제공. (Has-A 관계. 사용관계. 역할관계)
그래서 List, Set, Queue는 모두 foreach 사용이 가능하다.
Iterable
↑
Collection
↑
┌──────────┬──────────┬──────────┐
List Set Queue
↑ ↑
ArrayList HashSet
-------------------
Map
↑
HashMap
TreeMap
4. Iterable 구조
public interface Iterable<T> {
Iterator<T> iterator(); // Iterator 타입 객체를 반환하는 메서드
}
Iterable
↓ iterator()
Iterator
↓ next()
데이터
Iterable은 Iterator를 제공하는 인터페이스이고,
Iterator는 실제 순회를 수행하는 인터페이스이다. 순회 도구
public interface Iterator<E> {
boolean hasNext();
E next();
}
핵심:
iterator()
메서드 제공.
주의
Map은 Collection 계열이 아니다.
Collection
├ List
├ Set
└ Queue
Map
└ HashMap
5. 의미
즉:
“나 Iterator (순회인터페이스)줄 수 있어”
라는 의미.
6. Collection은 대부분 Iterable 구현
대표:
- List
- Set
- Queue
등.
즉:
for (String s : list)
가능.
Iterable <- Collection <- List, Set, Queue
Iterable 구현한거라서.
ArrayList내부는 아래같은 느낌
public class ArrayList<E>
implements List<E> {
public Iterator<E> iterator() {
return new Itr();
}
private class Itr
implements Iterator<E> {
public boolean hasNext() {
...
}
public E next() {
...
}
}
}
7. Iterator란?
Iterator 는:
Iterator는 순회를 위한 인터페이스이다.
실제로 list.iterator()를 호출하면
Iterator 구현체 인스턴스가 생성되어 반환된다.
Iterator<String> it =
list.iterator();
//인터페이스 타입으로 받고 있지만 실제 객체는 ArrayList$Itr 같은 JDK 내부 Iterator 구현체.
8. Iterator 구조
public interface Iterator<E> {
boolean hasNext();
E next();
void remove();
}
9. 핵심 메서드
| 메서드 | 의미 |
| hasNext() | 다음 요소 존재 여부 |
| next() | 다음 요소 반환 |
| remove() | 현재 요소 제거. next()를 호출한 직후에만 가능. 안그러면 IllegalStateException 발생 |
10. 기본 사용 예시
Iterator<String> iter =
list.iterator();
while (iter.hasNext()) {
String value = iter.next();
System.out.println(value);
}
11. 동작 흐름
iterator 생성
↓
다음 요소 존재 확인
↓
next() 호출
↓
순차 접근
12. foreach는 사실 Iterator다
매우 중요합니다.
예:
for (String s : list)
실제로 컴파일 시 내부적으로 거의:
Iterator<String> iter =
list.iterator();
while (iter.hasNext()) {
String s = iter.next();
}
변환.
더 정확히는 foreach는 list가 Iterable을 구현했기 때문.
13. enhanced for문이라 부르는 이유
for (Type t : collection)
문법을:
enhanced for loop
라고 함.
14. 왜 배열도 foreach 가능할까?
배열은 특별 문법 지원.
Collection은:
Iterable 구현
해야 가능.
15. 직접 Iterable 구현 가능
예:
class MyCollection
implements Iterable<String>
16. 구현 예시
@Override
public Iterator<String> iterator() {
return list.iterator();
}
그러면:
for (String s : myCollection)
가능.
17. Iterator 장점
| 장점 | 설명 |
| 내부 구조 숨김 | O |
| 통일된 순회 방식 | O |
| Collection 독립성 | O |
18. List와 Set 순회 차이 숨김
예:
ArrayList
LinkedList
HashSet
내부 구조 다 다름.
하지만:
Iterator 인터페이스로 통일
가능.
19. Iterator는 상태(state)를 가진다
매우 중요.
예:
iter.next();
호출 시:
현재 위치 이동
합니다.
즉:
순회 상태 유지
객체.
20. next() 주의점
iter.next();
는 실제로:
포인터 이동 + 값 반환
수행.
21. hasNext() 없이 next() 호출 시
문제:
NoSuchElementException
발생 가능.
22. remove()란?
현재 Iterator 위치 요소 제거.
next() 호출 직후에만 사용가능.
Iterator<String> it =
list.iterator();
it.remove();
↓
IllegalStateException
발생.
23. 왜 Iterator remove가 중요할까?
컬렉션 순회 중 직접 remove하면 문제 가능.
예:
for (String s : list) {
list.remove(s);
}
24. 결과
ConcurrentModificationException
발생 가능.
25. 왜 발생할까?
순회 중 Collection 구조 변경 발생.
즉 Iterator 입장에서:
예상 구조 깨짐
상황.
26. fail-fast란?
매우 중요한 개념.
Fail-fast 는:
잘못된 동시 수정 감지 시 즉시 예외 발생
전략.
27. HashMap/ArrayList 내부 구조
내부적으로:
modCount
같은 변경 카운터 유지.
28. Iterator 생성 시
현재 modCount 저장.
29. 순회 중 변경 발생 시
modCount 달라짐.
그러면:
ConcurrentModificationException
발생.
fail-fast는 버그 조기 발견을 위한 메커니즘이다.
동시 수정이 발생했다고 항상 예외가 발생하는 것을 보장하지 않는다. ( cannot be guaranteed)
(best-effort)
30. 왜 fail-fast 사용할까?
목표:
예상 못 한 데이터 변경 조기 감지
입니다.
31. 올바른 제거 방식
Iterator<String> iter =
list.iterator();
while (iter.hasNext()) {
String value = iter.next();
if (value.equals("Java")) {
iter.remove();
}
}
32. 왜 안전할까?
Iterator가:
자기 상태 함께 갱신
하기 때문.
33. fail-safe Iterator도 존재
대표:
CopyOnWriteArrayList
34. fail-safe 특징
복사본 기반 순회.
즉:
순회 중 수정 허용
가능.
35. 하지만 비용 큼
수정 시:
배열 전체 복사
발생 가능.
36. ListIterator란?
ListIterator 는:
List 전용 고급 Iterator
입니다.
37. 추가 기능
| 기능 | 설명 |
| previous() | 역방향 이동 |
| add() | 중간 삽입 |
| set() | 값 변경 |
38. Iterator와 Stream 차이
매우 중요.
Iterator
외부 반복(External Iteration)
개발자가 반복 제어.
Stream
내부 반복(Internal Iteration)
JVM이 반복 제어.
39. Iterator 특징
while(iter.hasNext())
직접 제어.
40. Stream 특징
list.stream()
JVM이 내부 최적화 가능.
41. 왜 Stream이 중요할까?
JVM이:
- 병렬 처리
- lazy evaluation
- pipeline 최적화
가능.
42. Iterator 실무 사용 사례
대표:
- Collection 순회
- remove 처리
- 커스텀 자료구조
- 라이브러리 구현
43. Iterable 실무 의미
매우 중요.
Iterable 구현
=
foreach 지원
입니다.
44. 실무에서 자주 하는 실수
1) 순회 중 Collection 직접 수정
ConcurrentModificationException 발생 가능.
2) next()만 호출
NoSuchElementException 가능.
3) Iterator와 Stream 차이 이해 부족
성능/병렬 처리 혼동 가능.
45. 핵심 흐름 요약
Iterable
↓
iterator() 제공
↓
Iterator 생성
↓
hasNext()/next() 순회
46. 가장 중요한 핵심 한 줄
Iterable은 “반복 가능함”을 의미하고,
Iterator는 “실제 순회 로직”을 담당한다
입니다.
47. 정리
Iterator와 Iterable은 단순 반복 문법이 아닙니다.
실제로는:
- Collection 순회 구조
- foreach 내부 동작
- fail-fast
- ConcurrentModificationException
- Stream 내부 반복
전체와 연결되는 Java 핵심 개념입니다.
특히 실무에서는:
- Iterator remove()
- modCount
- fail-fast
- Stream과 차이
- Iterable 구현
을 정확히 이해하는 것이 매우 중요합니다.
다음 글에서는:
Generic 기초
를 타입 안정성(Type Safety), 타입 소거(Type Erasure), 컴파일러 동작 원리까지 포함해서 깊게 정리해보겠습니다.
'language > java' 카테고리의 다른 글
| Java Wildcard (<? extends T>, <? super T>) 완벽 이해하기 (0) | 2026.05.27 |
|---|---|
| Java Generic(제네릭) 기초 완벽 이해하기 (0) | 2026.05.27 |
| Java Comparable vs Comparator 완벽 이해하기 (0) | 2026.05.27 |
| Java equals()와 hashCode() 완벽 이해하기 (0) | 2026.05.27 |
| Java Hash 충돌(Hash Collision) 처리 방식 완벽 이해하기 (0) | 2026.05.27 |
댓글