[백기선님과 함께하는 Live-Study] 11주차 - Enum

JoonYoung Maeng·2021년 1월 29일
0
post-thumbnail

✔️ 목표

자바의 열거형에 대해 학습하세요.

✔️ 학습할 것 (필수)

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

📌 Enum(열거형)

Enum이란 Enumeration(열거)의 줄인말로 자바에서 서로 관련이 있는 상수를 모아놓은 집합을 말한다. 단순 상수만 모아놓은 집합이기 때문에 class, interface에 선언해 사용할 수 있지만,

💡 Enum 정의하는 방법

기본적으로 Enum을 정의하는 방법은 Class를 정의하는 방법과 비슷하다. class 키워드 대신 enum 키워드를 넣어주면 되고, Enum 내부에서 정의하고자 하는 상수들은 상수명을 콤마(,)로 구분하여 넣어준다.

public enum Grade {
    VIP,
    DIAMOND,
    GOLD
}

Enum은 class와 비슷하게 생성자를 이용해 상수의 값을 지정해 주는 것이 가능하다.

package com.livestudy.eleventh;

public enum Month {
    JANUARY(1), FEBRUARY(2), MARCH(3), APRIL(4), MAY(5), JUNE(6),
    JULY(7), AUGUST(8), SEPTEMBER(9), OCTOBER(10), NOVEMBER(11), DECEMBER(12);

    private int month;

    Month(int month) {
        this.month = month;
    }

    public int getMonth() {
        return month;
    }
}

일반적으로 클래스 객체의 동일함을 비교할 때 equals 메소드를 이용해 비교하지만 Enum은 클래스의 종류 중 한개 임에도 불구하고 == 을 이용한 비교를 가능하게 한다.

package com.livestudy.eleventh;

public class UserTest {
    public static void main(String[] args) {
        User user = new User("user A",Grade.DIAMOND);
        User user2 = new User("user B",Grade.VIP);

        int discount = getDiscount(user);
				System.out.println(user.getId()+"의 등급은 "+user.getGrade()+"이고, 할인 가격은 "+discount+"원 입니다.");
    }

    private static int getDiscount(User user) {
				// == 지원 
				// if(user.getGrade().equals(Grade.VIP)) 틀린 것은 아님
        if(user.getGrade() == Grade.VIP)
            return 3000;
        if (user.getGrade() == Grade.DIAMOND)
            return 2000;
        if (user.getGrade() == Grade.GOLD)
            return 1000;
        return 0;
    }
}

==을 통해 유저 A의 등급을 비교했을 때 정확하게 할인가격을 반환해주는 것을 확인할 수 있다.

image


💡 Enum이 제공하는 메소드 (values()와 valueOf())

✏️ values() 메소드

Enum에서 values 메소드는 Enum에 열거되어 있는 상수들을 배열 형태로 반환해주는 메소드이다. 예를 들어 위의 Enum Month를 values()를 이용해 가져와보자.

package com.livestudy.eleventh;

public class MonthTest {
    public static void main(String[] args) {
        Month[] months = Month.values();
        for(Month month : months){
            System.out.println(month);
        }
    }
}

values() 메소드를 이용해 배열 형식으로 값을 가져옴을 확인할 수 있다.

image

✏️ valueOf() 메소드

Enum에서 valueOf() 메소드는 Enum에 열거되어 있는 상수 중 메소드의 파라미터의 값과 동일한 상수를 반환한다. 당연한 얘기이고 상수이기 때문에 대문자로 선언되어 있을 가능성이 높지만, 대소문자, 공백이 모두 동일한 경우에만 값을 반환하고, 만약 열거되어 있는 상수가 없는 경우에는 IllegalArgumentException 예외를 발생시킨다.

package com.livestudy.eleventh;

public class MonthTest {
    public static void main(String[] args) {
				// 정상 출력
        Month Jan = Month.valueOf("JANUARY");
        System.out.println(Jan+"는 "+Jan.getMonth()+"월");

				//IllegalArgumentException 발생
        Month July = Month.valueOf("July");

    }
}

👉🏻 실행 결과

image

✏️ Ordinal() 메소드

Enum에서 Ordinal() 메소드는 Enum에 열거되어 있는 상수의 index를 반환하는 메소드이다.

package com.livestudy.eleventh;

public class MonthTest {
    public static void main(String[] args) {
        for(Month month : Month.values()){
            System.out.print(month+"는 "+month.getMonth()+"월 index : "+month.ordinal()+"\t");   
        }
    }
}

👉🏻 실행 결과

image


💡 java.lang.Enum

java.lang.Enum 클래스는 자바의 모든 Enum 타입의 상위 클래스이다.

출처 : https://www.geeksforgeeks.org/java-lang-enum-class-java/

📌 java.lang.Enum 주요 메소드

  • final String name() : 열거된 상수의 이름을 반환하는 메소드이다.
package com.livestudy.eleventh;
public class GradeTest {
    public static void main(String[] args) {
        Grade grade = Grade.DIAMOND;
        System.out.println("Grade 열거 이름 : " + grade.name());
    }
}

