Java에서 Enum 사용하기

hksdpr·2023년 7월 15일
0

Java Enum의 기본 사용

java 에서는 enum을 선언하여 사용할 수 있다. 가령 술의 종류를 구분하고 싶다면 다음과 같은 enum을 만들어서 사용한다.

public enum LIQUOR_TYPE{
    DISTILLED,  //증류주
    FERMENTED,  //발효주
    INFUSED; // 침출주
}

enum의 종류에 따라 술의 이름을 출력하는 printLiquors함수는 다음과 같이 만들 수 있다.

public void printLiquors(LIQUOR_TYPE type){
    switch(type){
        case DISTILLED:
            System.out.println(
                    "Whisky, Brandy, Tequila ..."
            );
            break;
        case FERMENTED:
            System.out.println(
                    "Wine, Beer, Mead ..."
            );
            break;
        case INFUSED:
            System.out.println(
                    "Gin, Benedictine, Chartreuse ..."
            );
            break;
    }
}

이제 술의 종류에 따른 구분을 할 수 있다.

public static void main(String[] args) {
    Main m = new Main();
    LIQUOR_TYPE type1 = LIQUOR_TYPE.DISTILLED;
    LIQUOR_TYPE type2 = LIQUOR_TYPE.FERMENTED;
    LIQUOR_TYPE type3 = LIQUOR_TYPE.INFUSED;
    m.printLiquors(type1);
    m.printLiquors(type2);
    m.printLiquors(type3);
}

다음과 같이 코드를 작성하여 실행하면

public class Main {
    public enum LIQUOR_TYPE{
        DISTILLED,  //증류주
        FERMENTED,  //발효주
        INFUSED; // 침출주
    }

    public void printLiquors(LIQUOR_TYPE type){
        switch(type){
            case DISTILLED:
                System.out.println(
                        "Whisky, Brandy, Tequila ..."
                );
                break;
            case FERMENTED:
                System.out.println(
                        "Wine, Beer, Mead ..."
                );
                break;
            case INFUSED:
                System.out.println(
                        "Gin, Benedictine, Chartreuse ..."
                );
                break;
        }
    }

    public static void main(String[] args) {
        Main m = new Main();
        LIQUOR_TYPE type1 = LIQUOR_TYPE.DISTILLED;
        LIQUOR_TYPE type2 = LIQUOR_TYPE.FERMENTED;
        LIQUOR_TYPE type3 = LIQUOR_TYPE.INFUSED;
        m.printLiquors(type1);
        m.printLiquors(type2);
        m.printLiquors(type3);
    }
}

아래와 같은 결과가 나온다.

Whisky, Brandy, Tequila ...
Wine, Beer, Mead ...
Gin, Benedictine, Chartreuse ...

추가적인 값 관리하기

단순히 이름만 지정할 수 있는게 아니라 연관된 값을 지정할 수도 있다.
가령 각 종류의 소문자 이름을 함께 관리하고 싶으면 해당 정보를 추가하여 줄 수 있다. 추가한 정보를 사용하기 위한 getter를 생성해야 하며, getter에서 값을 읽을 때 사용할 private final 변수도 지정해야 한다. 또한 생성자에서 값을 초기화 해야 한다. 이 때 생성자는 private이어야 한다.

public enum LIQUOR_TYPE {
    DISTILLED("distilled"),  //증류
    FERMENTED("fermented"),  //발효
    INFUSED("infused"); // 침출

    private final String small;

    private LIQUOR_TYPE(String small) {
        this.small = small;
    }

    public String getSmall() {
        return this.small;
    }
}

다음과 같은 코드를 실행해보면

public class Main {
    public enum LIQUOR_TYPE {
        DISTILLED("distilled"),  //증류
        FERMENTED("fermented"),  //발효
        INFUSED("infused"); // 침출

        private final String small;

        private LIQUOR_TYPE(String small) {
            this.small = small;
        }

        public String getSmall() {
            return this.small;
        }
    }

