====== Java enum ======
===== name() 기반 조회가 많을 경우 =====
* ''name()''이나 기타 enum의 특정 필드값을 기준으로 다시 enum 자체를 조회할 일이 많다면 static 으로 미리 Map 을 만들어두고 Map 에서 조회하는게 낫다.
public enum MyEnum {
BAR,
BAZ;
// 외부에서는 MAP에 접근이 불가능해야한다.
private static final Map MAP = Stream.of(MyEnum.values()).collect(Collectors.toMap(Enum::name, Function.identity()));
public static MyEnum fromName(String name){
return MAP.get(name);
}
}
https://stackoverflow.com/a/43664038/1051402
===== 자기 참조 enum - Self referential enum =====
enum이 enum 생성자에서 동일 enum의 다른 값을 참조해야하는 경우가 발생할 수 있는데, 아직 초기화가 안된 다른 값을 참조하는 것은 문법적으로 불가하다.
이를 해결하는 여러가지 방법이 있다.
[[http://stackoverflow.com/questions/19429343/self-referential-enum-with-immutable-parameters|java - Self referential enum with immutable parameters - Stack Overflow]]
==== abstract method 구현 ====
public enum Flippable {
A {
public Flippable flip() { return Z; }
}, B {
public Flippable flip() { return Y; }
}, Y {
public Flippable flip() { return B; }
}, Z {
public Flippable flip() { return A; }
};
// 아래 추상 메소드를 각 enum 에서 직접 구현한다.
public abstract Flippable flip();
}
==== static loading ====
정적 초기화를 사용할 수도 있다. 그러나 이 경우에 새로운 enum이 추가될 경우 빠뜨린 값이 있을 경우가 있다. 이에 대해 정적 초기화 구문에서 validation을 해주는 코드를 넣는 것이 좋을 것 같다.
public enum Flippable {
A, B, Z, Y;
static {
A.opposite = Z;
B.opposite = Y;
Y.opposite = B;
Z.opposite = A;
// 모두 올바르게 값 설정이 되었는지 검증
for (Flippable f : Flippable.values()) {
if (f.flip().flip() != f) {
throw new IllegalStateException("Flippable " + f + " inconsistent.");
}
}
}
public Flippable flip() {
return opposite;
}
private Flippable opposite;
}
==== static loading with EnumMap ====
정적 로딩을 하되 [[https://docs.oracle.com/javase/7/docs/api/java/util/EnumMap.html|EnumMap]]을 사용한다.
public enum Flippable
{
A, B, Y, Z;
// 외부에서 접근, 변경 불가능하도록 private으로 선언.
private static final Map opposites;
static {
opposites = new EnumMap<>(Flippable.class);
opposites.put(A, Z);
opposites.put(B, Y);
opposites.put(Y, B);
opposites.put(Z, A);
// 모두 올바르게 값 설정이 되었는지 검증
for (Flippable f : Flippable.values()) {
if (f.flip().flip() != f) {
throw new IllegalStateException("Flippable " + f + " inconsistent.");
}
}
}
public Flippable flip() {
return opposites.get(this);
}
}
==== 문자열 사용 ====
생성자에서 enum이 아닌 enum을 나타내는 문자열을 받아서 나중에 메소드 호출시 이것을 enum 값으로 변경해주는 방법도 있다. 별로 추천하고 싶지 않음.