Enum

이기영·2024년 6월 26일

Java 기초학습

목록 보기
11/14
post-thumbnail

목표

Java의 열거형에 대해 학습

목차

1. enum 정의하는 방법
2. enum이 제공하는 메소드(values()와 valueOf())
3. java.lang.Enum
4. EnumSet


1. enum 정의하는 방법

Java에서 enum(열거형)은 상수의 집합을 정의하는 특수한 데이터 타입입니다. enum을 사용하면 코드의 가독성을 높이고, 특정 값들만 사용할 수 있도록 제한할 수있습니다.


1-1 기본적인 enum의 정의

바로 코드를 통해 알아보겠습니다.

public enum Day {
    SUNDAY,
    MONDAY,
    TUESDAY,
    WEDNESDAY,
    THURSDAY,
    FRIDAY,
    SATURDAY
}

public class Main {
    public static void main(String[] args) {
        Day today = Day.MONDAY;
        System.out.println("오늘은: " + today);

        switch (today) {
            case MONDAY:
                System.out.println("월요일입니다.");
                break;
            case TUESDAY:
                System.out.println("화요일입니다.");
                break;
            // 다른 요일에 대한 처리...
            default:
                System.out.println("다른 요일입니다.");
                break;
        }
    }
}

  이렇게 정의된 enum을 사용할 때는 위와 같이 사용할 수 있습니다.



1-2 enum에 멤버 변수와 메서드 추가

  enum은 단순히 상수 값만 가질 수 있는 것이 아니라, 멤버 변수와 메서드도 추가할 수 있습니다. 예를 들어 각 요일에 대한 간단한 설명을 추가해 보겠습니다.

public enum Day {
    SUNDAY("휴일"),
    MONDAY("평일"),
    TUESDAY("평일"),
    WEDNESDAY("평일"),
    THURSDAY("평일"),
    FRIDAY("평일"),
    SATURDAY("휴일");

    private String description;

    Day(String description) {
        this.description = description;
    }

    public String getDescription() {
        return description;
    }
}

public class Main {
    public static void main(String[] args) {
        Day today = Day.SUNDAY;
        System.out.println("오늘은: " + today);
        System.out.println("설명: " + today.getDescription());
    }
}



1-3 enum에 추상 메서드 추가

  enum에 추상 메서드를 추가하고 각 열거형 값에서 이를 구현할 수 있습니다. 예를 들어 각 요일에 따라 다른 행동을 정의해보겠습니다.

public enum Day {
    SUNDAY {
        @Override
        public void action() {
            System.out.println("휴식을 취합니다.");
        }
    },
    MONDAY {
        @Override
        public void action() {
            System.out.println("일을 합니다.");
        }
    },
    TUESDAY {
        @Override
        public void action() {
            System.out.println("일을 합니다.");
        }
    },
    WEDNESDAY {
        @Override
        public void action() {
            System.out.println("일을 합니다.");
        }
    },
    THURSDAY {
        @Override
        public void action() {
            System.out.println("일을 합니다.");
        }
    },
    FRIDAY {
        @Override
        public void action() {
            System.out.println("일을 합니다.");
        }
    },
    SATURDAY {
        @Override
        public void action() {
            System.out.println("휴식을 취합니다.");
        }
    };

    public abstract void action();
}

public class Main {
    public static void main(String[] args) {
        Day today = Day.FRIDAY;
        today.action();  // "일을 합니다." 출력
    }
}

요약

  • enum은 상수의 집합을 정의하는 특수한 데이터 타입입니다.
  • enum에 멤버 변수와 메서드를 추가할 수 있습니다.
  • enum에 추상 메서드를 추가하고 각 열거형 값에서 이를 구현할 수 있습니다.



2. enum이 제공하는 메소드(values()와 valueOf())

enum은 자동으로 valuse()valueOf(String name) 메서드를 제공합니다.


2-1 values() 메서드

  values() 메서드는 해당 enum 타입의 모든 열거형 상수들을 배열로 반환합니다. 이 메서드는 컴파일러가 자동으로 추가하는 메서드로, 모든 enum 타입에서 사용할 수 있습니다.


public enum Day {
    SUNDAY, MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY
}

public class Main {
    public static void main(String[] args) {
        Day[] days = Day.values();

        for (Day day : days) {
            System.out.println(day);
        }
    }
}

// 출력
// SUNDAY
// MONDAY
// TUESDAY
// WEDNESDAY
// THURSDAY
// FRIDAY
// SATURDAY

  위 예제를 보면 알 수 있듯이, Day.values()Day 열거형 타입의 모든 상수를 배열로 반환합니다. 이 배열을 반복하여 모든 상수를 출력할 수 있습니다.



