λ³Έλ¬Έ λ°”λ‘œκ°€κΈ°
Java | Spring/Java

[JAVA] μ—΄κ±°ν˜• enums

by 동기 2021. 11. 1.
λ°˜μ‘ν˜•

πŸ¦Šμ—΄κ±°ν˜•(enums)

  • 1.1 μ—΄κ±°ν˜•μ΄λž€?
  • 1.2 μ—΄κ±°ν˜•μ˜ μ •μ˜μ™€ μ‚¬μš©
  • 1.3 μ—΄κ±°ν˜•μ— 멀버 μΆ”κ°€ν•˜κΈ°
  • 1.4 μ—΄κ±°ν˜•μ˜ 이해

🐡1.1 μ—΄κ±°ν˜•μ΄λž€?

컴퓨터 ν”„λ‘œκ·Έλž˜λ°μ—μ„œ μ—΄κ±°ν˜•μ΄λž€ μš”μ†Œ, 멀버라 λΆˆλ¦¬λŠ” λͺ…λͺ…λœ κ°’μ˜ 집합을 μ΄λ£¨λŠ” μžλ£Œν˜•μ΄λ‹€.

μžλ°”μ˜ μ—΄κ±°ν˜•μ€ μ—΄κ±°ν˜•μ΄ κ°–λŠ” κ°’λΏλ§Œ μ•„λ‹ˆλΌ νƒ€μž…κΉŒμ§€ κ΄€λ¦¬ν•˜κΈ° λ•Œλ¬Έμ— 보닀 논리적인 였λ₯˜λ₯Ό 쀄일 수 μžˆλ‹€.

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{
    enum Kind { CLOVER, HEART, DIAMOND, SPADE } // μ—΄κ±°ν˜• Kind μ •μ˜
    enum Value { TWO, THREE, FOUR } //μ—΄κ±°ν˜• Value μ •μ˜
    
    final Kind kind; // νƒ€μž…μ΄ int κ°€ μ•„λ‹Œ Kind 이닀
    final Value value;
}

기쑴의 λ§Žμ€ μ–Έμ–΄λ“€μ—μ„œλŠ” νƒ€μž…μ΄ 달라도 값이 κ°™μœΌλ©΄ 쑰건식 κ²°κ³Όκ°€ μ°Έ(true)μ΄μ—ˆμœΌλ‚˜ μžλ°”μ˜ 'νƒ€μž…μ— μ•ˆμ „ν•œ μ—΄κ±°ν˜•(typesafe enum)' μ—μ„œλŠ” μ‹€μ œ 값이 같아도 νƒ€μž…μ΄ λ‹€λ₯΄λ©΄ μ‘°κ±΄μ‹μ˜ κ²°κ³Όκ°€ falseκ°€ λœλ‹€.

 

κΈ°μ‘΄
if(Card.CLOVER == Card.TWO) // μ˜λ―Έμƒ false μ΄μ§€λ§Œ, κ°’ 0으둜 κ°™μ•„ true 둜 λ‚˜μ˜΄

enum ν™œμš©
if(Card.Kind.CLOVER == Card.Value.TWO) // 값이 0으둜 동일 ν•˜μ§€λ§Œ, μ˜λ―ΈλŠ” 달라 false둜 λ‚˜μ˜¨λ‹€

이처럼 κ°’λΏλ§Œ μ•„λ‹ˆλΌ νƒ€μž…κΉŒμ§€ μ²΄ν¬ν•˜κΈ° λ•Œλ¬Έμ— νƒ€μž…μ— μ•ˆμ „ν•˜λ‹€κ³  ν•˜λŠ” 것이닀.

그리고 더 μ€‘μš”ν•œ 것은 μ—΄κ±°ν˜• μƒμˆ˜λ₯Ό μ‚¬μš©ν•˜λ©΄, 기쑴의 μ†ŒμŠ€λ₯Ό λ‹€μ‹œ 컴파일 ν•˜μ§€ μ•Šμ•„λ„ λœλ‹€. ( κΈ°μ‘΄μ—λŠ” ν•΄λ‹Ή μƒμˆ˜λ₯Ό μ°Έμ‘°ν•˜λŠ” λͺ¨λ“  μ†ŒμŠ€λ₯Ό λ‹€μ‹œ 컴파일 ν•΄μ•Ό ν–ˆλ‹€.)


