예제코드
public class Plant {
enum LifeCycle { ANNUAL, PERNNIAL, BIENNIAL}
final String name;
final LifeCycle lifeCycle;
public Plant(String name, LifeCycle lifeCycle) {
this.name = name;
this.lifeCycle = lifeCycle;
}
@Override
public String toString() {
return name;
}
}
ordianl 인덱싱
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]);
}
문제
- 배배열은 제네릭과 호환되지 않아 비검사 형변환을 수행해야 함
- 배열은 각 인덱스의 의미를 모르기 때문에 출력 결과에 직접 레이블을 달아야 함
- 정수는 열거 타입과 달리 type-safe 하지 않기 때문에 정확한 정수값을 사용한다는 것을 직접 보증해야 함
EnumMap
Map<LifeCycle, Set<Plant>> plantsByLifeCycle = new EnumMap<>(LifeCycle.class);
for (LifeCycle lifeCycle : LifeCycle.values()) {
plantsByLifeCycle.put(lifeCycle,new HashSet<>());
}
for (Plant plant : garden) {
plantsByLifeCycle.get(plant.lifeCycle).add(plant);
}
//EnumMap은 toString을 재정의
System.out.println(plantsByLifeCycle);
장점
- 형변환을 하지 않음
- EnumMap의 toString을 이용하여 출력
- ordinal을 이용해 배열 인덱스를 사용하지 않아 인덱스를 계산하는 과정에서 오류가 발생하지 않음
- EnumMap은 내부에서 배열을 사용하기 때문에 Map의 타입 안전성과 배열의 성능을 보장
반응형
'스터디 > 이펙티브 자바' 카테고리의 다른 글
[Effective Java] Item39. 명명 패턴보단 어노테이션 (0) | 2022.06.26 |
---|---|
[Effective Java] Item38. 확장가능한 열거 타입이 필요하면 인터페이스 (0) | 2022.06.26 |
[Effective Java] Item36. 비트 필드 대신 EnumSet (0) | 2022.06.26 |
[Effective Java] Item35. ordinal 대신 인스턴스 필드 (0) | 2022.06.26 |
[Effective Java] Item34. int 대신 Enum (0) | 2022.06.19 |