Iterator(반복자)와 Enumeration(열거)는 모두 컬렉션(Collection)의 요소를 순회하고 접근하기 위한 커서(cursor)입니다. 둘 다 자바 컬렉션 프레임워크에 속하지만, Enumeration은 JDK 1.0에서, Iterator는 JDK 1.2에서 각각 도입되었다는 점이 다릅니다.
Enumeration과 Iterator의 기본 개념
Enumeration은 컬렉션 내부 요소에 대해 읽기 전용(read-only) 접근만 허용하기 때문에, 순회 중에 컬렉션의 구조를 변경할 수 없습니다. Enumeration이 제공하는 메서드는 다음과 같습니다.
- hasMoreElements() – 아직 읽지 않은 요소가 남아 있는지 확인합니다.
- nextElement() – 다음 요소를 반환합니다.
반면 Iterator는 요소를 읽을 수 있을 뿐만 아니라, 순회 중에 해당 요소를 삭제(remove)할 수도 있습니다. Iterator가 제공하는 메서드는 다음과 같습니다.
- hasNext() – 다음 요소가 존재하는지 확인합니다.
- next() – 다음 요소를 반환합니다.
- remove() – 마지막으로 반환된 요소를 컬렉션에서 제거합니다.
Iterator vs Enumeration 주요 차이점 비교표
| 번호 | 구분 | Iterator | Enumeration |
|---|---|---|---|
| 1 | 기본 동작 | 컬렉션을 순회하는 동안 요소를 읽고 삭제할 수 있습니다. | 컬렉션을 순회하는 동안 요소를 읽기만 할 수 있습니다. |
| 2 | 사용 범위 | 컬렉션 프레임워크의 모든 클래스에서 사용할 수 있습니다. | Vector, Hashtable 등 레거시(구버전) 클래스에서만 사용할 수 있습니다. |
| 3 | Fail-Fast / Fail-Safe | 순회 중 스레드가 컬렉션을 변경하면 ConcurrentModificationException이 발생합니다(Fail-Fast). | 본질적으로 Fail-Safe 방식으로 동작하여, 컬렉션이 변경되어도 ConcurrentModificationException이 발생하지 않습니다. |
| 4 | 제약 사항 | 앞쪽(forward) 방향의 순회만 가능합니다. | 요소 삭제(remove) 작업을 수행할 수 없습니다. |
| 5 | 메서드 | hasNext() next() remove() | hasMoreElements() nextElement() |
Enumeration 사용 예제
class EnumerationExample {
public static void main(String args[]) {
List list = new ArrayList(Arrays.asList(new String[] {"Apple", "Cat", "Dog", "Rat"}));
Vector v = new Vector(list);
delete(v, "Dog");
}
private static void delete(Vector v, String name) {
Enumeration e = v.elements();
while (e.hasMoreElements()) {
String s = (String) e.nextElement();
if (s.equals(name)) {
v.remove(name); // Enumeration 자체로는 삭제 불가
}
}
// 이름 출력
System.out.println("The names are:");
e = v.elements();
while (e.hasMoreElements()) {
// 요소 출력
System.out.println(e.nextElement());
}
}
}
Iterator 사용 예제
class IteratorExample {
public static void main(String args[]) {
List list = new ArrayList(Arrays.asList(new String[] {"Apple", "Cat", "Dog", "Rat"}));
Vector v = new Vector(list);
delete(v, "Dog");
}
private static void delete(Vector v, String name) {
Iterator i = v.iterator();
while (i.hasNext()) {
String s = (String) i.next();
if (s.equals(name)) {
i.remove(); // Iterator로 안전하게 삭제
}
}
// 이름 출력
System.out.println("The names are:");
i = v.iterator();
while (i.hasNext()) {
System.out.println(i.next());
}
}
}
정리: 어떤 것을 사용해야 할까?
현대 자바 개발에서는 요소 삭제가 가능하고 Fail-Fast 방식으로 데이터 일관성을 지켜주는 Iterator를 사용하는 것이 권장됩니다. Enumeration은 하위 호환성을 위해 유지되고 있으며, Vector나 Hashtable 같은 레거시 클래스를 다룰 때 주로 접하게 됩니다. 만약 양방향 순회나 요소 수정 기능까지 필요하다면, Iterator를 확장한 ListIterator를 활용하는 것도 좋은 선택입니다.