EnumMap은 Enum을 key값으로 사용하는 Map의 자료구조로 설계되었다.
EnumMap | HashMap |
---|---|
Enum Type만 Key로 사용되며, enum type key에 최적화되어 있음 | 모든 Object를 Key로 사용 |
내부 자료구조는 배열로 구성 | 내부자료구조는 HashTable로 구성 |
Enum의 선언적 순서에 따라(ordinal) 순서를 보장 | 순서를 보장하지 않음 |
(ordinal) 순서를 보장하여 배열을 유지함으로, 해시 충돌 가능성이 없음 | hascode를 사용하여 충돌 가능성이 있음 |
1public class EnumTestMap {23 public static void main(String[] args) {4 //EnumMap5 Map<Sports, String> enumMap = new EnumMap<>(Sports.class);6 enumMap.put(Sports.BASEBALL, "류현진");7 enumMap.put(Sports.BASKETBALL, "서장훈");8 enumMap.put(Sports.SOCCER, "손흥민");9 enumMap.put(Sports.SWIM, "박태환");1011 //HashMap12 Map<Sports, String> hashMap = new HashMap<>();13 hashMap.put(Sports.BASEBALL, "류현진");14 hashMap.put(Sports.BASKETBALL, "서장훈");15 hashMap.put(Sports.SOCCER, "손흥민");16 hashMap.put(Sports.SWIM, "박태환");17 18 19 enumMap.keySet().stream().collect(Collectors.toList()).forEach( i -> System.out.println(i));20 21 hashMap.keySet().stream().collect(Collectors.toList()).forEach( i -> System.out.println(i));2223 }24}25public enum Sports {2627 SOCCER,28 BASEBALL,29 BASKETBALL,30 SWIM3132}
EnumMap과 HashMap을 비교하기 위하여 위와 같이 예제를 사용하였다. 위의 내용을 결과를 확인해보면 EnumMap은 Enum클래스에 선언된 순서를 보장하여 SOCCER -> BASEBALL -> BASKETBALL -> SWIM 결과로 출력되고, HashMap은 순서가 보장되지 않아 Enum순서에 상관없이 해싱함수 결과값에 따라 순서가 랜덤으로 나오게 된다.
1// jdk 1.8 기준, EnumMap put 메서드2public class EnumMap<K extends Enum<K>, V> extends AbstractMap<K, V>3 implements java.io.Serializable, Cloneable {4 5 //생략...67 public V put(K key, V value) {8 typeCheck(key);910 int index = key.ordinal();11 Object oldValue = vals[index];12 vals[index] = maskNull(value);13 if (oldValue == null)14 size++;15 return unmaskNull(oldValue);16 }17}
ordinal() 메서드를 사용함으로써 순서를 보장하는 것을 알 수 있다.
EnumMap은 HashMap api와 거의 동일하나 key가 Enum으로만 한정되어 있기에 삽입, 조회, 삭제 과정에서 내부 구현만 다를 뿐이다.
너무나 당연하게도 Enum으로 key가 한정될 때 HashMap보다 EnumMap을 사용하는 것을 고려해볼 필요가 있다. 해싱과정이 이미 정해진 enum으로 하기에 최적화된 성능이 보장되고, 해싱충돌 염려가 없기 때문에 더 좋은 성능을 보장한다.
[Reference]