item 37) ordinal 인덱싱 대신 EnumMap을 사용하라

ordinal 인덱싱

  • 아래는 LifeCycle 상수의 ordinal 인덱스 값을 배열의 인덱스로 사용하여, 특정 LifeCycle에 해당되는 Plant들을 배열 내부 Set에 추가한다.

  • 배열이 제네릭과 호환되지 않아 비검사 형변환 수행해야 한다.

  • 배열의 각 인덱스에 해당하는 의미를 모르므로 출력 결과에 직접 레이블을 달아주어야 한다.

  • 정수는 열거 타입과 달리 타입 안전하지 않으므로 정확한 정숫값을 사용한다는 것을 직접 보증해야 한다.

public static void usingOrdinalArray(List<Plant> garden) {
    Set<Plant>[] plantsByLifeCycle = (Set<Plant>[]) new Set[LifeCycle.values().length];
    for (int i = 0 ; i < plantsByLifeCycle.length ; i++) {
        plantsByLifeCycle[i] = new HashSet<>();
    }

    for (Plant plant : garden) {
        plantsByLifeCycle[plant.lifeCycle.ordinal()].add(plant);
    }

    for (int i = 0 ; i < plantsByLifeCycle.length ; i++) {
        System.out.printf("%s : %s%n", LifeCycle.values()[i], plantsByLifeCycle[i]);
    }
}

EnumMap

  • 열거 타입을 키로 사용하도록 설계하여, 실질적인 열거 타입 상수를 값으로 매핑하도록 한다.

  • 내부 구현 방식은 배열으로 되어있지만, 내부로 감춰져 Map의 타입 안전성과 배열의 성능을 가진다.

  • 스트림과 EnumMap을 함께 사용하는 예제이다.

  • 생애주기에 속하는 Plant 객체가 있을 경우에만 EnumMap의 키가 생성된다.

중첩 EnumMap

  • 이전 상태에서 '이후 상태에서 전이로의 맵'에 대응시키는 맵

  • 실제 내부에서는 맵들의 맵이 배열들의 배열로 구현되니 낭비되는 공간과 시간도 거의 없이 명확하고 안전하고 유지보수하기 좋다.

Last updated