ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [Java] Enum에 필드 추가하기
    카테고리 없음 2019. 8. 4. 11:01

    Java의 Enum클래스는 상수의 범위를 제한함으로써 String이나 int등의 상수 변수를 쓰는 것에 비해 효과적이다.

    Java Enum을 클래스처럼 사용하기

    다음은 간단한 enum리스트이다. 주기율표의 첫 두 줄을 다음과 같이 enum으로 나타낼 수 있다.

    public enum Element {
    	H, HE, LI, BE, B, C, N, O, F, NE
    }

    위의 문법을 사용하면 간단하게 Element라는 static, final enum인스턴스를 생성할 수 있다.

    대문자로 변수를 표기하는 방법은 Java에서 일반적인 변수를 표기하는 방법이 아니다. 또한 요소의 이름이나 원자 무게 등의 정보도 빠져있다.

    Java의 enum은 클래스처럼 생성자, 필드, 그리고 메소드 등을 추가하여 사용할 수 있다. 이러한 항목들을 추가하여 위의 enum을 개선해보자.

    생성자와 필드 추가하기

    public enum Element {
        H("Hydrogen"),
        HE("Helium"),
        // ...
        NE("Neon");
     
        public final String label;
     
        private Element(String label) {
            this.label = label;
        }
    }

    private 생성자를 통해서 new로 인스턴스를 생성하는 것은 불가능하지만 인자가 있는 enum을 위한 생성자를 정의할 수 있다. enum의 기본 필드인 name과 별개로 label이라는 필드를 선언했으며, 인자로 label을 전달함으로써 개별 enum항목에서 Enum.name()메소드와의 구분했다.

    enum은 상수로 사용되기 때문에 label 필드는 final로 label이 생성 후에 변경되는 것을 방지했다. 

    label필드는 public 으로 선언하여 아래와 같이 접근 가능하도록 한다.

    System.out.println(BE.label);

    또는 private로 선언 후에 getLabel() 메소드를 추가하여 접근할 수도 있다.

    정의한 필드값으로 Enum 항목 찾기

    Java는 enum타입에 대해서 valueOf(String)을 제공한다. enum의 선언된 이름을 기반으로 아래와 같이 가져올 수 있다.

    assertSame(Element.LI, Element.valueOf("LI"));

    하지만, 우리가 정의한 label필드로 찾기를 원하는 경우, 아래와 같이 static 메소드를 정의한다.

    public static Element valueOfLabel(String label) {
    	for (Element e : values()) {
        	if (e.label.equals(label)) {
            	return e;
            }
        }
        return null;
    }

    다음은 valueOfLabel()메소드를 사용하는 간단한 사용예이다.

    assertSame(Element.LI, Element.valueOfLabel("Lithium"));

    Map을 사용한 Enum 항목 캐싱하기

    필드를 사용한 Enum항목을 찾을 때 매번 전체 Enum을 순회하는 것이 비효율적인 경우 항목들을 캐싱할 수 있다. 다음과 같이 class가 로딩될 때 static final Map을 사용하여 캐싱한다.

    public enum Element {
    	// ...
        private static final Map<String, Element> BY_LABEL = new HashMap<>();
        static {
        	for (Element e : values()) {
            	BY_LABEL.put(e.label, e);
            }
        }
        //...
        public Element valueOfLabel(String label) {
        	return BY_LABEL.get(label);
        }

    여러 필드를 사용한 캐싱

    public enum Element {
        H("Hydrogen", 1, 1.008f),
        HE("Helium", 2, 4.0026f),
        // ...
        NE("Neon", 10, 20.180f);
     
        private static final Map<String, Element> BY_LABEL = new HashMap<>();
        private static final Map<Integer, Element> BY_ATOMIC_NUMBER = new HashMap<>();
        private static final Map<Float, Element> BY_ATOMIC_WEIGHT = new HashMap<>();
         
        static {
            for (Element e : values()) {
                BY_LABEL.put(e.label, e);
                BY_ATOMIC_NUMBER.put(e.atomicNumber, e);
                BY_ATOMIC_WEIGHT.put(e.atomicWeight, e);
            }
        }
     
        public final String label;
        public final int atomicNumber;
        public final float atomicWeight;
     
        private Element(String label, int atomicNumber, float atomicWeight) {
            this.label = label;
            this.atomicNumber = atomicNumber;
            this.atomicWeight = atomicWeight;
        }
     
        public static Element valueOfLabel(String label) {
            return BY_LABEL.get(label);
        }
     
        public static Element valueOfAtomicNumber(int number) {
            return BY_ATOMIC_NUMBER.get(number);
        }
     
        public static Element valueOfAtomicWeight(float weight) {
            return BY_ATOMIC_WEIGHT.get(weight);
        }
    }

    출처 : https://www.baeldung.com/java-enum-values

    댓글

Designed by Tistory.