[JAVA] 컬렉션 프레임웍 : Iterator

DongGyu Jung·2022년 2월 19일
0

자바(JAVA)

목록 보기
33/60
post-thumbnail

🏃‍♂️ 들어가기 앞서..

본 게시물은 스터디 활동 중에 작성한 게시물로 자바의 정석-기초편 교재를 학습하여 정리하는 글입니다.
※ 스터디 Page : 〔투 비 마스터 : 자바〕

*해당 교재의 목차 순서와 구성을 참고하여 작성하며
각 내용마다 부족할 수 있는 내용이나 개인적으로 궁금한 점은
추가적인 검색을 통해 채워나갈 예정입니다.



이전까지 컬렉션(Collection)과
그 컬렉션 인터페이스를 상속받은 List클래스들에 대해 알아보았다.

컬렉션 인터페이스엔 List뿐만 아니라 Set도 있다는 것을 알 수 있고
List는 단순히 List로 있는 것이 아닌
ArrayList , LinkedList , Stack 등등의 클래스들로 나누어져 있다.

인터페이스 기반으로 틀은 같더라도
각자의 컬렉션에 속한 클래스들마다 저장된 요소를 읽어오는 방법이 다른 경우가 많다.
(ex. pop, poll, get, offer 등등 같은 기능이더라도 정의된 메서드가 달라서 호환이 안되는 경우)

이런 경우를 대비하여 고안된 방법이 바로 Iterator 이다.

Iterator 인터페이스

컬렉션에 저장된 요소에 접근하는 사용되는 3가지 인터페이스로는
Iterator / ListIterator / Enumeration 이 있다.
( EnumerationIterator개선ListIterator )

  • Iterator : 컬렉션에 저장된 요소 접근하는데 사용되는 인터페이스

  • ListIterator : Iterator + " 양방향 조회기능 " ( 단, List 구현한 경우만 사용 가능 )

  • Enumeration : Iterator 구 버젼

이렇게 요소 접근을 위해 인터페이스까지 만들어서 만든 이유는
앞서 말했다시피 기능 구현 중 사용하던 객체를 다른 Collection로 사용하게 될 경우,
서로 호환이 안되는 경우를 방지하기 위해

요소를 읽어오는 방법을 " 표준화 "시킨 것이다.

그렇게

public interface Iterator {
	boolean hasNext() ;
    Object next() ;
    void remove() ;
}

Iterator 인터페이스를 정의하고

Collection 인터페이스 내
이 <Iterator 구현한 클래스>의 인스턴스를 반환하는 iterator()를 정의되어 있다.

public interface Collection {
	...
    public Iterator iterator();
    ...
}

iterator()가 Collection 인터페이스에 정의된 메서드라는 것은
Collection의 자손인 ListSet에도 포함되어 있는 것이다.

같은 기능과 같은 이름을 가진 iterator()가 각자의 특징에 알맞게 작성되어 있다.

이렇게 각 클래스에게 맞춤형임과 동시에 " 이름과 기능이 같기 때문에 "
기존에 다른 클래스 타입 객체로 수정하더라도
데이터를 읽는 코드는 수정하지 않아도 되는 것이다.

static Queue q = new LinkedList();
static final int MAX_SIZE = 5 ;
...
// Linked List에 요소 저장
...

LinkedList tmp = (LinkedList) q ; 
// 자료형이 바뀔 경우 q 참조변수와 tmp 참조변수의 클래스 타입아 달라지는 것..!!
// ex. Set q = new HashSet() ; & HashSet tmp = (HashSet)q ; 과 같이 변경할 경우

/* 
만약 사용하는 LinkedList 타입 참조변수 q가 
HashSet 등과 같은 자료구조로 바뀌게 되면
오류가 발생할 코드임.
모두 수정이 필요하다.
*/
final int SIZE = tmp.size() // for문 시간 단축용
for (int i = 0 ; i < SIZE ; i++) {
	System.println( (i+1) + ":" + tmp.get(i) ) ;
}

/*
Iterator를 사용하면
q가 HashSet 등으로 타입이 바뀌게 되어도
값을 읽어들이는 반복문 수정할 필요가 없다.
*/
Iterator it = tmp.iterator();

while (it.hasNext()) {
	Object obj = it.next() ;
    System.out.println(obj) ;
}

위 예시는 HashSet의 경우로 예를 들어봤는데
사실 처음부터 Collection타입으로 참조변수 정의하게되면
Collection의 어떤 구조던 상관없이

코드의 일관성유지되고
재사용성극대화

말그대로 " 표준화된 코드 " 구현이 가능해진다.

Iterator 인스턴스를 사용할 때 주의할 점이 한가지 있다.
Iterator 인스턴스는 " 일회용 " 이기때문에

만약 요소를 읽어오는 작업을 반복문을 통해 모두 읽게되면
사라지기 때문에

다시 사용하고 싶으면
새로운 Iterator 인스턴스를 생성해야 한다.


❓ "Map" 도 Iterator 쓸 수 있을까..?

Map은 Key와 Value를 쌍으로 저장하고 있기 때문에
iterator()직접 호출할 순 없다.

대신 " Key 따로 " & " Value 따로 " 의 방법이 있다.

각각 따로 Set의 형태로 얻어온 후,
다시 iterator()를 호출하는 방법이다.

JAVA에서 Map의 Key-Value 쌍,
즉 " entry " 를 Set의 구조로 변환해서 얻어오는 메서드는
entrySet() 메서드이다.

이 메서드를 사용해서 Map에 Iterator를 사용한다면

Map map = newHashMap();
...
Set eSet = map.entrySet() ;
Iterator it = eSet.iterator() ;
// Iterator it = map.entrySet().iterator() ;

위와 같이 된다.

0개의 댓글