- enum 정의하는 방법
- enum이 제공하는 메소드 (values()와 valueOf())
- java.lang.Enum
- EnumSet
Enum
열거형(enum)은 서로 관련된 상수를 편리하게 선언하기 위해 JDK1.5부터 새로 추가되었습니다.
Enum 정의하는 방법
enum 열거형이름 다음에 괄호{}안에 상수의 이름을 나열하면 됩니다.
enum 열거형이름 { 상수명1, 상수명2, ... }
예시) 동서남북 4방향 열거형
enum Direction { EAST, SOUTH, WEST, NORTH }
Enum 비교방법
- '==' 사용 가능
- '>' '<' 같은 비교연산자 사용 불가능
- compareTo() 사용 가능
if (dir == Direction.EAST) {
//가능
} else if (dir > Direction.WEST) {
// 불가능
} else if (dir.compareTo(Direction.WEST) > 0) {
// 가능
}
...
java.lang.Enum
모든 열거형의 조상은 Enum 클래스 입니다.
Enum클래스에는 다음과 같은 메서드가 정의되어 있습니다.
메서드 | 설명 |
Class<E> getDeclaringClass() | 열거형의 Class객체를 반환한다. |
String name() | 열거형 상수의 이름을 문자열로 반환한다. |
int ordinal() | 열거형 상수가 정의된 순서를 반환한다.(0부터 시작) |
T valueOf(Class<T> enumType, String name) | 지정된 열거형에서 name과 일치하는 열거형 상수를 반환한다. |
열거형은 상수 하나하나가 자신의 객체입니다.
Direction으로 예를들면,
아래와 같은 Direction enum의 상수 EAST, SOUTH, WEST, NORTH는 하나하나가 다 Direction객체입니다.
enum Direction { EAST, SOUTH, WEST, NORTH }
아래 코드로 이해하면 쉽습니다.
class Direction {
static final Direction EAST = new Direction("EAST");
static final Direction SOUTH = new Direction("SOUTH");
static final Direction WEST = new Direction("WEST");
static final Direction NORTH = new Direction("NORTH");
private String name;
private Direction(String name) {
this.name = name;
}
}
실제 Enum을 흉내 내어 MyEnum을 작성해보겠습니다.
abstract class MyEnum<T extends MyEnum<T>> implements Comparable<T> {
static int id = 0; // 객체에 붙일 번호 (0부터 시작)
int ordinal;
String name = "";
public int ordinal() {
return ordinal;
}
MyEnum(String name) {
this.name = name;
ordinal = id++; // 객체를 생성할 때마다 id의 값을 증가시킨다.
}
public int compareTo(T t) {
return ordinal - t.ordinal();
}
}
객체가 생성될 때마다 번호를 붙여서 인스턴스 변수 ordinal에 저장합니다.
그리고 Comparable 인터페이스를 구현해서 열거형 상수간의 비교가 가능하도록 되어있습니다.
MyEnum<T extends MyEnum<T>> 인 이유
만약 클래스를 MyEnum<T>와 같이 선언하였다면, compareTo()를 위와 같이 간단히 작성할 수 없었을 것입니다.
왜냐하면 타입 T가 ordinal()이 정의되어 있는지 확인할 수 없기 때문입니다.
public int compareTo(T t) {
return ordinal - t.ordinal();
}
그래서 MyEnum<T extends MyEnum<T>>와 같이 선언한 것이며 이것은 타입 T가 MyEnum<T>의 자손이어야 한다는 의미입니다.
실제 Enum 클래스
- Enum<E extends Enum<E>> 으로 되어있는 것을 볼 수 있다.
- Comparable<E>도 구현하는 것을 볼 수 있다.
values()
values()는 열거형의 모든 상수를 배열에 담아 반환하는 메서드입니다.
이 메서드는 모든 열거형이 가지고있고, 컴파일러가 열거형에 자동으로 추가해줍니다.
public class EnumEx1 {
public static void main(String[] args) {
Direction[] values = Direction.values();
for (Direction value : values) {
System.out.printf("%s = %d\n", value.name(), value.ordinal());
}
}
}
valueOf()
values()와 마찬가지로 컴파일러가 자동으로 추가해주는 메서드입니다.
valueOf()는 열거형 상수의 이름으로 문자열 상수에 대한 참조를 얻을 수 있게 해줍니다.
static E values()
static E valueOf(String name)
사용예시
Direction d = Direction.valueOf("WEST");
System.out.println(d); // WEST
System.out.println(Direction.WEST == Direction.valueOf("WEST")); // true
EnumSet
EnumSet은 Set인터페이스를 기반으로 열거형의 요소들을 가장 쉽고 빠르게 배열처럼 다룰 수 있도록 고안된 구현체 입니다.
EnumSet의 중요한 특징
- 오직 열거형 상수만을 값으로 가질 수 있습니다.
- 모든 값은 같은 enum type이어야 합니다.
- null value 추가를 허용하지 않습니다.
- NullPointerException을 던지는 것을 허용하지 않습니다.
- ordinal 값의 순서대로 요소가 저장됩니다.
- 모든 메서드는 arithmetic 비트연산을 사용하기 때문에 모든 기본 연산의 시간 복잡도가 O(1)입니다.
- enum과 static타입의 메소드들로 구성되어있어 안정성을 보장합니다.
사용법
EnumSet static 메서드 | 설명 |
EnumSet.allOf() | 매개변수로 받는 열거형에 있는 모든 요소들을 가져온다. |
Enum.of() | 매개변수로 받는 해당 요소를 찾아서 넣는다. |
Enum.complementOf() | 매개변수로 받는 요소들만 빼고 넣는다. |
EnumSet.range() | 매개변수로 받는 두개의 구간안에 해당하는 요소를 넣는다. |
EnumSet.noneOf() | 매개변수로 받는 열거형을 비운 EnumSet을 반환한다. |
사용예시
package javastudy.ch11;
import java.util.EnumSet;
enum Color {
RED, YELLOW, GREEN, BLUE, BLACK, WHITE
}
public class EnumDemo {
public static void main(String[] args) {
EnumSet<Color> set1, set2, set3, set4, set4_1, set5;
set1 = EnumSet.allOf(Color.class);
set2 = EnumSet.of(Color.RED, Color.GREEN, Color.BLUE);
set3 = EnumSet.complementOf(set2);
set4 = EnumSet.range(Color.YELLOW, Color.BLACK);
set5 = EnumSet.noneOf(Color.class);
set5.add(Color.BLACK);
set5.add(Color.BLUE);
set5.remove(Color.BLACK);
System.out.println("set1 = " + set1);
System.out.println("set2 = " + set2);
System.out.println("set3 = " + set3);
System.out.println("set4 = " + set4);
try {
set4_1 = EnumSet.range(Color.BLACK, Color.YELLOW);
System.out.println("set4_1 = " + set4_1);
} catch (IllegalArgumentException e) {
System.out.println("set4_1은 오류가 발생합니다 : " + e.getMessage());
}
System.out.println("set5 = " + set5);
}
}
Enum 사용 참고 블로그
https://honbabzone.com/java/java-enum/
'Web > Java' 카테고리의 다른 글
[Java] 제네릭 (1) | 2021.08.30 |
---|---|
[Java] I/O (2) | 2021.08.24 |
[Java] 애노테이션 (1) | 2021.08.11 |
[Java] 멀티쓰레드 프로그래밍 (1) | 2021.08.06 |
[Java] 예외 (2) | 2021.08.02 |