🐡1.2 μ—΄κ±°ν˜•μ˜ μ •μ˜μ™€ μ‚¬μš©

μ—΄κ±°ν˜•μ„ μ •μ˜ν•˜λŠ” 방법은 κ°„λ‹¨ν•˜λ‹€. μ€‘κ΄„ν˜Έ{} μ•ˆμ— μƒμˆ˜μ˜ 이름을 λ‚˜μ—΄ν•˜κΈ°λ§Œ ν•˜λ©΄ λœλ‹€.

enum μ—΄κ±°ν˜•λͺ… { μƒμˆ˜λͺ…1, μƒμˆ˜λͺ…2, ... }

 

예제둜 λ™μ„œλ‚¨λΆ 4λ°©ν–₯을 μƒμˆ˜λ‘œ μ •μ˜ν•˜λŠ” μ—΄κ±°ν˜• Direction을 μž‘μ„±ν•΄λ³΄μž.

enum Direction { EAST, SOUTH, WEST, NORTH }

이 μ—΄κ±°ν˜•μ— μ •μ˜λœ μƒμˆ˜λ₯Ό μ‚¬μš©ν•˜λŠ” 방법은 'μ—΄κ±°ν˜•λͺ….μƒμˆ˜λͺ…' 이닀. 클래슀의 static λ³€μˆ˜λ₯Ό μ°Έμ‘°ν•˜λŠ” 것과 λ™μΌν•˜λ‹€.

class Unit{
    int x,y; //μœ λ‹› μœ„μΉ˜
    Direction dir; // μœ λ‹› λ°©ν–₯. μ—΄κ±°ν˜•μ„ μΈμŠ€ν„΄μŠ€ λ³€μˆ˜λ‘œ μ„ μ–Έ
    
    void init(){
    	dir = Direction.EAST; // μœ λ‹›μ˜ λ°©ν–₯을 EAST둜 μ΄ˆκΈ°ν™”
    }
}

 

μ—΄κ±°ν˜• μƒμˆ˜κ°„μ˜ λΉ„κ΅μ—λŠ” == λ₯Ό μ‚¬μš©ν•  수 μžˆλ‹€. equals()κ°€ μ•„λ‹Œ == 둜 비ꡐ가 κ°€λŠ₯ν•˜λ‹€λŠ” 것은 그만큼 λΉ λ₯Έ μ„±λŠ₯을 μ œκ³΅ν•œλ‹€λŠ” 말이닀. κ·ΈλŸ¬λ‚˜ > < 같은 λΉ„κ΅μ—°μ‚°μžλŠ” μ‚¬μš©ν•  수 μ—†κ³ , compareTo()λŠ” μ‚¬μš©κ°€λŠ₯ν•˜λ‹€.

( compareTo() λŠ” 두 λΉ„κ΅λŒ€μƒμ΄ κ°™μœΌλ©΄ 0, μ™Όμͺ½μ΄ 크면 μ–‘μˆ˜, 였λ₯Έμͺ½μ΄ 크면 음수λ₯Ό λ°˜ν™˜ν•œλ‹€. )

if(dir == Direction.EAST){
	x++;
} else if (dir > Direction.WEST){ //μ—λŸ¬. μ—΄κ±°ν˜• μƒμˆ˜μ— λΉ„κ΅μ—°μ‚°μž μ‚¬μš© λΆˆκ°€
	...
} else if (dir.compareTo(Direction.WEST) > 0){ // compareTo()λŠ” μ‚¬μš© κ°€λŠ₯ν•˜λ‹€.
	...
}

 

λ‹€μŒκ³Ό 같이 switch λ¬ΈμœΌλ‘œλ„ κ°€λŠ₯ν•˜λ‹€.

