Java 자료구조, 컬렉션 프레임웍 - 3, (Iterator, ListIterator, Enumeration)
Iterator, ListIterator, Enumeration
모두 컬렉션에 저장된 요소를 접근하는데 사용되는 인터페이스
Enumeration은 Iterator의 구버전
ListIterator는 Iterator를 상속받아 기능을 향상시킨 것,
이전 방향 조회기능 추가(List를 구현한 경우만 사용 가능), Iterator는 한 방향으로만 조회가 가능함
Collection 인터페이스와 List, Set, Queue 인터페이스의 계층구조는 알고 있었지만, Iterable이 Collection의 상위 인터페이스 인지는 잘 몰랐다.
그래서 인텔리제이에서 내부 구현 코드를 확인해봤다.
public interface Collection<E> extends Iterable<E> {
// Query Operations
}
이렇게 Collection 인터페이스의 상위 인터페이스는 Iterable 이라는 것을 알 수 있다. 그러면 Iterable의 내부를 한번 봐보자.
public interface Iterable<T> {
Iterator<T> iterator();
}
Iterable 인터페이스 안에는 iterator 메소드가 추상메소드로 선언이 되어있다.
이렇게 때문에 Collection 인터페이스 계층구조에서 List, Set, Queue를 구현하는 클래스들은 다 iterator 메소드를 가지고 있다.
따라서 Iterable의 역할은 iterator()메소드를 하위 클래스에서 무조건 구현을 하게 만들기 위함이다.
public interface Iterator<E> {
boolean hasNext();
E next();
default void remove() {
throw new UnsupportedOperationException("remove");
}
}
Iterator 인터페이스의 내부 구현은 위와 같이 되어있다.
따라서 위의 hasNext(), next(), remove() 등의 메소드를 이용할 수 있다.
용도는 컬렉션클래스의 데이터를 하나씩 읽어올 때 사용한다.
표준화가 되어 있지 않다면 컬렉션 클래스의 데이터를 읽어올 때마다 해당 클래스의 데이터를 꺼내오는 메소드들을 다 알고 있어야 하기 때문에 Iterator이 존재한다.
또한 공통 인터페이스를 정의해서 표준을 정의하고 구현하여 표준을 따르도록 함으로써,
코드의 일관성을 유지하여 재사용성을 극대화하는 것이 객체지향 프로그래밍의 중요한 목적 중의 하나이다.
import java.util.Iterator;
import java.util.LinkedList;
public class Test {
public static void main(String[] args) {
LinkedList<String> list = new LinkedList<>();
list.add("Lee"); list.add("ekk"); list.add("eww");
Iterator it = list.iterator();
while (it.hasNext()) {
System.out.print(it.next() + " ");
}
}
}
예시의 코드와 같은 상황이 있을 때, list.iterator() 의 역할을 생각해보자. 참조변수 list 로 iterator 메소드를 호출했다.
따라서 iterator은 LinkedList의 형태의 Iterator을 반환할 것이다.
그리고 나서 hasNext(), next()메소드를 통해서 출력을 하게 된다.
Comparator, Comparable
둘 다 인터페이스로, 컬렉션을 정렬하는데 필요한 메서드를 정의하고 있다.
Comparable을 구현하는 클래스들은 기본적으로 오름차순으로 구현되었다.
즉, Comparable을 구현한 클래스는 정렬이 가능하다는 것을 의미한다.
Comparable : 기본 정렬기준(오름차순)을 구현하는데 사용
Comparator : 다른 기준으로 정렬하고자할 때 사용