    public static void main(String[] args) {
        Main m = new Main();
        LIQUOR_TYPE type1 = LIQUOR_TYPE.DISTILLED;
        LIQUOR_TYPE type2 = LIQUOR_TYPE.FERMENTED;
        LIQUOR_TYPE type3 = LIQUOR_TYPE.INFUSED;
        System.out.println(type1.getSmall());
        System.out.println(type2.getSmall());
        System.out.println(type3.getSmall());
    }
}

다음과 같은 실행결과가 나온다.

distilled
fermented
infused

키 이름을 통해 enum 값 만들기

가끔 String값을 받아서 enum으로 변경해야 하는 경우가 있다. 가령 "DISTILLED"를 값으로 받아서 LIQUOR_TYPE.DISTILLED를 찾아야 하는 경우다. 이때는 enum이 기본으로 제공하는 valueOf함수를 이용하면 된다. 이전의 코드를 다음과 같이 수정할 수 있다.

public static void main(String[] args) {
    Main m = new Main();
    String typeString1 = "DISTILLED";
    String typeString2 = "FERMENTED";
    String typeString3 = "INFUSED";
    LIQUOR_TYPE type1 = LIQUOR_TYPE.valueOf(typeString1);
    LIQUOR_TYPE type2 = LIQUOR_TYPE.valueOf(typeString2);
    LIQUOR_TYPE type3 = LIQUOR_TYPE.valueOf(typeString3);
    System.out.println(type1.getSmall());
    System.out.println(type2.getSmall());
    System.out.println(type3.getSmall());
}

다음과 같은 전체 코드를 실행해보면

public class Main {
    public enum LIQUOR_TYPE {
        DISTILLED("distilled"),  //증류
        FERMENTED("fermented"),  //발효
        INFUSED("infused"); // 침출

        private final String small;

        private LIQUOR_TYPE(String small) {
            this.small = small;
        }

        public String getSmall() {
            return this.small;
        }
    }

    public static void main(String[] args) {
        Main m = new Main();
        String typeString1 = "DISTILLED";
        String typeString2 = "FERMENTED";
        String typeString3 = "INFUSED";
        LIQUOR_TYPE type1 = LIQUOR_TYPE.valueOf(typeString1);
        LIQUOR_TYPE type2 = LIQUOR_TYPE.valueOf(typeString2);
        LIQUOR_TYPE type3 = LIQUOR_TYPE.valueOf(typeString3);
        System.out.println(type1.getSmall());
        System.out.println(type2.getSmall());
        System.out.println(type3.getSmall());
    }
}

다음과 같이 동일한 결과가 나온다.

distilled
fermented
infused

두개 이상의 값 추가하기

이전에 소문자 이름인 small을 추가하여 함께 관리하였다. 이번에는 한글 이름을 함께 관리하기 위해 다음과 같이 코드를 수정할 수 있다.

public enum LIQUOR_TYPE {
    DISTILLED("distilled", "증류주"),  //증류
    FERMENTED("fermented", "발효주"),  //발효
    INFUSED("infused", "침출주"); // 침출

    private final String small;
    private final String korean;

    private LIQUOR_TYPE(String small, String korean) {
        this.small = small;
        this.korean = korean;
    }

    public String getSmall() {
        return this.small;
    }

    public String getKorean(){
        return this.korean;
    }
}

다음과 같은 코드를 작성하고 실행하면

public class Main {
    public enum LIQUOR_TYPE {
        DISTILLED("distilled", "증류주"),  //증류
        FERMENTED("fermented", "발효주"),  //발효
        INFUSED("infused", "침출주"); // 침출

        private final String small;
        private final String korean;

        private LIQUOR_TYPE(String small, String korean) {
            this.small = small;
            this.korean = korean;
        }

        public String getSmall() {
            return this.small;
        }

        public String getKorean(){
            return this.korean;
        }
    }