void move(){
    switch(dir){
    	case EAST: x++;
        	break;
        case WEST: x--;
        	break;
        case SOUTH: y++;
        	break;
        case NORTH: y--;
        	break;
    }
}

μ΄λ•ŒλŠ” case문에 μ—΄κ±°ν˜• 이름은 적지 μ•Šκ³ , μƒμˆ˜λͺ…λ§Œ 적어야 ν•œλ‹€λŠ” μ œμ•½μ΄ μžˆλ‹€.

 

 

λͺ¨λ“  μ—΄κ±°ν˜•μ˜ 쑰상 - java.lang.Enum

μ—΄κ±°ν˜• Direction에 μ •μ˜λœ λͺ¨λ“  μƒμˆ˜λ₯Ό 좜λ ₯ν•˜λ €λ©΄, λ‹€μŒκ³Ό κ°™μ΄ν•œλ‹€.

Direction[] dArr = Direction.values();

for(Direction d : dArr) // Direction.values() λͺ¨λ“  μƒμˆ˜μ˜ 값을 담은 dArr 루프
	System.out.printf("%s = %d%n",d.name(),d.ordinal());

ordinal() 은 λͺ¨λ“  μ—΄κ±°ν˜•μ˜ 쑰상인 java.lang.Enumν΄λž˜μŠ€μ— μ •μ˜λœ κ²ƒμœΌλ‘œ, μ—΄κ±°ν˜• μƒμˆ˜κ°€ μ •μ˜λœ μˆœμ„œ(0λΆ€ν„° μ‹œμž‘)λ₯Ό μ •μˆ˜λ‘œ λ°˜ν™˜ν•œλ‹€.

λ©”μ„œλ“œ μ„€λͺ…
Class<E> getDeclaringClass() μ—΄κ±°ν˜•μ˜ Class 객체λ₯Ό λ°˜ν™˜ν•œλ‹€.
String name() μ—΄κ±°ν˜• μƒμˆ˜μ˜ 이름을 λ¬Έμžμ—΄λ‘œ λ°˜ν™˜ν•œλ‹€.
int ordinal() μ—΄κ±°ν˜• μƒμˆ˜κ°€ μ •μ˜λœ μˆœμ„œλ₯Ό λ°˜ν™˜ν•œλ‹€.(0λΆ€ν„° μ‹œμž‘)
T valueOf(Class<T> enumType, String name) μ§€μ •λœ μ—΄κ±°ν˜•μ—μ„œ nameκ³Ό μΌμΉ˜ν•˜λŠ” μ—΄κ±°ν˜• μƒμˆ˜λ₯Ό λ°˜ν™˜ν•œλ‹€.

valueOf() λŠ” μ—΄κ±°ν˜• μƒμˆ˜μ˜ 이름을 μ΄μš©ν•˜μ—¬ λ¬Έμžμ—΄ μƒμˆ˜μ— λŒ€ν•œ μ°Έμ‘°λ₯Ό μ–»μ„μˆ˜μžˆλ‹€.

Direction d = Direction.valueOf("WEST");

System.out.println(d); // WEST
System.out.println(Direction.WEST==Direction.valueOf("WEST")); //true

 

이제 예제λ₯Ό 톡해 μ—΄κ±°ν˜•μ„ 직접 μ •μ˜ν•˜κ³  μ‚¬μš©ν•΄λ³΄μž.

public class RoadToJavaApplication {
    enum Direction { 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))); //equals둜 비ꡐ κ°€λŠ₯. ==보닀 느린 μ„±λŠ₯
