11주차 과제: Enum
목표
자바의 열거형에 대해 학습하세요.
학습할 것 (필수)
- enum 정의하는 방법
- enum이 제공하는 메소드 (values()와 valueOf())
- java.lang.Enum
- EnumSet
enum 정의하는 방법
- 먼저 enum 에 대해 알아보자
enum(enumeration) 클래스( 상수의 집합)
- 열거형 클래스이며, java 1.5 부터 사용이 가능하다
- 셈, 계산, 열거, 목록, 일람표 (enumeration) 의 앞부분을 딴 예약어
장점
- 열거체를 비교할 때 실제 값뿐만 아니라 타입까지도 체크한다
- 열거체의 상숫값이 재정의되더라도 다시 컴파일할 필요가 없다.
- 데이터들 간의 연관 관계 표현이 가능하다
- 상태와 행위를 한곳에서 관리가 가능하다
- 데이터 그룹관리가 가능하다
특징
- 클래스를 상수처럼 사용이 가능하다
- Enum 클래스를 구현하는 경우 상수 값과 같이 유일하게 하나의 인스턴스가 생성된다
- 상속이 안된다
실 사용 경험
- 실제로 프로젝트를 진행할 때 상태값을 지정하거나 고정된 값들을 지정할때 사용해봤었다
- 이동욱님의 Java Enum 활용기 포스팅 내용 중
데이터들 간의 연관관계 표현
부분의 코드를 실제로 프로젝트에 적용해보았다.
선언
문법
enum 열거체이름 { 상수1, 상수2, 상수3}
예제
enum Champion {NIDALEE, MASTERYI, YUMI, ...}
사용
문법
열거체이름.상수이름
예제
Champion.NIDALEE
사용 예제 (switch)
public enum Champion {
NIDALEE, MASTERYI, YUMI
}
public class ChampionManager {
public String getSkill(Champion champion){
String skill = "";
System.out.println(champion);
switch (champion) {
case NIDALEE:
skill = "창 투척";
break;
case MASTERYI:
skill = "알파 스트라이크";
break;
case YUMI:
skill = "샤르르탄";
break;
}
return skill;
}
public static void main(String[] args) {
ChampionManager manager = new ChampionManager();
String myAmount = manager.getSkill(Champion.NIDALEE);
System.out.println(myAmount);
}
}
결과
NIDALEE
창 투척
사용 예제 (switch 미적용)
public enum Champion2 {
NIDALEE("창 투척"), MASTERYI("알파 스트라이크"), YUMI("샤르르탄");
private final String skill;
Champion2(String skill) {
this.skill = skill;
}
public String getSkill() {
return skill;
}
}
public class ChampionManager2 {
public static void main(String[] args) {
Champion2 yumi = Champion2.YUMI;
System.out.println("champion2 = " + yumi);
System.out.println("champion2.getSkill() = " + yumi.getSkill());
System.out.println();
Champion2 masteryi = Champion2.MASTERYI;
System.out.println("masteryi = " + masteryi);
System.out.println("masteryi.getSkill() = " + masteryi.getSkill());
System.out.println();
Champion2 nidalee = Champion2.NIDALEE;
System.out.println("nidalee = " + nidalee);
System.out.println("nidalee.getSkill() = " + nidalee.getSkill());
}
}
결과
champion2 = YUMI
champion2.getSkill() = 샤르르탄
masteryi = MASTERYI
masteryi.getSkill() = 알파 스트라이크
nidalee = NIDALEE
nidalee.getSkill() = 창 투척
enum이 제공하는 메소드(values()와 valueOf())
Enum클래스에서 선언되어 있는 메소드
- compareTo(E e)
- 매개 변수로 enum 타입과의 순서(ordinal) 차이를 리턴한다.
- getDeclaringClass()
- 클래스 타입의 enum을 리턴한다.
- name()
- 상수의 이름을 리턴한다.
- ordinal()
- 상수의 순서를 리턴한다.
- valueOf(Class enumType, String name)
- 전달된 문자열과 일치하는 해당 열거체의 상수를 반환한다
valueOf() 예제
public class ChampionManager4 {
public static void main(String[] args) {
Champion2 champion2 = Champion2.valueOf("YUMI");
System.out.println(champion2);
}
}
결과
YUMI
- values()메소드
- 해당 열거체의 모든 상수를 저장한 배열을 생성하여 반환한다
values() 예제
public class ChampionManager3 {
public static void main(String[] args) {
Champion2[] list = Champion2.values();
Arrays.stream(list).forEach(System.out::println);
}
}
결과
NIDALEE
MASTERYI
YUMI
java.lang.Enum
enum 클래스의 부모는 무조건 java.lang.Enum이다
- enum은 extends를 이용하여 선언할 수는 없다.
열거체를 조작하기 위한 메서드
-
protected
- Enum(String name, int ordinal)
- 컴파일러에서 자동으로 호출되도록 해놓은 생성자다. 하지만, 개발자가 이 생성자를 호출할 수는 없다.
- Enum(String name, int ordinal)
-
Enum 클래스의 부모 클래스는 Object 클래스이기 때문에, Object 클래스의 메소드들은 모두 사용할 수 있다. 하지만, Enum 클래스는 개발자들이 Object 클래스 중 4개의 메소드를 Overring하지 못하도록 막아놓았다.
-
clone()
- 객체를 복제하기 위한 메소드다. 하지만, 이 메소드는 enum 클래스에서 사용하면 안 된다. 만약 호출될 경우엔 CloneNotSupportedException이라는 예외를 발생시키도록 되어 있다.
EnumSet
- EnumSet은
java.util
패키지 내에 정의 되어 있는 추상 클래스이다
특징 및 고려사항
- Enum 값만 포함할 수 있으며 모든 값은 동일한 Enum 에 속해야한다
- Null 값을 추가 할 수 없다
- Thread-safe 하지 않으므로 필요한 경우 외부에서 동기화해야한다
- Enum 에 선언된 순서에 따라 저장된다
장점
- EnumSet의 모든 메서드는 산술 비트 연산을 사용하여 구현된다. 이러한 계산은 매우 빠르기 때문에 모든 기본 작업이 일정한 시간에 실행된다.
- HashSet과 다르게 버킷을 찾기 위해 해시코드를 계산할 필요가 없다
- 비트 벡터의 특성으로 인해서 EnumSet은 매우 간결하고 효율적이고, 모든 이점과 함께 적은 메모리를 사용한다
AbstractSet과 Cloneable, Serializable을 구현하고 있으며 상속 및 구현 구조는 아래와 같다
사용 메소드
allOf
- Enum 클래스 전체를 담는다
noneOf
- 빈 컬렉션을 만들 수 있다
range
- Enum의 하위 집합을 만든다
complementOf
- 매개 변수로 전달된 요소를 제외한다
copyOf
- 다른 EnumSet의 모든 요소를 복사하여 EnumSet을 만들 수 있다
예제
import java.util.EnumSet;
public class EnumSetSample {
public static void main(String[] args) {
// Champion2 Enum 클래스 전체를 담는다
EnumSet<Champion2> enumSetAllOf = EnumSet.allOf(Champion2.class);
System.out.println("enumSet values = " + enumSetAllOf);
EnumSet<Champion2> enumSetNoneOf = EnumSet.noneOf(Champion2.class);
System.out.println("enumSetNoneOf = " + enumSetNoneOf);
EnumSet<Champion2> enumSetRange = EnumSet.range(Champion2.MASTERYI, Champion2.YUMI);
System.out.println("enumSetRange = " + enumSetRange);
EnumSet<Champion2> enumSetComplementOf = EnumSet.complementOf(EnumSet.of(Champion2.NIDALEE, Champion2.MASTERYI));
System.out.println("enumSetComplementOf = " + enumSetComplementOf);
EnumSet<Champion2> enumSetCopyOf = EnumSet.copyOf(EnumSet.of(Champion2.NIDALEE, Champion2.YUMI));
System.out.println("enumSetCopyOf = " + enumSetCopyOf);
}
}
결과
enumSet values = [NIDALEE, MASTERYI, YUMI]
enumSetNoneOf = []
enumSetRange = [MASTERYI, YUMI]
enumSetComplementOf = [YUMI]
enumSetCopyOf = [NIDALEE, YUMI]
EnumMap
- Enum을 키로 독점적으로 사용하는 Map의 구현이다
장점
- 대응하는 HashMap에 비해 효율적이고 간결한 구현이며 내부적으로 배열로 표시된다.
사용 예제
import java.util.EnumMap;
public class EnumMapSample {
public static void main(String[] args) {
EnumMap<Champion2, String> enumMap = new EnumMap<>(Champion2.class);
System.out.println("enumMap = " + enumMap);
enumMap.put(Champion2.NIDALEE, "숨통 끊기");
enumMap.put(Champion2.MASTERYI, "명상");
enumMap.put(Champion2.YUMI, "너랑 유미랑");
System.out.println("enumMap put after= " + enumMap);
enumMap.entrySet().forEach(System.out::println);
}
}
결과
enumMap = {}
enumMap put after= {NIDALEE=숨통 끊기, MASTERYI=명상, YUMI=너랑 유미랑}
NIDALEE=숨통 끊기
MASTERYI=명상
YUMI=너랑 유미랑
Reference
'스터디 > LiveStudy' 카테고리의 다른 글
13주차 과제 : I/O (0) | 2021.02.08 |
---|---|
12주차 과제 : 애노테이션 (0) | 2021.01.31 |
10주차 과제: 멀티쓰레드 프로그래밍 (6) | 2021.01.18 |
9주차 과제: 예외 처리 (0) | 2021.01.11 |
8주차 과제: 인터페이스 (0) | 2021.01.04 |