반응형

Iterator, ListIterator, Enumeration

 

  • 컬렉션에 저장된 데이터를 접근하는데 사용되는 인터페이스
  • Enumeration은 Iterator의 구버젼
  • ListIterator는 Iterator의 접근성을 향상시킨 것 (단방향 → 양방향)

 

Iterator, ListIterator, Enumeration은 전부 인터페이스다.
어떤 인터페이스냐면, 컬렉션에 저장된 데이터를 읽어올 때사용하는 인터페이스다.

그래서 이러한 메서드가 있는데,핵심은 hasNext(), next() 이게 핵심이다.

hasNext()는 읽어올 요소가 남아있는지 확인하고, 있으면 true, 없으면 false를 반환한다.
보통 next()를 호출하기 전에 hasNext()를 호출해서 읽어올 요소가 있는지 확인할때 사용한다.

next()는 다음 요소를 읽어온다. next()를 호출하기 전에 hasNext()를 호출해서 읽어올 요소가 있는지 확인하는 것이 안전하다.

Enumeration은 Iterator의 old버전이다.
위 그림에서 두번쨰 표는 Enumeration인터페이스의 메서드다.
hasMoreElements()는 hasNext()와 기능이 같고,
nextElement()는 next()와 기능이 같다.

우리는 Iterator를 사용하면 되고,
기존에 작성되어있던 Enumeration이 나오면, 이름만 다를뿐, Iterator와 같은 것이라는 것만 알면, 어려움이 없을 것이다.

 

그리고, ListIterator는 Iterator의 접근성을 향상시킨 것이다(단방향 -> 양방향)

Iterator는 next()만 있는데, ListIterator는 previous()도 있다.
즉, ListIterator는 다음요소와 이전요소를 모두 읽어올 수 있다.

 


 

Iterator가 필요한 이유

  • 컬렉션에 저장된 요소들을 읽어오는 방법을 표준화한 것

 

컬렉션의 종류가, List, Set, Map이 있는데, 이 컬렉션마다 구조가 다르다.
그래서 요소들을 읽어오는 방법이 다 다르다.

그것을 표준화 한 것이 Iterator다.

Iterator에서는 hasNext()로 확인하고, next()로 읽으면 된다.
즉, 구조가 어떻게 되있든간에, 데이터요소가 있는지 확인하고, 읽으면 된다.

그러므로, 컬렉션을 사용하는 쪽에서 굉장히 편리하다.

컬렉션종류마다 읽어오는 방법이 다른데, 그것을 Iterator로 표준화 함으로서 편리하다.

예를 들어서, List를 사용하다가 Set으로 바꾸면,
List와 Set은 구조가 다르기 때문에 저장되있는 요소를 읽어올 때 사용하는 메서드나 방법이 다르다.

그래서 이렇게 Collection클래스를 다른 것으로 바꿧을 때,
저장된 요소를 읽어오는 코드가 바뀌어야 한다.

그런데 이것을 Iterator를 이용해서 읽어오게 되면, Collection이 바뀌어도 읽어오는 코드를 변경하지 않아도 된다.

 

  • 컬렉션에 iterator()를 호출해서 Iterator를 구현한 객체를 얻어서 사용

 

컬렉션에서 Iterator() 메서드를 호출하면 그 메서드가 Iterator를 반환한다.

List list = ArrayList()일때, Iterator it = list.iterator();를 하면
Iterator가 반환된다.

Iterator()라는 메서드는 Collection인터페이스에 정의되어 있는 것이라서 Collection인터페이스의 자손인 List와 Set이 모두 가지고 있는 메서드이다.

그래서 list에서 list.iterator(); 로 iterator를 호출하면 iterator객체를 얻을 수 있다.

그리고 it.hasNext()로 읽어올 요소가 있는지 확인하고, next()를 호출해서 요소를 읽어온다.

더이상 읽어올 것이 없다면, while문을 빠져나올 것이다.

 

[Ex11_5]

이 예제에서 주의할 점은,

만약에, iterator객체로 데이터를 읽었을때, 1번 다 읽고나면,
iterator의 포인터가 다시 처음으로 가는게 아니라 데이터가없는 끝을 가리키고 있기때문에,

iterator에 저장된 데이터를 다시 출력하고 싶다고해서
출력문만 추가로 작성한다고해도 데이터가 출력되지 않는다. hasNext()가 False이기 때문이다.

그래서  Iterator를 다 쓰고나면, Iterator를 다시 얻어와야 한다.

이렇게 iterator는 1회용이라서 다 쓰고나면 새객체를 다시 얻어와야 한다.
이점을 주의하자.

그리고 앞서 Iterator를 사용하는 이유에 대해서 알아본 것 처럼

List를 사용하다가 Set으로 바꾸면,
List와 Set은 구조가 다르기 때문에 저장되있는 요소를 읽어올 때 사용하는 메서드나 방법이 다르다.

그래서 이렇게 Collection클래스를 다른 것으로 바꿧을 때,
저장된 요소를 읽어오는 코드가 바뀌어야 한다.

그런데 이것을 Iterator를 이용해서 읽어오게 되면, Collection이 바뀌어도 읽어오는 코드를 변경하지 않아도 된다.

 


 

Map과 Iterator

  • Map에는 iterator()가 없다.

 

Map에는 iterator()가 없다.

Iterator()메서드는 Collection인터페이스에 정의되어 있다.

List와 Set은 Collection인터페이스의 자손인 반면,
Map은 Collection인터페이스의 자손이 아니다.

 

그래서 Map에는 iterator()메서드가 없다.

그러면 Map에 저장되어 있는 요소를 가져오려면 어떻게 해야할까?
keySet(), entrySet(), values() 같은 메서드를 호출해서 interator()를 가져와야 한다.
얘네들은 전부 Iterator()를 가지고 있다.

즉, Map에서는 바로 iterator()를 가져올 수는 없고, keySet(), entrySet(), values()같은 메서드들을 이용해서 Set이나 Collection을 얻은 다음에, 거기에 iterator()를 호출해야 한다.

이런식으로, HashMap()이 있을 때,
거기서 entrySet()을 호출하고, 거기에 iterator()를 호출해서 iterator를 얻은 뒤, Map에 있는 요소들을 하나씩 읽어올 수 있다.

반응형

'JAVA' 카테고리의 다른 글

Comparator와 Comparable  (0) 2022.05.01
Arrays  (0) 2022.04.30
Stack, Queue 활용  (0) 2022.04.29
Stack과 Queue  (0) 2022.04.28
LinkedList  (0) 2022.04.28