Iterating HashMap Tip

Iterating HashMap Tip

October 10, 2004

HashMap이나 Hashtable과 같은 클래스를 iterator를 사용하여 각 엔트리들을 찾을 때 Map 인터페이스가 제공하는 keySet(), entrySet(), values() 등을 사용하게 됩니다. 이들 중 어느 것이 더 효율적일까요? 간단한 테스트를 통해 알아볼 수 있습니다.

첫번째 방법은 keySet() 을 사용하여 key를 검색한 다음 Map에 대해 get()을 호출하여 value를 구하는 방법입니다.

   1 Iterator it = map.keySet().iterator();
   2 StringBuffer buffer = new StringBuffer();
   3 while (it.hasNext()) {
   4   Object key = it.next();
   5   buffer.append("key=").append(key).append(",value=").append(map.get(key));
   6 }

두번째 방법은 entrySet()을 사용하여 key와 value를 구하는 방법입니다.

   1 Iterator it = map.entrySet().iterator();
   2 StringBuffer buffer = new StringBuffer();
   3 while (it.hasNext()) {
   4   Map.Entry entry = (Map.Entry) it.next();
   5   buffer.append("key=").append(entry.getKey()).append(",value=").append(entry.getValue());
   6 }

세번째 방법은 key 정보가 필요없을 때 value만을 차례로 읽어들이는 방법입니다.

   1 Iterator it = map.values().iterator();
   2 StringBuffer buffer = new StringBuffer();
   3 for (int i = 0; it.hasNext(); i++) {
   4   buffer.append("value=").append(it.next());
   5 }

물론 키 정보만 필요할 때에는 keySet()을 사용하면 되겠지요. 위의 세 가지 방법 중 가장 효율이 좋은 것은 물론 key 값에 대한 access를 하지 않는 values()의 경우입니다. 사실 이 경우는 다른 두 가지와 직접적인 비교는 의미가 없겠지요. 아무래도 다른 용도에 사용되는 것이니까요.

많이 사용되는 것은 첫번째와 두번째인데 결론적으로 말하자면, key와 value를 모두 찾아야 하는 Map의 순차는 entrySet()을 사용하는 것이 더 효율적이라는 것입니다. keySet()의 경우에는 key를 가져온 다음 다시 Map.get(key)를 호출하여 해싱 알고리즘을 매번 거쳐야 하므로 아무래도 엔트리에 key, value 쌍이 다 들어있는 entrySet() 방식에 비해 프로세싱이 더 들 수밖에 없습니다. 내부적으로 lock을 사용하는 Hashtable 같은 경우에는 entrySet() 방식이 keySet()과 get()을 함께 쓰는 방식보다 더 확연한 차이를 보여주게 됩니다.

물론 key만 필요하거나 value만 필요할 때에는 해당하는 keySet()이나 values()를 사용하는 것이 효율적일 것입니다.