👉🏻 실행 결과

image

  • final int ordinal() : 열거된 상수의 위치를 반환하는 메소드이다.
package com.livestudy.eleventh;

public class GradeTest {
    public static void main(String[] args) {
        Grade grade = Grade.DIAMOND;
        System.out.println("Grade 열거형 위치 : " + grade.ordinal());
    }
}

👉🏻 실행 결과

image

  • String toString() : 열거된 상수를 나타내는 String 객체를 반환하는 메소드이다. name()과 동일한 역할을 하지만 오버라이딩이 가능하다.
package com.livestudy.eleventh;

public class GradeTest {
    public static void main(String[] args) {
        Grade grade = Grade.DIAMOND;
        System.out.println("Grade 열거형 이름 : " + grade.toString());
    }
}

👉🏻 실행 결과

image

  • final boolean equals() : 열거된 상수와 동일한 객체인지 판단하는 메소드이다.
package com.livestudy.eleventh;

public class GradeTest {
    public static void main(String[] args) {
        Grade grade = Grade.DIAMOND;
        Grade grade2 = Grade.VIP;
        System.out.println("Grade와 Grade2가 동일한가 ? : "+ grade.equals(grade2));
    }
}

👉🏻 실행 결과

image

  • final int hashCode() : 열거된 상수의 해시코드 값을 반환하는 메소드이다.
package com.livestudy.eleventh;

public class GradeTest {
    public static void main(String[] args) {
        Grade grade = Grade.DIAMOND;
        System.out.println("Grade 해시코드 : "+grade.hashCode());
    }
}

👉🏻 실행 결과

image

  • final int compareTo(E obj) : 열거된 상수의 ordinal 값을 기준으로 지정된 객체와 비교하는 메소드이다.
package com.livestudy.eleventh;

public class GradeTest {
    public static void main(String[] args) {
        Grade grade = Grade.DIAMOND;
        Grade grade2 = Grade.VIP;
        System.out.println("Grade와 Grade2 비교 : "+ grade.compareTo(grade2));
    }
}

👉🏻 실행 결과

image

  • static T valueOf(Class enumType, String name) : 파라미터를 통해 전달되는 열거된 상수와 동일한 값을 반환한다.
package com.livestudy.eleventh;

public class GradeTest {
    public static void main(String[] args) {
        Grade grade = Grade.DIAMOND;
        System.out.println("파라미터와 일치하는 Grade 값  : "+ Grade.valueOf("DIAMOND"));
    }
}

👉🏻 실행 결과

image

  • final Class getDeclaringClass() : 열거형 상수의 열거형 타입의 클래스 객체를 반환하는 메소드이다.
package com.livestudy.eleventh;

public class GradeTest {
    public static void main(String[] args) {
        Grade grade = Grade.DIAMOND;
        System.out.println("선언된 클래스 : "+grade.getDeclaringClass());
    }
}

👉🏻 실행 결과

image

  • inal Object clone() : 컴파일러나 열거된 상수에 의해 사용되는 메소드로 열거 클래스의 싱글톤 상태를 보존하기 위해 사용된다.

  • final void finalize() : enum 클래스가 final 메소드를 가질 수 없게하는 메소드이다.


💡EnumSet

EnumSet은 열거형 타입 상수들을 하나의 배열처럼 사용할 수 있게 해준다. EnumSet은 비트 연산을 이용하기 때문에 메모리의 공간을 작게 차지할 뿐만 아니라 속도면에서 빠른모습을 보여준다. EnumSet은 new 연산자를 이용해 선언할 수 없기 때문에 EnumSet.allOf(열거형 클래스.class); 형식으로 선언할 수 있다.

package com.livestudy.eleventh;

import java.util.EnumSet;

public class EnumSetTest {
    public static void main(String[] args) {
				
				// EnumSet 선언
        EnumSet<Month> enumSet = EnumSet.allOf(Month.class);
        System.out.println(enumSet);

        // EnumSet을 비우는 메소
        enumSet = EnumSet.noneOf(Month.class);
        System.out.println(enumSet);

        // EnumSet.of() : 파라미터로 전달되는 열거형 상수를 제외한 상수를 담아 배열로 리턴하는 메소드
        enumSet = EnumSet.of(Month.JANUARY);
        System.out.println(enumSet);

        // 파라미터로 들어오는 EnumSet을 제외한 상수를 담아 배열로 리
        enumSet = EnumSet.complementOf(enumSet);
        System.out.println(enumSet);

        // 파라터로 전해지는 범위의 열거형 상수를 담아 배열로 리턴
        enumSet = EnumSet.range(Month.JANUARY,Month.JUNE);
        System.out.println(enumSet);
    }
}

👉🏻 실행 결과

image


📃 Reference

Enum : https://www.nextree.co.kr/p11686/

java.lang.Enum : https://www.geeksforgeeks.org/java-lang-enum-class-java/

EnumSet : https://velog.io/@kwj1270/Enum#enumset

profile
백엔드 개발자 지망생입니다!

0개의 댓글