//        System.out.println("d1 > d3) : "+(d1>d3)); // > < 비ꡐ연산 μ‚¬μš© λΆˆκ°€
        System.out.println("d1.compareTo(d3) : "+d1.compareTo(d3)); // a.compareTo(b) a,b 비ꡐ ν•˜μ—¬ 왼이 크면 μ–‘μˆ˜,κ°™μœΌλ©΄ 0, 였λ₯Έμ΄ 크면 음수
        System.out.println("d1.compareTo(d2) : "+d1.compareTo(d2)); // a.compareTo(b) a,b 비ꡐ ν•˜μ—¬ 왼이 크면 μ–‘μˆ˜,κ°™μœΌλ©΄ 0, 였λ₯Έμ΄ 크면 음수

        /* switch μ—°μ‚° */
        switch (d1){
            case EAST: //Direction.EAST 라고 μ“Έ 수 μ—†λ‹€.
                System.out.println("Direction is EAST");break;
            case WEST:
                System.out.println("Direction is WEST");break;
            case SOUTH:
                System.out.println("Direction is SOUTH");break;
            case NORTH:
                System.out.println("Direction is NORTH");break;
        }

        Direction[] dArr = Direction.values(); //μ—΄κ±°ν˜•μ˜ λͺ¨λ“  μƒμˆ˜λ₯Ό 배열에 λ‹΄μ•„ λ°˜ν™˜

        for(Direction d : dArr)
            System.out.printf("%s = %d \n", d.name(),d.ordinal()); //이름과 μˆœμ„œ
    }

}

πŸ”»μ‹€ν–‰κ²°κ³Ό

d1 = EAST
d2 = WEST
d3 = EAST
d1==d2 : false
d1==d3 : true
d1.equals(d3) : true
d1.compareTo(d3) : 0
d1.compareTo(d2) : -2
Direction is EAST
EAST = 0 
SOUTH = 1 
WEST = 2 
NORTH = 3

 


🐡1.3 μ—΄κ±°ν˜•μ— 멀버 μΆ”κ°€ν•˜κΈ°

Enum ν΄λž˜μŠ€μ— μ •μ˜λœ ordinal()이 μ—΄κ±°ν˜• μƒμˆ˜κ°€ μ •μ˜λœ μˆœμ„œλ₯Ό λ°˜ν™˜ν•˜μ§€λ§Œ, 이 값을 μ—΄κ±°ν˜• μƒμˆ˜μ˜ κ°’μœΌλ‘œ μ‚¬μš©ν•˜μ§€ μ•ŠλŠ”κ²ƒμ΄ μ’‹λ‹€. 이 값은 내뢀적인 μš©λ„λ‘œλ§Œ μ‚¬μš©λ˜κΈ° λ•Œλ¬Έμ΄λ‹€.

 

μ—΄κ±°ν˜•μ˜ μƒμˆ˜κ°’μ΄ 연속적이라면 μƒκ΄€μ—†μ§€λ§Œ, λΆˆμ—°μ†μ μΈ κ²½μš°μ—λŠ” 이름 μ˜†μ— μ›ν•˜λŠ” 값을 κ΄„ν˜Έ()와 ν•¨κ»˜ 적어주면 λœλ‹€.

    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;
        }
    }

μ§€μ •λœ 값을 μ €μž₯ν•  수 μžˆλŠ” μΈμŠ€ν„΄μŠ€ λ³€μˆ˜μ™€ μƒμ„±μžλ₯Ό μƒˆλ‘œ μΆ”κ°€ν•΄ μ£Όμ–΄μ•Ό ν•œλ‹€.

μ—΄κ±°ν˜•μ˜ μΈμŠ€ν„΄μŠ€ λ³€μˆ˜λŠ” final이어야 ν•œλ‹€λŠ” μ œμ•½μ€ μ—†μ§€λ§Œ, valueλŠ” μ—΄κ±°ν˜• μƒμˆ˜μ˜ 값을 μ €μž₯ν•˜κΈ° μœ„ν•œ κ²ƒμ΄λ―€λ‘œ final을 λΆ™μž„.

 

Direction d = new Direction(1); // μ—λŸ¬. μ—΄κ±°ν˜•μ˜ μƒμ„±μžλŠ” μ™ΈλΆ€μ—μ„œ 호좜 λΆˆκ°€

