EnumMap

2 분 소요

EnumMap은 Java에서 제공하는 Map 인터페이스 구현체 중 하나다.

주요 특징

  1. Key로 Enum을 사용: EnumMap은 이름에서 알 수 있듯이, 키로 Enum 타입만을 사용할 수 있다. 키의 타입이 제한적이지만, 이를 통해 EnumMap은 효율적인 성능을 제공합니다.
  2. 순서 보장: EnumMap에서는 키가 선언된 순서에 따라 데이터가 저장되며 조회된다. 이는 정렬에 대한 추가적인 작업 없이도 순서를 유지할 수 있다는 장점이 있다.
  3. 높은 성능: EnumMap은 내부적으로 배열을 사용하여 데이터를 저장한다. 이는 효율적인 메모리 사용을 가능하게 하며, 빠른 검색 속도를 제공한다. 또한, 해싱 충돌에 대한 걱정 없이 데이터를 관리할 수 있다.
  4. Null 키 불가: EnumMap은 null 키를 허용하지 않는다. 이는 NullPointerException을 방지하는 데 도움이 된다.
  5. 스레드 안전하지 않음: EnumMap은 동기화를 제공하지 않는다. 따라서, 여러 스레드에서 동시에 EnumMap을 변경하려는 경우, 외부에서 동기화를 제공해야 한다.

EnumMap은 내부적으로 배열을 사용하여 데이터를 저장하기 때문에 key로 사용하는 Enum이 가지고있는 상수의 수 만큼만 저장 공간이 필요하기 때문에, 저장 데이터가 늘어나면 리사이징을 하는 HashMap과 달리 리사이징을 할 필요가 없다. 또 EnumMap은 key로 Enum에 정의된 고유한 값을 사용하기 때문에 별도의 해싱 과정이 필요가 없다. 이로인해 해시 충돌이 일어나지 않으며 HashMap이 가지는 성능 저하 문제를 피할 수 있다. 추가로 HashMap은 순서를 유지하지 않고, EnumMap은 Enum에 정의된 key의 순서에 따라 저장 및 조회를 하기 때문에 정렬에 대한 추가적인 작업을 하지 않고도 순서를 유지할 수 있다.

package lotto.domain;  
  
import static lotto.domain.RankPrizeMessage.DEFAULT_RANK;  
import static lotto.domain.RankPrizeMessage.WITH_BONUS_RANK;  
  
import java.util.Arrays;  
  
public enum RankPrize {  
    FIFTH_PLACE(DEFAULT_RANK.getMessage(), 3, 5_000),  
    FOURTH_PLACE(DEFAULT_RANK.getMessage(), 4, 50_000),  
    THIRD_PLACE(DEFAULT_RANK.getMessage(), 5, 1_500_000),  
    SECOND_PLACE(WITH_BONUS_RANK.getMessage(), 5, 30_000_000),  
    FIRST_PLACE(DEFAULT_RANK.getMessage(), 6, 2_000_000_000),  
    ;  
  
    private final String rankMessage;  
    private final int matchCounts;  
    private final int prizeAmount;  
  
    RankPrize(String rankMessage, int matchCount, int prizeAmount) {  
        this.rankMessage = rankMessage;  
        this.matchCounts = matchCount;  
        this.prizeAmount = prizeAmount;  
    }  
		...
}

RankPrize라는 enum으로 각 등수 별 정보가 들어있다. enum에 들어있는 각 등수 별 당첨 횟수를 저장하고 조회하는 것이 목표였다.

private static EnumMap<RankPrize, Integer> initializeRanks() {  
    EnumMap<RankPrize, Integer> ranks = new EnumMap<>(RankPrize.class);
    // EnumMap의 모든 key에 기본값을 지정해주기 위한 Stream.  
    Arrays.stream(values())  
            .forEach(rankPrize -> ranks.put(rankPrize, INITIAL_VALUE.getValue()));  
    return ranks;  
}

EnumMap을 생성할 때는 Enum 타입의 클래스를 생성자에 지정해줘야 한다. 이렇게 함으로써 EnumMap은 지정된 Enum 타입의 모든 상수를 키로 사용할 수 있는 구조를 초기화한다.

EnumMap을 생성시 기본적으로 모든 key에 대한 값은 null로 초기화 된다. 즉, 특정 key에 대한 값을 아직 설정하지 않은 경우, 해당 key에 대한 값을 조회하면 null을 반환한다. 이는 EnumMap이 내부적으로 배열을 사용하여 값을 저장하고, 배열의 요소는 자동적으로 해당 타입의 기본값(null, 0, false 등)으로 초기화되기 때문이다.

따라서, EnumMap을 사용하기 전에 필요한 모든 key-value 쌍을 명시적으로 설정해주는 것이 좋다. 이렇게 하면 null 값을 방지하고, key-value 쌍이 완전하게 초기화된 상태에서 Map을 사용할 수 있다. 아쉽게도EnumMap 에 모든 key에 대해 기본 값을 지정해주는 메서드는 없기 때문에 반복문을 통해 키에 기본값을 넣어줘야 한다. key로 사용한 Enum의 값을 values()로 모두 꺼내서 값에 원하는 값을 넣어주면 된다.

태그: ,

카테고리:

업데이트:

댓글남기기