본문 바로가기

이펙티브 자바

[이펙티브 자바] 아이템 37. ordinal 인덱싱 대신 EnumMap을 사용하라

ordinal 인덱싱 : 열거형 상수가 선언된 순서에 따라 숫자를 매기는 것을 말한다. 열거형의 첫 번째 상수는 0부터 시작하여 상수가 선언된 순서대로 1씩 증가하는 값을 가지게 된다.

 

EnumMap : 열거형을 키로 사용하는 맵이다. 이 맵은 열거형의 모든 상수를 키로 사용할 수 있으며, 각 상수에 대한 값에 접근하기 위해 배열을 사용한다. 열거형을 키로 사용하기 때문에 EnumMap은 해시 테이블 대신 배열을 사용하여 효율적으로 구현된다.

 

배열의 인덱스를 얻기위해 EnumMap을 사용한 예시 코드 : 

import java.util.EnumMap;

// 예시 Enum 타입
enum Weekday {
    MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY
}

public class Main {
    public static void main(String[] args) {
        // EnumMap 생성
        EnumMap<Weekday, Integer> indexMap = new EnumMap<>(Weekday.class);

        // 각 Enum 상수에 대한 인덱스 할당
        indexMap.put(Weekday.MONDAY, 0);
        indexMap.put(Weekday.TUESDAY, 1);
        indexMap.put(Weekday.WEDNESDAY, 2);
        indexMap.put(Weekday.THURSDAY, 3);
        indexMap.put(Weekday.FRIDAY, 4);

        // 각 Enum 상수에 대한 인덱스 조회
        System.out.println("Index of MONDAY: " + indexMap.get(Weekday.MONDAY));
        System.out.println("Index of TUESDAY: " + indexMap.get(Weekday.TUESDAY));
        System.out.println("Index of WEDNESDAY: " + indexMap.get(Weekday.WEDNESDAY));
        System.out.println("Index of THURSDAY: " + indexMap.get(Weekday.THURSDAY));
        System.out.println("Index of FRIDAY: " + indexMap.get(Weekday.FRIDAY));
    }
}

 

다차원 관계를 표현한 예시 코드 : 

import java.util.EnumMap;

// 요일 Enum 타입
enum Weekday {
    MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY
}

// 시간대 Enum 타입
enum TimeOfDay {
    MORNING, AFTERNOON, EVENING, NIGHT
}

public class Main {
    public static void main(String[] args) {
        // 다차원 관계를 표현하기 위해 EnumMap<Weekday, EnumMap<TimeOfDay, String>> 사용
        EnumMap<Weekday, EnumMap<TimeOfDay, String>> schedule = new EnumMap<>(Weekday.class);

        // 각 요일과 시간대에 해당하는 일정 추가
        schedule.put(Weekday.MONDAY, new EnumMap<>(TimeOfDay.class));
        schedule.get(Weekday.MONDAY).put(TimeOfDay.MORNING, "Meeting");
        schedule.get(Weekday.MONDAY).put(TimeOfDay.AFTERNOON, "Workout");

        schedule.put(Weekday.TUESDAY, new EnumMap<>(TimeOfDay.class));
        schedule.get(Weekday.TUESDAY).put(TimeOfDay.MORNING, "Gym");
        schedule.get(Weekday.TUESDAY).put(TimeOfDay.AFTERNOON, "Study");

        // 일정 조회 예시
        String mondayMorningSchedule = schedule.get(Weekday.MONDAY).get(TimeOfDay.MORNING);
        System.out.println("Monday morning schedule: " + mondayMorningSchedule);
    }
}

 

핵심정리 : 배열의 인덱스를 얻기 위해 ordinal을 쓰는 것은 일반적으로 좋지 않으니, 대신 EnumMap을 사용하라.

다차원 관계는 EnumMap<..., EnumMap<...>>으로 표현하라. ("애플리케이션 프로그래머는 Enum.ordinal을 사용하지 말아야한다" 는 일반 원칙의 특수한 사례다.)