본문 바로가기
Java/Java Basic

[Java Basic] 34 - 컬렉션 프레임워크4 (Iterator, ListIterator, Enumeration)

by Rosmary 2022. 9. 2.
728x90
반응형

 

 

 

컬렉션 프레임워크에 속하는, 데이터 집단을 다루는 객체들은 자신들이 가지는 요소(Element)에 접근하여 값을 확인할 수 있는 인터페이스를 사용할 수 있는 iterator()라는 매서드를 가지고 있다. 이 iterator() 매서드의 반환값은 Iterator 객체인데, 데이터 요소들의 접근과 조회를 이 Iterator 객체에서 진행할 수 있도록 몇 개의 매서드가 정의되어 있다. Iterator 외에도 ListIterator와 Enumeration이라는 이름의 인터페이스도 존재하는데, Enumeration은 Iterator와 동일한 기능을 가지는, 컬렉션 프레임워크 탄생 전에 존재하던 인터페이스고, ListIterator는 Iterator에 몇몇 매서드를 추가한, List 내 요소의 접근과 조회에 특성화된 인터페이스다.

 

이번 포스팅에서는 컬렉션 프레임워크에 저장된 요소들의 접근과 조회를 위한 인터페이스인 Iterator, Enumeration, ListIterator에 대해 알아보려 한다.

 

 

 

1. iterator() 매서드 Iterator, Enumertaion 인터페이스

 

서두에 언급했듯이 모든 컬렉션 프레임워크 내 클래스들은 iterator() 매서드를 정의하고 있다. Java Documentation에서 iterator를 검색창에 입력하면 컬렉션 프레임워크의 각 클래스에 정의된 iterator() 메서드 목록을 확인할 수 있다.

 

 

컬렉션 프레임워크의 모든 클래스에 정의된 iterator() 매서드는 Iterator라는 객체 타입을 반환한다.

 

 

 

 

"그럼 Iterator 객체는 무엇인가?"라는 당연한 물음이 생긴다. Documentation을 보면 다음과 같이 정의되어 있다.

 

 

 

Iterator는 Enumeration을 대체한 인터페이스라는 말이 나온다. 그럼 Enumeration의 정의를 살펴보자.

 

 

 

 

내용을 보면 연속적인 요소의 개별 출력을 지원하는 것이 Enumeration 인터페이스다. 컬렉션 프레임워크 등장 전에 존재하던 Vector 객체의 개별 요소를 연속으로 출력하기 위해 만들어졌으나, 컬렉션 프레임워크 등장으로 Enumeration 인터페이스의 자리는 Iterator 인터페이스가 계승한 것이다. 그렇다고 Enumeration이 아예 사용되지 않는 것은 아닌데, StringTokenizer 클래스가 Enumeration 인터페이스를 구현하고 있음을 문서에서 확인할 수 있다.

 

Enumeration과 Iterator에서 각 요소를 연속으로 출력하는 방식은 매우 단순하다. 먼저 컬렉션프레임워크 객체를 iterator() 매서드를 사용하여 Iterator와 Enumeration 객체로 전환한다.

 

 

 

Enumeration과 Iterator는 데이터 집단에 접근할 수 있는 매서드를 가진다. Iterator에서는 next(), Enumeration에서는 nextElement()라는 이름의 매서드로 정의되어 있다.

 

 

 

 

Iterator 인스턴스를 생성한 직후, 인스턴스를 통해 next(), nextElement() 매서드를 호출하면 객체에 저장된 값의 가장 첫 요소가 반환된다. 이를 print() 함수로 출력하면 반환받은 요소값이 화면에 출력된다.

 

 

 

 

첫 인자를 호출한 상태에서 next(), nextElement() 매서드를 다시 호출하면 다음에 저장된 요소값이 반환된다.

 

 

 

모든 요소를 출력한 뒤에 next(), nextElement()를 호출하면 어떻게 될까? 존재하는 값이 없기 때문에 단순히 출력물이 없을 것이라는 생각과 달리 NoSuchElementException이라는 예외가 발생한다. next(), nextElement()는 다음 요소가 존재하는 경우에 한해 그 값을 반환받게 되어 있기 때문에, 데이터에 접근할 수 없는 상태에서 이 매서드들을 호출하면 반환받는 값이 없기 때문에 이런 에러가 발생하는 것이다.

 

 

 

따라서 Iterator와 Enumeration 인터페이스는 다음 요소의 존재유무를 확인할 수 있는 hasNext(), hasNextElement() 매서드를 정의하고 있다. 이 메서드를 적용하여 컬렉션 프레임워크에 저장된 값을 연달아 출력하는 코드는 아래와 같이 작성할 수 있다.

 

 

 

ArrayList 등의 컬렉션 프레임워크에서 모든 요소를 출력할 수 있는 기능을 제공하는 매서드는 존재하지 않는다. 따라서 for 문과 get() 매서드를 사용하여 요소를 하나씩 출력해야 하는데, Iterator 객체로 변환하면 각 요소를 연속적으로 출력하기가 수월해진다.

 

 

 

2. listiterator() 매서드와 ListIterator 인터페이스

 

컬렉션 프레임워크의 List 인터페이스를 구현하는 클래스들(대부분이 이름 어미가 List로 끝난다)은 listIterator() 매서드를 가지고 있다. iterator() 매서드와 유사한 기능을 하는데, 컬렉션 프레임워크 객체를 ListIterator 객체로 변환한다는 점만 다르다.

 

 

 

ListIterator 역시 Iterator와 동일한 방식으로 객체를 생성하고, List 객체의 요소를 출력한다.

 

 

 

ListIterator는 List 객체를 다루기 위한 추가 기능이 있는데, 바로 다음 요소를 확인하는 next(), hasNext() 매서드 말고도, 직전의 요소를 확인할 수 있는 previous(), hasPrevious() 매서드를 정의하고 있다.

 

 

 

 

previous(), hasPrevious() 매서드의 존재로 인해 ListIterator는 Iterator 보다 사용이 훨씬 용이한 편인데, Iterator의 경우 마지막 요소 출력 후 다시 모든 요소를 출력하려면 Iterator 객체를 재선언해야한다는 단점이 있다. 하지만 ListIterator는 이전 단계의 요소로 이동이 가능하기 때문에 하나의 ListIterator를 사용하여 여러 번 요소 값을 반환받을 수 있다.

 

 

 

 


 

다음 포스팅에서는 배열 작업과 연관된 Arrays 클래스와, Array의 비교 및 정렬에 사용되는 Comparable, Comparator 인터페이스에 대해 알아보려한다.

 

 

Fin.

 

 

반응형

댓글