아이템 33. ordinal을 배열 첨자로 사용하는 대신 EnumMap을 이용하라.

33. ordinal을 배열 첨자로 사용하는 대신 EnumMap을 이용하라.

ordinal 값을 배열 첨자로 사용하는 것은 적절하지 않다. 값이 변할 수 있을 뿐만 아니라, 타입 안정성도 보장 받지 못한다. 대안으로 EnumMap를 쓰자.

public enum Phase{
    SOLID, LIQUID, GAS;
    
    public enum Transition{
        MELT(SOLID, LIQUID),
        FREEZE(LIQUID, SOLID),
        BOIL(LIQUID, GAS),
        CONDENSE(GAS, LIQUID),
        SUBLIME(SOLID, GAS),
        DEPOSIT(GAS, SOLID);
        
        private final Phase src;
        private final Phase dst;
        
        Transition(Phase src, Phase dst){
            this.src = src;
            this.dst = dst;
        }
        
        private static final Map<Phase, Map<Phase, Transition>> m = new EnumMap<Phase, Map<Phase,Transition>>(Phase.class);
        static {
            Arrays.stream(Phase.values()).forEach(p->m.put(p, new EnumMap<Phase, Map<Phase,Transition>>(Phase.class)));
            Arrays.stream(Transition.values()).forEach(t->m.get(t.src).put(t.dst, t));
        }
        
        public static Transition from(Phase src, Phase dst){
            return m.get(src).get(dst);
        }
    }
}