class Card {
// 카드 무늬
static final int CLOVER = 0;
static final int HEART = 1;
static final int DIAMOND = 2;
static final int SPADE = 3;
// 카드 숫자
static final int TWO = 0;
static final int THREE = 1;
static final int FOUR = 2;
final int kind;
final int num;
}
위 처럼 정의하기엔 너무 많음
간단하게 정의할 수 있는 것이 열거형
값 & 타입 모두 체크하는 장점이 있음
class Card {
// 상수가 자동으로 0부터 매겨짐
// {0, 1, 2, 3}
enum Kind {CLOVER, HEART, DIAMOND, SPADE}
// {0, 1, 2}
enum Value { TWO, THREE, FOUR}
final Kind kind; // 타입은 int가 아닌 kind임을 유의
final Value value;
}
// C언어에서는 값만 체크하기에 같다고 나옴
// 하지만 Java에서는 타입에 안전한 열거형 제공
// - 값 & 타입 체크
// C언어 : 값만 체크 가능해서 true지만 false여야 의미상 맞음 (값이 같기에 true)
// Java : 컴파일 에러, 값은 같지만 타입이 달라서 비교 불가
if(Card.CLOVER == CARD.TWO)
if(Card.kind.CLOVER == Card.Value.TWO) { // 컴파일 에러, 타입이 달라서 비교 불가
enum 열거형이름 {상수명1, 상수명2, ...}
// 0, 1, 2, 3
enum Direction { EAST, SOUTH, WEST, NORTH}
class Unit {
int x, y; // 유닛의 위치
// 열거형 인스턴스 변수 선언
// Direction 외의 값을 넣을 수 없음
Direction dir;
void init() {
dir = Direction.EAST; // 유닛의 방향 EAST 초기화
}
}
// true
if(dir == Direction.EAST) {
x++;
}
// 에러, 열거형 상수 비교연산자 사용불가
else if (dir > Direction.WEST) {
}
else if (dir.compareTo(Direction.WEST) > 0 ) { // compareTo()는 가능
// compareTo() : 왼쪽이 크면 양수, 오른쪽이 크면 음수, 같으면 0
}
메소드 | 설명 |
---|---|
Class<E> getDeclaringClass() | 열거형의 Class객체를 반환 |
String name() | 열거형 상수의 이름을 문자열로 반환 |
int ordinal() | 열거형 상수가 정의된 순서를 반환(0부터 시작) |
T valueOf(Class<T> enumType, String name) | 지정된 열거형에서 name과 일치하는 열거형 상수를 반환 |
values(), valueOf()는 컴파일러가 자동으로 추가
Direction[] dArr = Direction.values();
for(Direction d : dArr)
System.out.printf("%s = %d%n", d.name(), d.ordinal());
Direction d = Direction.valueOf("WEST"); // 열거형 상수 이름
// Direction.WEST 와 같은 의미
enum Direction { EAST, SOUTH, WEST, NORTH}
public class Main {
public static void main(String[] args) {
Direction d1 = Direction.EAST; // 열거형 타입.상수이름
Direction d2 = Direction.valueOf("WEST"); // == Direction.WEST
Direction d3 = Enum.valueOf(Direction.class, "EAST"); // Direction.EAST
System.out.println("d1="+d1); // d1=EAST
System.out.println("d2="+d2); // d2=WEST
System.out.println("d3="+d3); // d3=EAST
System.out.println("d1==d2 ? " + (d1==d2)); // d1==d2 ? false
System.out.println("d1==d3 ? " + (d1==d3)); // d1==d3 ? true
System.out.println("d1.equals(d3) ? " + d1.equals(d3)); // d1.equals(d3) ? true
// System.out.println("d2 > d3 ? " + (d1 > d3)); // 대소 비교 불가 에러
System.out.println("d1.compareTo(d3) ? " + (d1.compareTo(d3))); // 0 (같음)
System.out.println("d1.compareTo(d2) ? " + (d1.compareTo(d2))); // -2 (왼쪽이 작음)
switch(d1) {
// Direction.EAST 불가 : switch문 문법
case EAST:
System.out.println("The direction is EAST.");
break;
case SOUTH:
System.out.println("The direction is SOUTH.");
break;
case WEST :
System.out.println("The direction is WEST.");
break;
case NORTH :
System.out.println("The direction is North.");
break;
default :
System.out.println("Invalid direction.");
break;
}
Direction[] dArr = Direction.values(); // 열거형의 모든 상수를 배열로 반환
for(Direction d : dArr) // for(Direction d : Direction.values())
System.out.printf("%s=%d%n", d.name(), d.ordinal()); // ordinal : 순서, 열거형 객체에 값을 주면 ordinal값과 다를 수 있음
}
}
// 괄호 : 생성자 호출을 의미
enum Direction { EAST(1), SOUTH(5), WEST(-1), NORTH(10) }
enum Direction {
EAST(1), SOUTH(5), WEST(-1), NORTH(10); // 끝에 ; 추가 필요
private final int value; // 정수를 저장할 인스턴스 변수
(private) Direction(int value) { // 생성자 추가
this.value = value;
}
public int getValue() {
return value;
}
}
Direction d = new Direction(1); // 에러, 열거형의 생성자는 외부에서 호출 불가
enum Durection2 {
EAST(1, ">"), SOUTH(2, "V"), WEST(3, "<"), NORTH(4, "^");
0
private static final Direction2[] DIR_ARR = Direction2.values();
private final int value;
private final String symbol;
Direction2(int value, String symbol) { // 접근 제어자 private 생략
this.value = value;
this.symbol = symbol;
}
public int getValue() {
return value;
}
public String getSymbol() {
return symbol;
}
public static Direction2 of(int dir) {
if(dir < 1 || dir > 4)
throw new IllegalArgumentException("Invalid value :" + dir);
return DIR_ARR[dir - 1];
}
// 방향을 회전시키는 메서드. num 값만큼 90도씩 시계빵향 회전
public Direction2 rotate(int num) {
num = num % 4;
if(num < 0) num += 4; // num이 음수일때는 시계 반대 방향으로 회전
return DIR_ARR[(value-1+num) % 4];
}
public String toString() {
return name() + getSymbol();
}
}
class Ex12_6 {
public static void main(String[] args) {
for(Direction2 d : Direction2.values())
System.out.printf("%s=%d%n", d.name(), d.getValue());
// EAST=1, SOUTH=2, WEST=3, NORTH=4
// d.ordinal() 로 변경 시 0, 1, 2, 3 으로 순서대로 나옴
Direction2 d1 = Direction2.EAST;
Direction2 d2 = Direction2.of(1);
System.out.printf("d1=%s, %d%n", d1.name(), d1.getValue()); // d1=EAST, 1
System.out.printf("d2=%s, %d%n", d2.name(), d2.getValue()); // d2=EAST, 1
System.out.println(Direction2.EAST.rotate(1));
// SOUTHV
System.out.println(Direction2.EAST.rotate(2));
// WEST<
System.out.println(Direction2.EAST.rotate(-1));
// NORTH^
System.out.println(Direction2.EAST.rotate(-2));
// WEST<
}
}
@Getter
public enum MembershipType {
READY(0),
STARTING(1),
PAUSE(2),
EXTENSION(3),
RESTART(4);
private int status;
MembershipType(int status) {
this.status = status;
}
}
@Getter
public enum HistoryType {
PAYMENT(0),
EXTENSION(1),
PAUSE(2),
RESTART(3),
EXPIRATION(4);
private int status;
HistoryType(int status) {
this.status = status;
}
}
GymHistory tmp2 = GymHistory.builder()
.apt(user.getApt())
.gym(updateMembership.getGym())
.price(gymTicket.getPrice())
.name(gymTicket.getName())
.startDate(startDate)
.endDate(endDate)
.status(HistoryType.EXTENSION.getStatus()) // 연장 history
.paymentMethod(method)
.user(user)
.userName(userName != null ? userName : "알수없음")
.contact(contact != null ? contact : "알수없음")
.address(userAddress != null ? userAddress : "알수없음")
.build();
// 변경 전
.status(1) // 1은 연장을 나타냄
// 변경 후
.status(HistoryType.EXTENSION.getStatus()) // 연장 history