EnumMap이 뭐지?

로마·2022년 3월 7일
4
post-thumbnail

EnumMap의 발견

이번 로또 미션을 진행하던 중 EnumMap이란 것을 알게되었습니다.

저는 Map이라 하면 당연히 HashMap을 사용해야하는 것인 줄 알고 이번 미션에도 당연히 사용하고 있었습니다. 그런데 다른 크루들의 코드를 보니 EnumMap을 사용하더군요.. 그래서 오늘은 EnumMap이 뭔지 왜 다들 사용하는지 왤케 핫한지 알아보도록 하겠습니다 🧐

EnumMap이 뭐야? 🤷‍♂️

보통 Map 이라 하면 key와 value를 가지는 자료구조를 뜻합니다. 그런데 앞에 Enum이 붙으면 어떻게 될까요?

EnumMap 구현 코드에 들어가보면 다음과 같이 설명됩니다.

A specialized Map implementation for use with enum type keys. All of the keys in an enum map must come from a single enum type that is specified, explicitly or implicitly, when the map is created. Enum maps are represented internally as arrays. This representation is extremely compact and efficient.

요약하자면.. EnumMap 은 Enum 타입을 키로 가지는 특수한 Map 구현체입니다

EnumMap에는 키를 Enum 타입으로 가지는 것 외에 주요한 특징들이 있습니다.

  • 내부적으로 데이터를 저장할 때 Enum 상수의 개수를 size로 하는 배열을 이용합니다.
  • EnumMap의 정렬은 Enum 에 정의된 상수의 순서를 따라갑니다.
  • null 값을 키로 사용할 수 없다.
  • 대부분 컬렉션 구현과 마찬가지로 EnumMap은 동기화되지 않습니다. 따라서 멀티쓰레드 환경에서 thread-safe하게 구현하기 위해서는 외부에서 동기화 해주는 작업이 필요합니다.

EnumMap 왜 쓰나요?

1. 성능적 이점

이를 알아보기 위해 다시 구현 코드의 설명을 봅시다.

EnumMap 구현체 가장 아래에는 다음과 같은 문구가 적혀있습니다.

Implementation note: All basic operations execute in constant time. They are likely (though not guaranteed) to be faster than their HashMap counterparts.

EnumMap은 모든 기본 작업을 일정한 상수 시간에 처리하게 됩니다. 그리고 장담은 못하지만 HashMap 보다 빠를 수 있다고 나와있습니다. 그렇다면 왜 HashMap 보다 빠를 수 있다고 이야기하는 걸까요?

위 코드는 EnumMap의 생성자입니다. 보면 keyType을 받아서 Objects 배열을 만들어 vals로 넣어주는 것을 확인할 수 있습니다. 위에 특징으로 말했던 내부를 배열로 구현을 한다는 것을 확인할 수 있죠!

배열로 구현을 하기 때문에 Enum의 각 순서를 유지하고 Null 값을 키로 가질 수 없게 되는 특징이 나오게 되는거죠. 그렇다면 이에 반해 HashMap은 어떨까요? HashMap은 HashTable을 이용하여 데이터를 저장하게 됩니다.

(https://ko.wikipedia.org/wiki/%ED%95%B4%EC%8B%9C_%ED%85%8C%EC%9D%B4%EB%B8%94)

해시 테이블은 삽입, 삭제, 조회 과정에서 평균적으로 O(1)의 시간복잡도를 가지고 있는 등 성능이 매우 좋은 것으로 유명합니다. 하지만 해시 충돌이 발생할 시에는 O(1)의 시간복잡도를 보장할 수 없죠. 하지만 EnumMap의 경우 모든 작업이 항상 상수시간에 처리가 되기 때문에 성능적으로 이점이 있다고 볼 수 있습니다!

2. 정렬된 맵

EnumMap은 정의한 Enum 상수의 순서대로 정렬된 상태로 존재하기 때문에 여기에서 오는 장점들이 존재합니다.

Enum 클래스에는 ordinal() 이라는 메서드가 존재합니다. 이는 Enum 상수가 몇 번째 위치에 해당하는지 찾아주는 메서드 입니다. 하지만 이 메서드를 사용을 이펙티브 자바에서는 지양하고 있고 API에서도 마찬가지로 다음과 같이 적혀있습니다.

Returns the ordinal of this enumeration constant (its position in its enum declaration, where the initial constant is assigned an ordinal of zero). Most programmers will have no use for this method. It is designed for use by sophisticated enum-based data structures, such as java.util.EnumSet and java.util.EnumMap.

대부분의 프로그래머에게는 이 메서드를 사용할 일이 없다고 적혀있고 이 대신 EnumMap이나 EnumSet 같은 enum 기반 자료구조를 사용하라고 적혀있습니다.

ordinal을 이용해서 직접 위치를 알아내는 것 보다 EnumMap을 사용하여 정렬된 상태를 이용하라는 것이죠.

해당 내용은 이펙티브 자바 아이템 35 ( ordinal 메서드 대신 인스턴스 필드를 사용하라 ), 아이템 37 ( ordinal 인덱싱 대신 EnumMap을 사용하라 )를 참고하면 자세히 알아볼 수 있습니다.

정리

Enum을 key로 가지는 맵이라면 EnumMap을 고려해보자

참조

https://velog.io/@kasania/Java-EnumMap

https://yoon0120.tistory.com/59

HashMap 자료 https://d2.naver.com/helloworld/831311

이펙티브 자바 아이템 35, 37

profile
우공이산

3개의 댓글

comment-user-thumbnail
2022년 3월 7일

오오오 ... 🤩

1개의 답글
comment-user-thumbnail
2022년 3월 7일

"장담은 못하지만" 빠르다라... 흐음...

답글 달기