Iterator
이 인터페이스가 존재하기에 각각 다른 데이터 그룹(콜렉션)들을 같은 방식으로 순회하며 데이터들을 조작할 수 있다.
참고: Fail-Fast, Fail-Safe
Fail-Fast 방식은 동작 중 오류가 발생하면 오류를 알리고 동작을 정지한다.
Fail-Safe 방식은 동작 중 오류가 발생해도 작업을 중단하지 않고 진행한다.
Iterable 인터페이스를 구현하는 콜렉션 프레임워크의 클래스 중 java.util.concurrent 패키지의 콜렉션들은 Fail-Safe이다. (Ex: ConcurrentHashMap, CopyOnWriteArrayList) 그 외의 콜렉션은 모두 Fail-Fast 이다. 다음은 ConcurrentHashMap을 사용한 Fail-Safe 테스트 코드이다.
public class App {
public static void main(String[] args) {
executeFailSafe();
executeFailFast();
}
public static void executeFailFast() {
List<Integer> integers = new ArrayList<>(Arrays.asList(1, 2, 3, 4, 5));
Iterator<Integer> iterator = integers.iterator();
while (iterator.hasNext()) {
Integer elm = iterator.next();
//integers.add(6);
System.out.println(elm);
}
}
public static void executeFailSafe() {
Map<String, Integer> map = new ConcurrentHashMap<>();
map.put("one", 1);
map.put("two", 2);
map.put("three", 3);
map.put("four", 4);
final Iterator<Map.Entry<String, Integer>> iterator = map.entrySet().iterator();
while (iterator.hasNext()) {
final Map.Entry<String, Integer> entry = iterator.next();
map.put("five", 5);
System.out.println(entry);
}
}
}
Java
복사
Iterable
여러 콜렉션 구현체들을 Iterator 클래스를 통해 요소 조회를 표준화할 수 있다고 했는데, 해당 타입(Iterator)으로 반환받기 위해 만들어진 인터페이스다.
내부 코드를 보면 다음과 같다.
public interface Iterable<T> {
Iterator<T> iterator();
...
}
Java
복사
Iterable 인터페이스를 구현하려면 Iterator 인터페이스 타입을 반환하는 iterator() 메서드를 재정의해줘야 한다.
그리고 여기서 한가지 더 볼 필요가 있다. 콜렉션 프레임워크 인터페이스인 Colleciton을 보자.
public interface Collection<E> extends Iterable<E> { ... }
Java
복사
콜렉션 프레임워크의 최상위 클래스인 Collection 인터페이스는 Iterable을 구현한다.
즉, 콜렉션 프레임워크에서 Collection을 구현하는 인터페이스 및 클래스(ex: List, Set, Queue ...)는 모두 iterator() 메서드를 재정의해서 구현해야하며 각각 자신이 가지고있는 데이터그룹을 Iterator 인터페이스가 정의하는 방식으로 읽을 수 있도록 구현해야 한다.
그렇게 함으로써 개발자는 콜렉션의 각종 구현체들 각각의 순회방법을 익힐 필요 없이 Iterator의 API만 학습하면 된다.