본문 바로가기

Program/Java Core

[Java] java.util.Iterator 인터페이스

디자인 패턴 중 Iterator 패턴을 생각하다가 문득 java.util.Iterator 인터페이스가 생각나서 api를 찾아보았다.

Java로 프로그래밍을 해본 사람이면 java.util.Iterator 인터페이스를 써봤을 것이다. Iterator 인터페이스는 열거되어있는 것들을 하나하나 선택해서 가져올 때 사용하는 컬렉션 중 하나이다.

Iterator 클래스에는 다음과 같이 3개의 method가 정의되어있다.

hasNext()
next()
remove() 


hasNext() : iterator객체가 다음 elements가 있는지를 확인한다. elements가 있으면 true, 없으면 false를 반환한다.
next() : 현재 iterator객체가 위치한 지점의 elements를 반환하고 다음 위치의 elements를 가리킨다.
remove() : 현재 iterator객체가 위치한 지점의 이전 elements를 삭제한다.

그리고 Iterator 인터페이스는 보통 다음과 같은 형식으로 쓰인다.

Iterator it = vector.iterator();


while (it.hasNext()) {

TestIterator tit = (TestIterator) it.next();

if (조건) {

it.remove();


tit.print();

}


간단한 예제소스를 한번 만들어 보았다.

위 소스의 결과는 다음과 같다.


그런데 Main의 while 문을 다음과 같이 바꾸면 어떻게 될까??
 

결과는 다음과 같다.

보면 알겠지만 next() 메소드 위치에 따라 결과가 다르다.


그럼 Iterator 인터페이스의 메소드들이 어떻게 돌아가는지 알아보자.


여기에 중요한 변수 두개가 있다. 하나는 cursor이고 다른 하나는 lastRet이다. cursor는 현재 가리키는 위치를 의미하고 초기화가 0으로 되어있다. lastRet은 현재 가리키는 위치의 직전의 위치로서 -1로 초기화 되어있다.

hasNext() 메소드를 보면 다음 elements가 있는지, 없는지를 전체 사이즈와 현재 cursor를 비교해서 확인한다.
next() 메소드는 현재 cursor위치에 있는 elements를 반환한 뒤, lastRet에 현재 위치를, cursor에는 다음 위치를 저장한다.
remove() 메소드는 lastRet위치에 있는 elements를 삭제하고 값을 -1로 초기화한다. ( 초기화를 통해 실수로 같은 위치의 elements를 중복해서 삭제하는 것을 예방해 준다.)

여기서 눈여겨 볼 만한 것은 next() 메소드는 현재 위치의 elements를 반환하고 다음 위치를 가리킨다는 것과 remove() 메소드는 lastRet에 위치한 elements를 지운다는 것이다. 그래서 보통 Iterator 인터페이스는 next() 메소드를 먼저 호출해서 elements를 가져오고, 삭제를 할 경우에는 그 elements를 이용해 조건을 넣어서 elements를 삭제하는 방법으로 사용한다.

만약에 Iterator 인터페이스를 사용하는데 원하지 않는 결과가 나온다면, Iterator 인터페이스의 메소드 구조를 생각해보자! 

그렇다면 Iterator 인터페이스는 왜 쓰는 것일까? for문같은 반복문으로도 충분히 사용이 가능한데도 말이다. 이 문제에 대한 해답은 바로 java언어가 객체지향을 추구한다는 것과 관계가 있다.
Iterator 인터페이스는 구현과 분리해서 하나씩 셀 수가 있다. for문을 사용하게되면 반복문 코드 부분이 객체의 구현에 따라 수정이 필요로 할 수가 있는데, 이것을 Iterator 인터페이스를 사용하면 반복문 부분이 객체의 구현으로부터 의존할 필요가 없기 때문에 코드의 수정 없이 사용할 수 있다. 잘 이해가 안된다면 디자인 패턴 중 Iterator 패턴을 공부해보자.