μ—΄κ±°ν˜• Direction에 μƒˆλ‘œμš΄ μƒμ„±μžκ°€ μΆ”κ°€ λ˜μ—ˆμ§€λ§Œ, μœ„μ™€ 같이 μ—΄κ±°ν˜•μ˜ 객체λ₯Ό 생성할 수 μ—†λ‹€. μ—΄κ±°ν˜•μ˜ μƒμ„±μžλŠ” μ œμ–΄μžκ°€ λ¬΅μ‹œμ μœΌλ‘œ private이기 λ•Œλ¬Έμ΄λ‹€.

enum Direction{
	...
	Direction(inte value) { // private Direction(inte value)와 동일
    ...
	}
}

 

ν•„μš”ν•˜λ‹€λ©΄ , μ•„λž˜μ™€ 같이 ν•˜λ‚˜μ˜ μ—΄κ±°ν˜• μƒμˆ˜μ— μ—¬λŸ¬ 값을 지정할 수 μžˆλ‹€. λ‹€λ§Œ 그에 맞게 μΈμŠ€ν„΄μŠ€ λ³€μˆ˜μ™€ μƒμ„±μž 등을 μƒˆλ‘œ μΆ”κ°€ν•΄μ£Όμ–΄μ•Ό ν•œλ‹€.

enum Direction{
    EAST(1,">"),SOUTH(2,"V"),WEST(3,"<"),NORTH(4,"^");

    private static final Direction[] DIR_ARR = Direction.values();
    private final int value;
    private final String symbol; //μΈμŠ€ν„΄μŠ€ λ³€μˆ˜ μΆ”κ°€

    Direction(int value,String symbol){ // private
        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];
    }
    //λ°©ν–₯을 νšŒμ „μ‹œν‚€λŠ” λ©”μ„œλ“œ. num의 κ°’λ§ŒνΌ 90도씩 μ‹œκ³„λ°©ν–₯으둜 νšŒμ „ν•œλ‹€.
    public Direction 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 EnumEx2 {

    @Test
    void main(){
        for(Direction d: Direction.values())
            System.out.printf("%s=%d%n",d.name(),d.getValue());

        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));
    }
}

πŸ”»μ‹€ν–‰ κ²°κ³Ό

EAST=1
SOUTH=2
WEST=3
NORTH=4
d1=EAST, 1
d2=EAST, 1
SOUTHV
WEST<
NORTH^
WEST<

 

μ—΄κ±°ν˜•μ— 좔상 λ©”μ„œλ“œ μΆ”κ°€ν•˜κΈ°

μ•„λž˜μ˜ μ—΄κ±°ν˜• Transportation은 μš΄μ†‘ μˆ˜λ‹¨μ˜ μ’…λ₯˜ λ³„λ‘œ μƒμˆ˜λ₯Ό μ •μ˜ν•˜κ³  있으며, 각 μš΄μ†‘ μˆ˜λ‹¨μ—λŠ” κΈ°λ³Έμš”κΈˆ(BASIC_FARE)이 μ±…μ •λ˜μ–΄ μžˆλ‹€.

 

enum Transportation {
	BUS(100), TRAIN(150), SHIP(100), AIRPLANE(300);
    
    private final int BASIC_FARE;
    private transportation(int basicFare) {
		BASIC_FARE = basicFare;
    }
    int fare() { //μš΄μ†‘ μš”κΈˆμ„ λ°˜ν™˜
     return BASIC_FARE;
 	}
}

κ·ΈλŸ¬λ‚˜ μ΄κ²ƒλ§ŒμœΌλ‘œλŠ” λΆ€μ‘±ν•˜λ‹€.

 

 


🐡1.4 μ—΄κ±°ν˜•μ˜ 이해

λ°˜μ‘ν˜•

'Java | Spring > Java' μΉ΄ν…Œκ³ λ¦¬μ˜ λ‹€λ₯Έ κΈ€

[JAVA] μ»¬λ ‰μ…˜ ν”„λ ˆμž„μ›Œν¬ - μ΄ν„°λ ˆμ΄ν„°  (0) 2021.06.21

λŒ“κΈ€