[Java] Enum


Enum 요소 조회하기

많이 사용되는 2가지 방법

  1. 정적 팩토리 메서드
  2. HashMap

정적 팩토리 메서드

보통은 find, findByName, of, … 등의 이름을 가지며 형태는 다음의 Operator 클래스에 있는 of 메서드와 비슷한 모양으로 생겼다.

Example

public enum Operator {
    PLUS("+"),
    MINUS("-"),
    DIVIDE("/"),
    MULTIPLY("*");

    private final String representation;

    Operator(final String representation) {
        this.representation = representation;
    }

    public static Operator of(String input) {
        return Arrays.stream(Operator.values())
                .filter(operator -> operator.representation.equals(input))
                .findAny()
                .orElseThrow(() -> new IllegalArgumentException("연산자를 찾을 수 없습니다."));
    }
}

of 메서드는 파라미터로 비교하고자 하는 값을 전달받고 stream의 filter를 통해 원하는 Enum 요소를 찾아내고, 만약 원하는 Enum 요소를 조회하지 못한다면 예외를 발생시킨다

Enum요소를 조회할 때마다 values()를 매번 순회해야 한다. 개수가 많아지거나 호출 주기가 짧다면 비효율적

HashMap

Example

public enum Operator {
    PLUS("+"),
    MINUS("-"),
    DIVIDE("/"),
    MULTIPLY("*");
    
    private static final Map<String, Operator> OPERATOR_MAP =
            Collections.unmodifiableMap(Stream.of(values())
                    .collect(Collectors.toMap(Operator::getRepresentation, Function.identity())));

    private final String representation;

    Operator(final String representation) {
        this.representation = representation;
    }
    
    public static Operator of(String representation) {
        if (OPERATOR_MAP.containsKey(representation)) {
            return OPERATOR_MAP.get(representation);
        }
        throw new IllegalArgumentException("연산자를 찾을 수 없습니다.");
    }
    
    public static ErrorCode find(int code) {
            return Optional.ofNullable(map.get(code)).orElseThrow(IllegalArgumentException::new);
    }

    public String getRepresentation() {
        return representation;
    }
}

이전 방식에 비해 코드가 살짝 길어지긴 했지만, 이와 같이 Enum 안에서 HashMap을 통해 요소를 캐싱 하는 방식으로 구현하면 속도에서 장점을 확보할 수 있다.

필요한 Stream 처리를 한 번만 하고 이후에는 map의 get() 메서드를 통해 시간 복잡도 O(1) 만에 요소를 조회할 수 있기 때문에 앞서 살펴본 팩토리 메서드를 사용했을 때보다 약 20배 정도 빠른 조회 성능을 얻을 수 있다.

결론

Enum 요소가 많지 않을 경우 편의상 팩토리 메소드를 사용하는게 일반적이지만,

Enum요소의 개수와 조회 메소드의 호출 주기를 고려하면 효율적인 성능을 얻을 수 있다.

참고 자료

https://woowacourse.github.io/javable/2020-04-21/enum_search