본문 바로가기

Programing/JVM(Java, Kotlin)

[Java] enum find static 헬퍼 메서드

enum에 가끔 코드와 같은 값을 같이 넣을일이 있다.

문제는 enum <->코드 간에 데이터 변환이 필요하다.


enum -> 코드로 가는 것은 getter를 제공하면 되는데, 반대는 열거에서 찾아야 한다.

enum의 values()를 이용하면 iteration이 가능하기 때문이다.


enum 타입이 많은 경우에 최악의 경우 O(n)의 복잡도를 가지게 된다.

따라서 정적으로 map을 넣어두었다가 key에 해당하는 enum을 반환하게 헬퍼 메서드를 종종 만들게 된다.


그런데 키튼님에게 코드 리뷰를 받다 보니 Hashmap을 사용할 경우 CPU가 높이 치솟는 일이 발생할 수 있다고

java.util.concurrent.ConcurrentMap 를 사용하라고 권장하셨다.


대중 템플릿은 아래와 같은 형태가 된다.

public enum SomeStatus {
STATUS_A("0"),
STATUS_B("1"),
STATUS_C("2"),
STATUS_D("3"),
STATUS_E("4");

private String code;

SomeStatus(String code) {
this.code = code;
}

public String getCode() {
return code;
}

private static final Map<String, SomeStatus > findMap = Maps.newConcurrentMap();
static {
for (SomeStatus status : SomeStatus.values()) {
findMap.put(status.getCode(), status);
}
}
public static SomeStatus findByCode(String code) {
return findMap.get(code);
}
}

참고로 Maps는 구아바의 com.google.common.collect.Maps 이다.


만약 lombok을 쓴다면 아래처럼 쓸 수 있다.

@AllArgsConstructor(access = lombok.AccessLevel.PRIVATE)
public enum SomeStatus {
STATUS_A("0"),
STATUS_B("1"),
STATUS_C("2"),
STATUS_D("3"),
STATUS_E("4");

@Getter
private String code;

public static final Map<String, SomeStatus> findMap = Maps.newConcurrentMap();
static {
for (SomeStatus status : SomeStatus.values()) {
findMap.put(status.getCode(), status);
}
}
public static SomeStatus findByCode(String code) {
return findMap.get(code);
}
}

PMD에서 뭐라고 한다.


Name 'findMap' must match pattern '^[A-Z][A-Z0-9]*(_[A-Z0-9]+)*$'.

Validates identifiers for constants (staticfinal fields).