본문 바로가기
개발/JAVA

HashMap으로 보는 Iterator의 유용성

by pastry 2014. 11. 26.

Iterator는 Iterable를 구현한 하위 클래스들을 객체 단위로 접근하게 해주는 클래스이다.

 

Collection에는 List와 Set이 있고 각 하위에는 다시

 

(List 하위) Stack, ArrayList, LinkedList, Vector가 있고

(Set 하위) SortedSet-TreeSet, Hashset이 있다.

Collection의 특징으로는 각 인덱스가 있고(배열처럼) 그 인덱스 값으로 데이타의 접근이 가능한데, 각 Collection에 있는 자료에 접근하기위해 흔히 Iterator를 사용한다.

 

 

※예제로 사용할 HashMap은 Map계열로 Map계열의 특성상 (Key와 Value로 나뉘기 때문에) 그대로 Iterator를 사용 할 수 없고 Key값을 뽑아와서 써야한다.

 

Iterator에 대해서 검색해보면 "Collection Class의 종류에 상관없이 동일한 방법으로 (동일한 형태의 데이타 접근 방식으로) 사용할 수 있기에 사용이 용이하다." 라고 나와있다.  이는 Iterator 패턴이 주는 특징이라 하겠다. (hasNext(),next()만으로 Collection에 있는 객체에 접근이 가능하기 때문에 어떤 집합체든 안에 어떤 인스턴스를 가지고 있든 간단하게 접근이 가능하다.) 각설하고 아래의 코드를 보자.

 

 

main안에 있는 출력문은 HashMap에 있는 값을 제대로 출력하지 못한다. 그 이유는 HashMap에 Key와 value를 넣을때 key값을 임시 객체Name으로 생성해서 넣었는데 임시객체의 HashCode와 출력문에서 쓰인 get안에 있는 임시객체의 HashCode는 다르기 때문이다.  Map계열의 get메소드는 각 key값의 HashCode를 비교하기 때문에 hashCode()메소드와 equals()를 override해서 값이 같은 객체는 같도록 인식하게 해줘야 한다. 여기까지는 책에서 찾아 볼 수 있었다.

 

아래 처럼 Name class에 hashcode()와 equals를 overriding해서 쓴다.

 

 

그럼 HashMap의 Key값들을 Iterator로 뽑아서 출력하면 어떨까?

 

 

된다. 당연히 될 수 밖에 없다.

Iterator로 각 key값을 접근하면 처음에 key로 넣었던 객체에 접근 할수가 있다. generic으로 type cast하기 위해서 key의 class를 명시하긴(Iterator<Name>이런 식으로) 하지만 그래도 훨씬 편하다. 위에 예제에 override한 equals()는 instanceof로 비교대상을 확인하기때문에 만약 Name을 상속받은 NameChild라는 객체가 동일한 변수를 갖고 있으면 true를 반환해서 value에 접근하게 해 줄수도 있다.

(경우에 따라 의도치 않은 작동을 할 여지가 있다.)

(물론 instanceof말고 getClass()로 클래스 자체를 비교하면 이부분은 해결될 수 있다.)  

 

 

 

 

댓글