반응형
Enum을 Key값으로 써야하는 Map을 만들 때 어떻게 해야할까?
흠,, 그냥 HashMap을 쓰면 되나..?
이때 java에서 Enum을 효과적으로 Map형태로 사용할 수 있는 EnumMap을 제공한다.
왜 EnumMap을 사용해야하는지 Araboja
EnumMap?
: EnumMap은 Enum(열거유형)에 대한 Map인터페이스의 특수한 구현형태이다.
Map인터페이스를 구현하고 AbstractMap을 상속받아 Enum에 특화된 Map을 제공한 것이다.
EnumMap 특징
- EnumMap은 Java Collections Framework 중 하나이며 동기화되지 않는다. (필요하다면 Collections.synchronizedMap으로 wrap하는것을 권장한다.)
- EnumMap은 정렬된 컬렉션이며 키의 순서로 유지 된다. ( Enum클래스 내에서 상수가 선언된 순서 )
- HashMap보다 훨씬 빠르다.
- EnumMap 인스턴스의 모든 key값은 동일한 Enum유형이여야 한다.
- EnumMap은 key에 null값을 허용하지 않는다. (NPE)
- EnumMaap은 내부적으로 배열로 표현되므로 더 나은 성능을 제공한다.
HashMap보다 성능이 좋은 이유
어떤 처리를 했길래 EnumMap이 HashMap보다 성능이 좋을까?
바로 해싱처리를 안하고 키의 선언순서를 인덱스를 사용한다.
(* 해싱 : key값을 hash function을 통해 index화 시키는 작업)
Enum은 하나의 인스턴스만 생성하는 싱글톤 형태이기 때문에 EnumMap 인스턴스를 생성할때 Enum의 길이만큼 배열을 생성하여 키의 선언순서를 인덱스로 바로 접근할 수 있다.
성능 테스트
import java.util.*;
class EnumMapExample {
public enum Days {
Sunday, Monday, Tuesday, Wendnesday;
}
public static void setDays(Map<Days, Integer> map) {
map.put(Days.Sunday, 1);
map.put(Days.Monday, 2);
map.put(Days.Tuesday, 3);
map.put(Days.Wendnesday, 4);
}
private static long getPerform(Map<Days, Integer> map) {
long startTime = System.nanoTime();
for (int j = 0; j < 100000000; j++) {
map.get(Days.Wendnesday);
}
long endTime = System.nanoTime();
return endTime - startTime;
}
public static void main(String[] args) {
// Creating an EnumMap of the Days enum
EnumMap<Days, Integer> enumMap = new EnumMap<>(Days.class);
setDays(enumMap);
Map<Days, Integer> hashMap = new HashMap<>();
setDays(hashMap);
System.out.println("hashMap : " + getPerform(hashMap));
System.out.println("enumMap : " + getPerform(enumMap));
}
}
결과 값
hashMap : 291439360
enumMap : 116256175
1억번 get메서드를 돌린결과 enumMap이 약 3배정도 빠른 퍼포먼스를 보여주고 있다.
결론
Map의 Key값을 enum으로 사용할 계획이라면 EnumMap의 사용을 고민해보자.
EnumMap은 키의선언순서를 인덱스로 직접 배열에 접근하기 때문에, O(1)이라는 시간 복잡도를 가져 매우 효율적이다.
따라서, HashMap보다 퍼포먼스적인 측면에서 우수하고 Safety하게 사용할 수 있다.
반응형
'Language > ☕️Java' 카테고리의 다른 글
[Java] 멀티스레드를 통한 성능개선 (2) | 2023.01.19 |
---|---|
Java - bucket4j를 통해 트래픽 제한 및 IP 차단으로 Rate Limit 구현 (1) | 2022.12.21 |
JVM 아키텍처 2탄 - 런타임 데이터 영역(Run-time Data Area) (0) | 2022.08.31 |
StringBuffer에서 Thread safe의 원리 및 Example Sample Code를 통한 고찰 (0) | 2022.08.16 |
JAVA로 카카오 메시지 API연동 (4) | 2022.02.25 |
댓글