JAVA/고급 자바

Iterator 그리고 Iterable에 대해 정리

위들 wedul 2018. 10. 4. 00:19
반응형

Java8의 Stream에 map 기능을 사용하다가 이런문제를 겪었다.



Iterable과 Iterator 정확한 정리를 하지 않고 무턱대고 사용하다보니 발생한 문제였다.

정확하게 집고 넘어가기 위해 정리해보자.

Iterator

Iterator는 자바 1.2에 발표된 인터페이스이다.  hasNext, next 등을 통해 현재 위치를 알 수 있고 다음 element가 있는지를 판단하는 기능등에 대한 명세를 제공한다. 이를 사용하기 위해서는 Iterator 인터페이스의 내용을 직접 구현해야 한다. 

대게 Collection 인터페이스를 사용하는 클래스의 경우 별도의 Iterator를 구현하여 사용하고 있다. 밑에 Iterable을 설명하면서 정리해보자.

1
2
3
4
5
6
7
8
9
10
11
12
public interface Iterator<E> {
    boolean hasNext();
    E next();
    default void remove() {
        throw new UnsupportedOperationException("remove");
    }
    default void forEachRemaining(Consumer<super E> action) {
        Objects.requireNonNull(action);
        while (hasNext())
            action.accept(next());
    }
}
cs


Iterable

Java 1.5부터 나온 인터페이스로 Iterator보다 더 늦게 나온 인터페이스로 Iterator를 제공하는 메서드를 보유하고 있는 인터페이스이다.

이 인터페이스는 실질적으로 for-each를 사용할 수 있는 클래스라는것을 명세해주는 기능을 제공하고, Iterable을 상속받은 클래스는 Iterator를 사용하여 for- each 기능을 사용할 수 있다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public interface Iterable<T> {
   Iterator<T> iterator();
    
   default void forEach(Consumer<super T> action) {
        Objects.requireNonNull(action);
        for (T t : this) {
            action.accept(t);
        }
    }
 
   default Spliterator<T> spliterator() {
       return Spliterators.spliteratorUnknownSize(iterator(), 0);
   }
}
cs

조금 더 이해가 가능하도록 ArrayList를 예로 들어보자.

ArrayList는 List를 구현하고 있고, List는 Collection을 상속받고 있으며 Collection은 Iterable을 상속받고 있다.

1
2
3
4
5
6
7
// ArrayList
public class ArrayList<E> extends AbstractList<E>
        implements List<E>, RandomAccess, Cloneable, java.io.Serializable
// List
public interface List<E> extends Collection<E> {
// Collection
public interface Collection<E> extends Iterable<E> {
cs


그래서 ArrayList에 보면 Iterator<E> iterator()가 구현되어 있다.

그리고 Iterator()에서 반환하는 Iterator인터페이스를 구현한 Itr 클래스도 제공하고 있으며 이를 사용하여 반복 동작을 가능하도록 사용한다.

※Java 1.8 부터는 Iterable에 forEach default method를 제공하고 있어서 바로 사용할 수 있다.


결론은
for-each 기능을 제공하는 Collection의 경우 Iterable을 구현하고 있으며, 그 Iterable 인터페이스에 있는 Iterator<E> iterator() 메소드를 구현하여 Collection의 요소들은 Iterate 하는데 사용된다.


728x90
반응형