🟢 enum 열거형
- 관련된 상수들을 같이 묶어 놓는 것. java는 타입에 안전한 열거형을 제공
class Card{
static final int CLOVER = 0;
static final int HEART = 1;
static final int DIAMOND = 2;
static final int TWO = 0;
static final int THREE = 1;
static final int FOUR = 2;
final int kind;
final int num;
}
//아래 코드는 true이다.
Card.CLOVER == Card.TWO; //true. 하지만 이둘은 의미상 엄연히 다르다.
아래처럼 enum을 사용할 수 있다
//아래처럼 바꿀 수 있다.
class Card{
enum Kind { CLOVER, HEART, DIAMOND, SPADE } //열거형 kind를 정의앞에서부터 0, 1, 2, 3
enum Value { TWO, THREE, FOUR } //열거형 Value를 정의
final Kind kind; //타입이 int가 아닌 Kind
final Value num;
}
//enum을 사용하면 아래 코드는 false이다.
Card.Kind.CLOVER == Card.Value.TWO // ERROR. 타입이 달라 둘을 비교할 수 없
이처럼 자바의 열거형은 값과 타입을 모두 체크한다.
- 열거형을 정의하는 방법
// enum 열거형이름 { 상수명1, 상수명2, ... }
enum Direction { EAST, SOUTH, WEST, NORTH }
- 열거형 타입의 변수를 선언하고 사용하는 방법
class Unit{
int x, t;
Direction dir //열거형 인스턴스 변수를 선언
void init(){
dir = Direction.EAST; // 유닛의 방향을 EAST로 초기화
}
}
- 열거형 상수의 비교에 == 와 compareTo() 사용가능
if(dir == Direction.EAST){...} // 이건 가능
else if(dir > Direction.WEST){...} // 이건 안됨!!!
else if (dir.compareTo(Direction.WEST){...} // 이건 가능
// 비교연산자는 사용 불가!!!!
- 모든 열거형은 Enum(java.lang.Enum)의 자손이며, 아래의 메서드를 상속받는다.
메서드 | 설명 |
String name() | 열거형 상수의 이름을 문자열로 반환 |
int ordinal() | 열거형 상수가 정의된 순서를 반환(0부터 시작) |
T valueOf(Class<T> enumType, String name) | 지정된 열거형에서 name과 일치하는 열거형 상수를 반환 |
- values(), valueOf()는 컴파일러가 자동으로 추가
static E[] values()
static E valueOf(String name)
Direction[] dArr = Direction.values();
for(Direction d : dArr)
System.out.println(d.name()+" - "+d.ordinal());
// EAST - 0
// SOUTH - 1
// WEST - 2
// NORTH - 3
//valueOf()에 인자로 열거형 상수 이름을 넣으면
Direction d = Direction.valueOf("WEST");
예시:
public class Ex12_5 {
enum Direction{
// 0 1 2 3
EAST, SOUTH, WEST, NORTH
}
public static void main(String[] args) {
Direction d1 = Direction.EAST;
Direction d2 = Direction.valueOf("WEST");
Direction d3 = Enum.valueOf(Direction.class, "EAST");
System.out.println("d1 = " + d1);
System.out.println("d2 = " + d2);
System.out.println("d3 = " + d3);
System.out.println("d1==d2 ? " + (d1 == d2)); //false
System.out.println("d1==d3 ? " + (d1 == d3)); //true
System.out.println("d1.equals(d3) ? "+d1.equals(d3));
// System.out.println("d2 > d3 ? " + (d1 > d3)); //ERROR
System.out.println("d1.compareTo(d3) ? " + (d1.compareTo(d3)));
System.out.println("d1.compareTo(d3) ? " + (d1.compareTo(d3)));
switch(d1){
case EAST ://Direction.EAST라고 쓸 수 없음
System.out.println("The Direction is EAST."); break;
case SOUTH ://Direction.EAST라고 쓸 수 없음
System.out.println("The Direction is SOUTH."); break;
case WEST ://Direction.EAST라고 쓸 수 없음
System.out.println("The Direction is WEST."); break;
case NORTH ://Direction.EAST라고 쓸 수 없음
System.out.println("The Direction is NORTH."); break;
default:
System.out.println("INVALID direction"); break;
}
Direction[] dArr = Direction.values();
for (Direction d : dArr) {
System.out.printf("%s = %d%n",d.name(), d.ordinal());
}
}
}
출력결과:
열거형에 멤버 변수 추가하기
이전까지는 열거형의 상수들에 순서대로 0, 1, 2, 3... 의 값들이 할당되었지만 아래처럼 직접 원하는 값을 괄호()안에 넣을 수 있다.
enum Direction { EAST(1), SOUTH(5), WEST(-1), NORTH(10) }
위처럼 괄호()를 사용하려면, 인스턴스 변수와 생성자를 새로 추가해줘야 한다.
enum Direction{
EAST(1), SOUTH(5), WEST(-1), NORTH(10); //끝에 ;를 추가해줘야 한다.
private final int value;
Direction(int value) {
this.value = value;
}
public int getValue() {
return value;
}
}
열거형의 생성자는 묵지적으로 private이므로, 외부에서 객체 생성 불가
Direction d = new Direction(1); // ERROR. 열거형의 생성자는 외부에서 호출불가
예시:
package lambda.nam.enumex;
public class Ex12_6 {
enum Direction{
EAST(1, ">"), SOUTH(2, "V"), WEST(3, "<"), NORTH(4, "^");
private final int value;
private final String symbol;
private static final Direction[] DIR_ARR = Direction.values();
Direction(int value, String symbol) {
this.value = value;
this.symbol = symbol;
}
public int getValue() {
return value;
}
public String getSymbol() {
return symbol;
}
public static Direction of(int dir){
if(dir < 1 || dir > 4)
throw new IllegalArgumentException("Invalid value : "+dir);
return DIR_ARR[dir - 1];
}
public Direction rotate(int num) {
num = num % 4;
if(num < 0) num += 4;
return DIR_ARR[(value - 1 + num) % 4];
}
}
public static void main(String[] args) {
for (Direction d : Direction.values()) {
System.out.printf("%s = %d%n",d.name(), d.ordinal());
}
Direction d1 = Direction.EAST;
Direction d2 = Direction.of(1);
System.out.printf("d1 = %s, %d%n",d1.name(), d1.getValue());
System.out.printf("d2 = %s, %d%n",d2.name(), d2.getValue());
System.out.println(Direction.EAST.rotate(1));
System.out.println(Direction.EAST.rotate(2));
System.out.println(Direction.EAST.rotate(-1));
System.out.println(Direction.EAST.rotate(-2));
}
}
출력결과:
출처: 남궁성님 유튜브 강의
https://www.youtube.com/user/MasterNKS
'java' 카테고리의 다른 글
Generics 05 제네릭 형 변환 (0) | 2022.01.04 |
---|---|
Generics 05 와일드 카드, 제네릭 메서드 (0) | 2022.01.04 |
Generics 04 제한된 제네릭 클래스(제네릭스의 제약) (0) | 2022.01.03 |
Generics 03 Iterator, HashMap과 제네릭스 (0) | 2022.01.03 |
Generics 02 제네릭스 용어, 제네릭 타입과 다형성 (0) | 2022.01.02 |