EnumMap이란?
EnumMap
은 해시맵처럼 key
와 value
를 저장하고 (key, value)
한 쌍의 entry
를 저장할 수 있는 자료구조입니다. 해시맵과의 차이점은 이름에서 알 수 있듯이 모든 key
의 type이 enum
type이어야 한다는 것입니다.
HashMap과의 차이점
HashMap
은 해시테이블을 사용하여 key
를 저장하고, key
에 매핑되는 value
값을 가리키는 방식으로 저장됩니다. 이때 key
를 저장하는 위치는 hash 함수에 key값을 대입해서 나오는 주소가 됩니다.
반면 EnumMap
은 entry
를 저장하는 내부 구조가 '배열'로 되어 있습니다. 배열의 가장 큰 장점은 index
를 이용한 빠른 접근이 가능하단 점이죠! 즉, 해시 함수를 통해 key
가 저장된 위치를 계산한 뒤 접근하는 것보다 해당 인덱스의 위치로 바로 접근하여 원하는 데이터를 가져올 수 있는 것입니다.
그러면 EnumMap은 해시함수 없이 어떻게 key가 저장된 위치에 인덱스로 접근이 가능한걸까요?
EnumMap에서 key를 이용해 value를 가져오는 메소드인 get()
메소드를 살펴보면, key에 해당하는 Enum의 ordinal을 key를 저장하는 인덱스로 활용하게 됩니다.
EnumMap이 HashMap보다 좋은 성능을 갖는 이유
또 하나, hash함수를 통해 key가 저장될 위치를 계산하는 방식은 일반적으로 시간 복잡도를 갖습니다. 하지만 hash함수에 다른 key값을 대입해 같은 주소가 나오는 경우 즉, 해시 충돌이 발생하는 경우에는 만큼의 시간 복잡도를 갖는다고 합니다.
반면 Enum의 고유한 ordinal을 인덱스로 사용하여 key를 저장하는 EnumMap은 hash함수를 사용하여 key의 위치를 결정하는 것이 아니기 때문에 해시 충돌이 발생할 일이 없고, 그렇기 때문에 원하는 데이터를 찾을 때 최악의 경우에도 의 시간 복잡도를 갖는 것입니다.
EnumMap 사용법 예시
예제에서 사용할 enum 클래스는 다음과 같습니다.
// enum 클래스 생성
enum RankNumber {
FIRST(6),
SECOND(6),
THIRD(5),
FOURTH(4),
FIFTH(3);
private int number;
RankNumber(int number) {
this.number = number;
}
}
1. EnumMap에 데이터 추가하기
EnumMap을 초기화할 때는 HashMap과 달리 생성자에 key에 사용될 enum 타입을 넘겨주어야 합니다.
/* EnumMap 초기화
* Key : 등수
* Value : 해당 등수의 로또 개수
*/
EnumMap<RankNumber, Integer> myEnumMap = new EnumMap<>(RankNumber.class);
2. EnumMap에 저장된 데이터 추가하기
// FIRST를 key로, 0을 value로 갖는 entry 추가
// 1등 로또가 1개 있다는 의미입니다.
myEnumMap.put(RankNumber.FIRST, 1);
3. key를 이용하여 EnumMap에 저장된 데이터 가져오기
// firstRankNumber 변수에 1 대입
int numberOfFirstRank = myEnumMap.get(RankNumber.FIRST);
4. EnumMap에 저장된 데이터 삭제하기
// FIRST를 key로 갖는 entry 삭제
myEnumMap.remove(RankNumber.FIRST)