2-2 valueOf(String name) 메서드

  valueOf(String name) 메서드는 주어진 문자열과 일치하는 enum 상수를 반환합니다. 이 메서드는 java.lang.Enum 클래스에 정의되어 있으며, 문자열이 일치하는 enum 상수가 없으면 IllegalArgumentException을 던집니다. 문자열은 대소문자를 구분합니다.


public enum Day {
    SUNDAY, MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY
}

public class Main {
    public static void main(String[] args) {
        Day day = Day.valueOf("MONDAY");
        System.out.println(day);

        // 만약 문자열이 열거형 상수와 일치하지 않으면 예외가 발생합니다.
        try {
            Day invalidDay = Day.valueOf("FUNDAY");
        } catch (IllegalArgumentException e) {
            System.out.println("예외 발생: " + e.getMessage());
        }
    }
}

  위 예제 코드의 출력은 아래와 같습니다.

MONDAY
예외 발생: No enum constant Main.Day.FUNDAY

  위 예제에서 Day.valueOf("MONDAY")Day.MONDAY 상수를 반환합니다. 하지만, "FUNDAY"Day 열거형에 없는 타입이므로 IllegalArgumentException이 발생합니다.

요약

  • values() 메서드 : 해당 enum 타입의 모든 상수를 배열로 반환합니다.
  • valueOf(String name) 메서드 : 주어진 문자열과 일치하는 enum 상수를 반환하며, 일치하는 상수가 없으면 IllegalArgumentException을 던집니다.



3. java.lang.Enum

java.lang.Enum 클래스는 자바에서 모든 enum 타입의 공통적인 상위 클래스입니다. 이 클래스는 enum 타입을 보다 유용하게 만들기 위해 다양한 메서드와 기능을 제공합니다.

Enum 클래스는 제네릭 클래스이며, Enum<E extends Enum<E>>로 정의되어 있습니다. 이는 모든 enum 타입이 이 클래스를 상속받아야 함을 의미합니다.


3-1 name()

  name() 메서드는 열거형 상수의 이름을 반환합니다. 이 이름은 열거형 상수가 선언된 그대로의 문자열입니다.

public enum Day {
    SUNDAY, MONDAY, TUESDAY
}

public class Main {
    public static void main(String[] args) {
        Day day = Day.MONDAY;
        System.out.println(day.name());  // "MONDAY" 출력
    }
}



3-2 ordinal()

  ordinal() 메서드는 열거형 상수가 열거형 선언에서 정의된 순서를 반환합니다. 순서는 0부터 시작합니다.

public enum Day {
    SUNDAY, MONDAY, TUESDAY
}

public class Main {
    public static void main(String[] args) {
        Day day = Day.MONDAY;
        System.out.println(day.ordinal());  // 1 출력
    }
}



3-3 compareTo(E o)

  compareTo(E o) 메서드는 현재 열거형 상수와 주어진 열거형 상수를 비교합니다. 열거형 상수의 정의 순서에 따라 비교하며, 이 순서에 기반하여 정렬에 사용할 수 있습니다.

public enum Day {
    SUNDAY, MONDAY, TUESDAY
}

public class Main {
    public static void main(String[] args) {
        Day day1 = Day.MONDAY;
        Day day2 = Day.TUESDAY;
        System.out.println(day1.compareTo(day2));  // -1 출력
    }
}



3-4 toString()

  toString() 메서드는 열거형 상수의 이름을 반환합니다. name() 메서드와 동일한 결과를 반환합니다.

public enum Day {
    SUNDAY, MONDAY, TUESDAY
}

public class Main {
    public static void main(String[] args) {
        Day day = Day.MONDAY;
        System.out.println(day.toString());  // "MONDAY" 출력
    }
}



3-5 valueOf(Class<T> enumType, String name)

  valueOf(Class<T> enumType, String name) 메서드는 주어진 클래스 객체와 문자열을 사용하여 열거형 상수를 반환합니다. 주어진 이름과 일치하는 열거형 상수가 없으면 IllegalArgumentException을 던집니다.

public enum Day {
    SUNDAY, MONDAY, TUESDAY
}

public class Main {
    public static void main(String[] args) {
        Day day = Enum.valueOf(Day.class, "MONDAY");
        System.out.println(day);  // "MONDAY" 출력
    }
}



Enum 클래스의 구조

  java.lang.Enum 클래스의 기본 구조는 다음과 같습니다.

public abstract class Enum<E extends Enum<E>> implements Comparable<E>, Serializable {
    private final String name;
    private final int ordinal;

    // 기본 생성자
    protected Enum(String name, int ordinal) {
        this.name = name;
        this.ordinal = ordinal;
    }

    // 기타 메서드...
}



