순서 의존성: 상수의 선언 순서가 바뀌면 numberOfMusicians의 값도 함께 바뀌어 불일치가 발생한다.
값 중복 불가: 동일한 인원 수를 가진 상수(OCTET, DOUBLE_QUARTET)는 추가할 수 없다. 만일 중간에 다른 상수라도 추가되면 numberOfMusicians()는 혼란에 빠진다.
값을 건너뛸 수 없음: 중간에 비어 있는 값을 사용하지 못해 의미 없는 상수를 추가해야 할 수 있다.
ordinal()은 EnumSet, EnumMap과 같이 열거타입 기반의 범용 자료구조에 쓰일 목적으로 설계되었다.
2. EnumSet, EnumMap 범용 자료구조에 쓰일 목적의 ordinal()
ordinal() 메서드는 EnumSet과 EnumMap에서 열거 타입의 상수를 내부적으로 저장할 때 유용하게 활용된다. EnumSet은 열거 타입의 상수를 비트 벡터로 관리하고, EnumMap은 열거 타입을 키로 사용하는 맵으로 ordinal 값을 기반으로 효율적으로 동작한다.
importjava.util.EnumSet;importjava.util.EnumMap;importjava.util.Map;publicclassEnumExample {// 열거 타입 정의publicenumDay { MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY }publicstaticvoidmain(String[] args) {// EnumSet 예제: 주중과 주말을 구분EnumSet<Day> weekdays =EnumSet.range(Day.MONDAY,Day.FRIDAY);EnumSet<Day> weekend =EnumSet.of(Day.SATURDAY,Day.SUNDAY);System.out.println("Weekdays: "+ weekdays);System.out.println("Weekend: "+ weekend);// EnumMap 예제: 각 요일에 할당된 할일을 저장EnumMap<Day,String> dayTasks =newEnumMap<>(Day.class);dayTasks.put(Day.MONDAY,"Study Java");dayTasks.put(Day.TUESDAY,"Go to gym");dayTasks.put(Day.WEDNESDAY,"Grocery shopping");dayTasks.put(Day.THURSDAY,"Clean house");dayTasks.put(Day.FRIDAY,"Watch a movie");System.out.println("Tasks for the week:");for (Map.Entry<Day,String> entry :dayTasks.entrySet()) {System.out.println(entry.getKey() +": "+entry.getValue()); }// ordinal() 출력 예제System.out.println("\nOrdinal values:");for (Day day :Day.values()) {System.out.println(day +" ordinal: "+day.ordinal()); } }}
설명
EnumSet: EnumSet.range() 메서드는 ordinal()을 사용해 Day 열거 타입의 상수 순서에 따라 월요일부터 금요일까지의 범위를 지정한다. EnumSet.of()로 주말만 포함된 집합을 만들 수도 있다. EnumSet은 내부적으로 비트 벡터를 이용해 ordinal()을 활용해 고속 연산을 한다.
EnumMap: EnumMap은 열거 타입 상수를 키로 사용하여, ordinal 값으로 인덱스를 계산하여 배열처럼 효율적으로 값을 저장하고 검색한다.
ordinal(): ordinal() 메서드를 통해 열거 타입 상수의 순서(정수 값)를 확인할 수 있으며, 출력된 결과를 통해 각 상수의 ordinal 값을 확인할 수 있다.
Weekdays: [MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY]
Weekend: [SATURDAY, SUNDAY]
Tasks for the week:
MONDAY: Study Java
TUESDAY: Go to gym
WEDNESDAY: Grocery shopping
THURSDAY: Clean house
FRIDAY: Watch a movie
Ordinal values:
MONDAY ordinal: 0
TUESDAY ordinal: 1
WEDNESDAY ordinal: 2
THURSDAY ordinal: 3
FRIDAY ordinal: 4
SATURDAY ordinal: 5
SUNDAY ordinal: 6
EnumSet과 EnumMap은 ordinal을 내부적으로 사용해 고성능 자료구조를 제공하며, 이를 통해 열거 타입 상수를 효율적으로 관리할 수 있다.
3. ordinal 메서드 대신 인스턴스 필드를 사용하자
이 문제는 각 상수에 고유한 값을 할당하는 인스턴스 필드를 통해 해결할 수 있다.ordinal 메서드 대신, 상수별로 고정된 값을 필드에 저장하여 사용하는 방식이다.