    public static void main(String[] args) {
        Main m = new Main();
        LIQUOR_TYPE type1 = LIQUOR_TYPE.DISTILLED;
        LIQUOR_TYPE type2 = LIQUOR_TYPE.FERMENTED;
        LIQUOR_TYPE type3 = LIQUOR_TYPE.INFUSED;
        System.out.println(type1.getSmall() + " " + type1.getKorean());
        System.out.println(type2.getSmall() + " " + type2.getKorean());
        System.out.println(type3.getSmall() + " " + type3.getKorean());
    }
}

다음과 같은 결과가 나온다.

distilled 증류주
fermented 발효주
infused 침출주

값으로 enum찾기

소문자 이름이나 한글이름이 입력으로 주어졌을때 enum값을 만들고 싶은 경우가 있다. 가령 "증류주"라는 String이 입력되었을 때 LIQUOR_TYPE.DISTILLED값을 찾고 싶은 경우를 위해 다음과 같이 코드를 수정 할 수 있다.

public enum LIQUOR_TYPE {
    DISTILLED("distilled", "증류주"),  //증류
    FERMENTED("fermented", "발효주"),  //발효
    INFUSED("infused", "침출주"); // 침출

    private final String small;
    private final String korean;

    private static final Map<String, LIQUOR_TYPE> BY_SMALL =
            new HashMap<>();

    private static final Map<String, LIQUOR_TYPE> BY_KOREAN =
            new HashMap<>();

    static{
        for(LIQUOR_TYPE l : values()){
            BY_SMALL.put(l.getSmall(), l);
            BY_KOREAN.put(l.getKorean(), l);
        }
    }
    private LIQUOR_TYPE(String small, String korean) {
        this.small = small;
        this.korean = korean;
    }

    public String getSmall() {
        return this.small;
    }

    public String getKorean(){
        return this.korean;
    }

    public static LIQUOR_TYPE bySmall(String small){
        return BY_SMALL.get(small);
    }
    public static LIQUOR_TYPE byKorean(String korean){
        return BY_KOREAN.get(korean);
    }
}

다음과 같이 전체적인 코드를 실행하면

public class Main {
    public enum LIQUOR_TYPE {
        DISTILLED("distilled", "증류주"),  //증류
        FERMENTED("fermented", "발효주"),  //발효
        INFUSED("infused", "침출주"); // 침출

        private final String small;
        private final String korean;

        private static final Map<String, LIQUOR_TYPE> BY_SMALL =
                new HashMap<>();

        private static final Map<String, LIQUOR_TYPE> BY_KOREAN =
                new HashMap<>();

        static{
            for(LIQUOR_TYPE l : values()){
                BY_SMALL.put(l.getSmall(), l);
                BY_KOREAN.put(l.getKorean(), l);
            }
        }
        private LIQUOR_TYPE(String small, String korean) {
            this.small = small;
            this.korean = korean;
        }

        public String getSmall() {
            return this.small;
        }

        public String getKorean(){
            return this.korean;
        }

        public static LIQUOR_TYPE bySmall(String small){
            return BY_SMALL.get(small);
        }
        public static LIQUOR_TYPE byKorean(String korean){
            return BY_KOREAN.get(korean);
        }
    }

    public static void main(String[] args) {
        Main m = new Main();
        LIQUOR_TYPE type1 = LIQUOR_TYPE.byKorean("증류주");
        LIQUOR_TYPE type2 = LIQUOR_TYPE.bySmall("fermented");
        LIQUOR_TYPE type3 = LIQUOR_TYPE.byKorean("침출주");
        System.out.println(type1.getSmall() + " " + type1.getKorean());
        System.out.println(type2.getSmall() + " " + type2.getKorean());
        System.out.println(type3.getSmall() + " " + type3.getKorean());
    }
}

아래와 같은 결과가 출력된다.

distilled 증류주
fermented 발효주
infused 침출주

다만 이렇게 사용하는 경우 소문자 이름이나 한글 이름이 고유하다는 것이 명확해야 한다. 그렇지 않으면 HashMapput을 하는 과정에서 일부 값이 덮어 씌워지게 될 것이다. 간단한 방법으로는 values로 조회된 배열을 순회하면서 값이 일치하는지 확인하는 것이 있다.

0개의 댓글