일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
- 백준#boj#12755
- 백준#boj#16932#모양만들기
- 백준#BOJ#2615#오목
- 백준#BOJ#1939#중량제한
- 백준#BOJ#8012#한동이는영업사원
- 백준#BOJ#12865#평범한배낭
- 백준#BOJ#14501#퇴사#브루트포스
- Today
- Total
순간을 성실히, 화려함보단 꾸준함을
11주차 과제: Enum 본문
목표
자바의 열거형에 대해 학습하세요.
학습할 것 (필수)
- enum 정의하는 방법
- enum이 제공하는 메소드
- java.lang.Enum
- EnumSet
1. enum 정의하는 방법
열거형이란?
- 서로 관련된 상수를 편리하게 선언하기 위한 것으로 여러 상수를 정의할 때 사용하면 유용하다. Java5에서 추가된 개념으로 열거형이 갖는 값뿐만 아니라 타입도 관리하기 때문에 보다 논리적인 오류를 줄일 수 있다.
정의
enum 열거형이름{ 상수명1, 상수명2, ...}
예를 들어 동,서,남,북 을 정의하는 열거형 Direction은 다음과 같다
enum Direction{ EAST,WEST,SOUTH,NORTH}
정의된 상수를 사용하는 방법은 열거형이름.상수명
이다.
class Unit{
int x,y; // 유닛의 위치
Direction dir; // 열거형을 인스턴스 변수로 선언
void inti(){
dir = Direction.EAST; // 유닛의 방향을 EAST로 초기화
}
}
열거형 상수간의 비교에서 ==
을 사용할 수 있다. equals()
가 아닌 ==
으로 비교가 가능하다는 것은 빠른 성능을 제공한다는 뜻
그러나 <,>
와 같은 비교연산자는 사용할 수 없고 compareTo()는 사용 가능하다.
if(dir==Direction.EAST){
x++;
} else if(dir > Direction.WEST){ // 에러, 열거형 상수에 비교연산자 사용불가
...
} else if(dir.compareTo(Direction.WEST > 0){ //compareTo() 사용가능
...
}
CompareTo() 란?
compareTo() 함수는 두 Integer 객체에 저장된 int값(value)를 비교하여 같으면 0, 크면 -1, 작으면 1을 반환해주는 함수이다.
Comparable 인터페이스에 정의되어 있는 메소드이다.
switch문의 조건식에도 열거형을 사용할 수 있다.
void move(){
switch(dir){
case EAST: x++;
break;
case WEST: x--;
break;
case SOUTH: y++;
break;
case NORTH: y--;
break;
}
}
이때 주의할 점은 case문에 열거형의 이름은 적지 않고 상수의 이름만 적어야 한다.
열거형(enum)의 특징
- 열거형 상수들은 해당 열거형의 객체이다.
enum Direction { EAST, SOUTH, WEST, NORTH }
사실은 열거형 상수 하나하나가 Direction 객체이다. 위의 문장을 클래스로 표현해보자
class Direction{
static final Direction EAST = new Direction("EAST");
static final Direction SOUTH = new Direction("SOUTH");
static final Direction WEST = new Direction("WEST");
static final Direction NORTH = new Direction("NORTH");
private String name;
private Direction(String name) {
this.name = name;
}
Direction 클래스의 static 상수 EAST,SOUTH,WEST,NORTH 의 값은 객체의 주소이고, 이 값은 바뀌지 않으므로 ==
으로 비교가 가능한 것이다.
- 열거형에 맴버를 추가할 수 있고, 생성자를 선언할 수 있다.
열거형에 맴버를 추가할 수 있는데, 이때 상수들을 선언하고 마지막에 ;
세미콜론을 반드시 추가하여야 한다.
또한, 생성자를 선언할 수 있다.
public class Main{
public static void main(String[] args) {
Direction dir = new Direction("North"); //Compile Error 발생
}
}
enum Direction{
EAST("E"), WEST("W"), SOUTH("S"), NORTH("N");
String dir;
Direction(String dir){
this.dir=dir;
}
String getDir(){
return this.dir;
}
}
위의 소스는 컴파일에러가 발생한다. 그 이유는 열거형 생성자는 제어자가 묵시적으로 private이기 때문에 외부에서 열거형의 생성자를 호출 할 수 없다.
필요하다면 열거형 상수에 여러값을 지정할 수 있다.
enum Direction{
EAST("E",1), WEST("W",2), SOUTH("S",3), NORTH("N",4);
String dir;
Direction(String dir,int number){ //private이 생략된 것 이다.
this.dir=dir;
}
String getDir(){
return this.dir;
}
}
2. enum이 제공하는 메소드
- T[] values() : enum의 요소들을 순서대로 enum 타입의 배열로 리턴한다.
- T valueOf(Class
enumType, String name) : 지정된 열거형에서 name 과 일치하는 열거형 상수를 반환한다. - Class
getDeclaringClass() : 열거형의 Class객체를 반환한다. - String name() : 열거형 상수의 이름을 문자열로 반환한다.
- int ordinal() : 열거형 상수가 정의된 순서를 반환한다.(0부터 시작)
T[] values() : enum의 요소들을 순서대로 enum 타입의 배열로 리턴한다.
public class Main{
public static void main(String[] args) {
for(Direction d : Direction.values())
System.out.println(d);
}
}
enum Direction{
EAST, WEST, SOUTH, NORTH;
}
//출력
EAST
WEST
SOUTH
NORTH
T valueOf(Class enumType, String name) : 지정된 열거형에서 name 과 일치하는 열거형 상수를 반환한다.
public class Main{
public static void main(String[] args) {
//2가지의 방법이 존재한다.
Direction dir1 = Enum.valueOf(Direction.class,"EAST");
System.out.println(dir1);
Direction dir2 = Direction.valueOf("EAST");
System.out.println(dir2);
}
}
enum Direction{
EAST, WEST, SOUTH, NORTH;
}
//출력
EAST
EAST
int ordinal() : 열거형 상수가 정의된 순서를 반환한다.(0부터 시작)
public class Main{
public static void main(String[] args) {
int order;
order = Direction.EAST.ordinal();
System.out.println(order);
order = Direction.WEST.ordinal();
System.out.println(order);
order = Direction.SOUTH.ordinal();
System.out.println(order);
order = Direction.NORTH.ordinal();
System.out.println(order);
}
}
enum Direction{
EAST, WEST, SOUTH, NORTH;
}
3. java.lang.Enum
모든 Enum 클래스는 java.lang.Enum
클래스를 상속받는다.
또한, 자바는 다중 상속을 지원하지 않으므로 Enum 클래스는 다른 클래스를 상속받을 수 없다.
public class Main{
public static void main(String[] args) {
}
}
class Rabbit{
int age;
Rabbit(){}
}
enum Direction extends Rabbit{ //Compile Error 발생 (No extends clause allowed for enum)
EAST, WEST, SOUTH, NORTH;
}
Enum타입은 고정된 상수들의 집합으로, 컴파일타임에 모든 값을 알고있어야 한다.(런타임이 아니다).
즉, 다른 클래스나 패키지에서 Enum 타입에 접근해서 동적으로 임의의 값을 정해줄 수 없다.
4. EnumSet
열거셋(EnumSet)은 Set 인터페이스를 기반으로 하면서 enum 열거요소들을 이용해서 보다 빠르고 강력하게 결과를 도출해 낼 수 있도록 자바 5 에서 등장한 개념이다.
EnumSet은 기술상으로 2^6(64)개를 넘지 않을 경우에 겉은 Set 기반이지만 내부적으로 long 데이터형의 비트 벡터를 사용하고 있다.
비트 벡터(Bitvector)
특별한 종류의 배열이다. 기본적으로 비트벡터는 저장 공간이 낭비되지 않도록 비트값(boolean 값)들을 배열에 꽉 채워넣기 위한 공간으로, 비트들을 최소의 크기로 꾸려 넣을 수 있게 한다.
enum Day{
SUNDAY,MONDAY,TUESDAY,WEDNESDAY,THURSDAY,FRIDAY,SATURDAY
}
public class Main{
public static void main(String[] args) {
EnumSet es = EnumSet.allOf(Day.class);
System.out.println(es);//출력 : [SUNDAY, MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY]
EnumSet es2 = EnumSet.copyOf(es);
System.out.println(es2);//출력 : [SUNDAY, MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY]
es2 = EnumSet.noneOf(Day.class);
System.out.println(es2); //출력 : []
es = EnumSet.of(Day.FRIDAY,Day.WEDNESDAY);
System.out.println(es); //출력 : [WEDNESDAY, FRIDAY]
es2 = EnumSet.complementOf(es);
System.out.println(es2);//출력 : [SUNDAY, MONDAY, TUESDAY, THURSDAY, SATURDAY]
es2 = EnumSet.range(Day.TUESDAY,Day.FRIDAY);
System.out.println(es2);//출력 : [TUESDAY, WEDNESDAY, THURSDAY, FRIDAY]
}
}
- copyOf(EnumSet s) : 매개변수로 들어온 EnumSet을 복사한다.
- noneOf(Class elementType) : 비어있는 EnumSet을 반환한다.
- of(E e1, E e2) : 열거형 상수 2개를 입력받아 새로운 EnumSet에 넣어 반환한다.
- complementOf(EnumSet s) : 매개변수에 들어온 EnumSet의 열거형 상수들을 제외한 열거형 상수들을 새로운 EnumSet에 넣어 반환한다.
- range(E from, E to) : 인자로 받은 열거형 상수 사이의 범위를 인덱스 순서대로 새로운 EnumSet에 넣어 반환한다. 단, 앞선 매개변수의 인덱스가 빠르면 런타임 에러가 발생한다.
reference
자바의 정석(남궁성)
[http://alecture.blogspot.com/2012/11/enumset.html]
[https://javabom.tistory.com/50]
[https://www.baeldung.com/java-enumset]
'백기선님과 함께 하는 자바 스터디' 카테고리의 다른 글
12주차 과제: 애노테이션 (0) | 2021.07.12 |
---|---|
[리뷰] 11주차 : Enum (0) | 2021.07.10 |
[리뷰] 10주차 : Critical Path (0) | 2021.07.03 |
10주차 과제: 멀티쓰레드 프로그래밍 (1) | 2021.07.03 |
9주차 과제: 예외 처리 (0) | 2021.06.26 |