🏃♂️ 들어가기 앞서..
본 게시물은 스터디 활동 중에 작성한 게시물로 자바의 정석-기초편 교재를 학습하여 정리하는 글입니다.
※ 스터디 Page : 〔투 비 마스터 : 자바〕
*해당 교재의 목차 순서와 구성을 참고하여 작성하며
각 내용마다 부족할 수 있는 내용이나 개인적으로 궁금한 점은
추가적인 검색을 통해 채워나갈 예정입니다.
이전까지 컬렉션(Collection)과
그 컬렉션 인터페이스를 상속받은 List클래스들에 대해 알아보았다.
컬렉션 인터페이스엔 List뿐만 아니라 Set도 있다는 것을 알 수 있고
List는 단순히 List로 있는 것이 아닌
ArrayList
, LinkedList
, Stack
등등의 클래스들로 나누어져 있다.
인터페이스 기반으로 틀은 같더라도
각자의 컬렉션에 속한 클래스들마다 저장된 요소를 읽어오는 방법이 다른 경우가 많다.
(ex. pop
, poll
, get
, offer
등등 같은 기능이더라도 정의된 메서드가 달라서 호환이 안되는 경우)
이런 경우를 대비하여 고안된 방법이 바로 Iterator
이다.
Iterator
인터페이스컬렉션에 저장된 요소에 접근하는 사용되는 3가지 인터페이스로는
Iterator
/ ListIterator
/ Enumeration
이 있다.
( Enumeration
▶ Iterator
▶ 개선 ▶ 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의 자손인 List와 Set에도 포함되어 있는 것이다.
같은 기능과 같은 이름을 가진 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() ;
위와 같이 된다.