요약

  • 모든 enum 타입의 공통적인 상위 클래스
    Enum클래스는 모든 enum 타입이 자동으로 상속받는 클래스입니다.

  • 이름과 순서
    Enum 클래스는 각 열거형 상수의 이름과 순서를 저장합니다.

  • 비교와 정렬
    compareTo()메서드를 통해 열거형 상수 간의 비교와 정렬이 가능합니다.

  • 직렬화 가능
    Enum 클래스는 Serializable 인터페이스를 구현하여 열거형 상수가 직렬화 가능함을 보장합니다.

  • 유용한 메서드 제공
    name(), ordinal(), valueOf() 등 다양한 유용한 메서드를 제공합니다.



4. EnumSet

EnumSet은 자바에서 enum 타입의 상수를 저장하기 위해 특별히 설계된 집합(Set) 구현체입니다.

EnumSet은 일반적인 Set과는 다르게 성능 최적화 및 메모리 절약을 위해 특별한 내부 구조를 가지고 있습니다. EnumSetjava.util 패키지에 속해 있으며, enum 상수 집합을 다룰 때 매우 유용합니다.


특징

  • enum 타입 전용
    EnumSet은 특정 enum 타입의 상수들만 저장할 수 있습니다.

  • 효율적이고 빠름
    비트 백터(bit vector)로 내부적으로 구현되어 있어 메모리 사용이 적고 매우 빠릅니다.

  • 정렬
    저장된 요소들은 enum 상수가 정의된 순서대로 정렬됩니다.

  • 불변 객체
    EnumSet 자체는 변경 가능하지만, enum 상수는 불변 객체이므로 추가나 제거 시 항상 안전하게 작동합니다.


4-1 사용방법

EnumSet을 생성하는 방법은 아주 다양합니다.

allOf()

특정 enum 타입의 모든 상수를 포함하는 EnumSet을 생성합니다.

enum Day {
    SUNDAY, MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY
}

EnumSet<Day> allDays = EnumSet.allOf(Day.class);

nonOf()

비어있는 EnumSet을 생성합니다.

EnumSet<Day> noDays = EnumSet.noneOf(Day.class);

of()

하나 이상의 특정 enum 상수를 포함하는 EnumSet을 생성합니다.

EnumSet<Day> weekend = EnumSet.of(Day.SATURDAY, Day.SUNDAY);

range()

enum 상수 사이의 범위를 포함하는 EnumSet을 생성합니다.

EnumSet<Day> workdays = EnumSet.range(Day.MONDAY, Day.FRIDAY);

copyOf()

다른 컬렉션을 복사하여 EnumSet을 생성합니다.

Set<Day> someDays = EnumSet.of(Day.MONDAY, Day.WEDNESDAY);
EnumSet<Day> copiedDays = EnumSet.copyOf(someDays);



4-2 EnumSet의 메서드

EnumSetSet 인터페이스를 구현하므로 일반적인 Set 메서드들을 사용할 수 있습니다.

public class Main {
    public static void main(String[] args) {
        EnumSet<Day> weekend = EnumSet.of(Day.SATURDAY, Day.SUNDAY);

        // 요소 추가
        weekend.add(Day.FRIDAY);
        System.out.println("주말과 금요일: " + weekend);

        // 요소 제거
        weekend.remove(Day.FRIDAY);
        System.out.println("주말: " + weekend);

        // 포함 여부 확인
        boolean isWeekend = weekend.contains(Day.SUNDAY);
        System.out.println("일요일이 포함되어 있는가? " + isWeekend);

        // 반복
        for (Day day : weekend) {
            System.out.println(day);
        }
    }
}

출력은 아래와 같습니다.

주말과 금요일: [FRIDAY, SATURDAY, SUNDAY]
주말: [SATURDAY, SUNDAY]
일요일이 포함되어 있는가? true
SATURDAY
SUNDAY



4-3 활용 예시

EnumSet은 특정 enum 값들의 집합을 관리할 때 유용합니다. 예를 들어, 권한이나 상태를 관리하는데 사용할 수 있습니다.

enum Permission {
    READ, WRITE, EXECUTE
}

public class Main {
    public static void main(String[] args) {
        EnumSet<Permission> permissions = EnumSet.of(Permission.READ, Permission.WRITE);

        // 권한 추가
        permissions.add(Permission.EXECUTE);

        // 권한 확인
        if (permissions.contains(Permission.WRITE)) {
            System.out.println("쓰기 권한이 있습니다.");
        }

        // 권한 제거
        permissions.remove(Permission.READ);
        System.out.println("권한: " + permissions);
    }
}

출력은 아래와 같습니다.

쓰기 권한이 있습니다.
권한: [WRITE, EXECUTE]



요약

  • EnumSet은 특정 enum 타입의 상수를 저장하기 위한 효율적이고 메모리 절약형 집합입니다.

  • EnumSetenum 상수의 순서를 유지하고, 다양한 유용한 메서드를 제공합니다.

  • 다양한 생성 방법과 Set 인터페이스의 메서드들을 통해 쉽게 사용할 수 있습니다.

profile
안녕나를소개하지이름은HaBu직업은Programer취미는tai chi meditation

0개의 댓글