-
백기선님의 자바스터디를 진행하며 찾아본 내용입니다.
목표
자바의 열거형에 대해 학습하세요.
학습할 것
- enum 정의하는 방법
- enum이 제공하는 메소드 (values()와 valueOf())
- java.lang.Enum
- EnumSet
Enum 정의하는 방법
열거형(Enumeration)은 상수의 집합을 표현하는데 사용되는 기법이다.
자연에서는 행성들, 색깔들, 방향 등등의 자연에서 찾아 볼 수 있는 열거형이 있다.
예를들어 요일을 다음과 같이 Enum으로 표기 할 수 있다.
12345public enum Day {SUNDAY, MONDAY, TUESDAY, WEDNESDAY,THURSDAY, FRIDAY, SATURDAY}cs 이 열거형을 다음과 같이 활용 할 수 있다.
1234567891011121314151617181920212223242526272829303132333435363738public class EnumTest {Day day;public EnumTest(Day day) {this.day = day;}public void tell_it_like_it_is() {switch (day) {case MONDAY:System.out.println("Mondays are bad.");break;case FRIDAY:System.out.println("Friday are better.");break;case SATURDAY: case SUNDAY:System.out.println("Weekend are best.");break;default:System.out.println("Midweek day are so-so =");break;}}public static void main(String[] args) {EnumTest firstDay = new EnumTest(Day.MONDAY);firstDay.tell_it_like_it_is();EnumTest thirdDay = new EnumTest(Day.WEDNESDAY);thirdDay.tell_it_like_it_is();EnumTest fifthDay = new EnumTest(Day.FRIDAY);fifthDay.tell_it_like_it_is();EnumTest sixthDay = new EnumTest(Day.SATURDAY);sixthDay.tell_it_like_it_is();EnumTest seventhDay = new EnumTest(Day.SUNDAY);seventhDay.tell_it_like_it_is();}}cs * 자바에서는 C/C++과 다르게 Enum 객체에 메소드나 생성자를 추가해 줄 수 있다.
* 모든 ENUM은 암시적으로 public static final 타입으로 선언된다.
ENUM이 제공하는 메소드(value(), valueOf())
1. values()
enum 내부의 모든 값을 리턴해준다.
내부에 정의 되어 있는 부분을 찾아보려 했더니 없어서 구글링 해보니 컴파일러가 '암시적'으로 메소드를 정의한다고 한다.
stackoverflow.com/questions/13659217/where-is-the-documentation-for-the-values-method-of-enum
다음과 같이 for-each문과 함께 자주 쓰인다고 한다.
123456789101112enum Color {RED, GREEN, BLUE;}public class EnumTest2 {public static void main(String[] args) {for (Color c : Color.values()) {System.out.printf("COLOR LIST : " + c + "\n");}}}cs Output:
2. valueOf()
string value로 명시화된 enum 상수가 존재한다면 상수를 리턴한다
* Enum 상수가 주어진 String에 해당하는 상수를 가지고 있지 않는다면 IllegalArgumentException이 발생한다.
3. ordinal()
ordinal 메소드를 통해 Enum 상수 인덱스를 찾을 수 있다
EnumSet이나 EnumMap과 같은 enum-based data structure에서 사용되기 위해 설계되어졌다.
3-1. value(), valueOf(), ordinal() Example
1234567891011121314151617181920212223// Java program to demonstrate working of values(),// ordinal() and valueOf()enum Color {RED, GREEN, BLUE;}public class EnumTest3 {public static void main(String[] args) {// Calling values()Color arr[] = Color.values();// enum with loopfor(Color col : arr) {// Calling ordinal to find index of colorSystem.out.println(col + " at index " + col.ordinal());}// Using ValueOf(). Return an object of Color with given constant.System.out.println(Color.valueOf("GREEN"));}}cs Output:
4. name()
public final String name()
enum 상수의 이름을 리턴한다. 이 메소드는 정확한 이름을 얻어야 하는 특수 상황에서 사용되는 것을 전제하고 설계되었기 때문에, 대부분의 상황에서 toString() 메소드를 쓰는 것이 권장되어진다.
5. toString()
public String toString()
선언에 포함되어 있는 enum 상수의 이름을 리턴한다.
6. equal()
public final boolean equals(Object other)
enum 상수와 인자로 주어진 object가 같다면 true를 리턴한다
7. compareTo()
public final int compareTo(E o)
동일한 Enum class의 상수의 값과 순서를 비교한다.
만약 매개변수의 값이 더 크다면 '음수'를
매개변수의 값과 같다면 '0'을
매개변수의 값보다 크다면 '양수'를 리턴한다
java.lang.Enum
모든 enum 클래스는 java.lang.Enum을 상속한다.
생성자 protected Enum(String name, int ordinal)이 있으나, 프로그래머가 호출 할 수는 없고
컴파일러가 enum 타입의 선언을 처리 할 때 사용되어진다.
EnumSet
열거형 타입을 사용한 Set Interface의 구현
다음과 같은 특징들이 있다.
- AbstractSet을 extend하고 Set Interface를 Implements한다.
- Java Collection Framework의 멤버이며 동기화되지 않는다.
- HashSet보다 빠른 구현방법이다.
- EnumSet의 모든 원소는 단일 열거 유형(single Enumeration type)에서 가져와야한다.
- nullObject는 허용되지 않고, 만약 들어갈경우 NullPointerException을 Throw한다.
EnumSet의 계급도
java.lang.Object
↳ java.util.AbstractCollection<E>
↳ java.util.AbstractSet<E>
↳ java.util.EnumSet<E>
Declaration:
public abstract class EnumSet<E extends Enum<E>>
여기서 E는 반드시 Enum을 상속받아야 한다.
1234567891011121314151617181920212223// Java program to illustrate working of EnumSet and its functions.import java.util.EnumSet;enum Gfg { CODE, LEARN, CONTRIBUTE, QUIZ, MCQ };public class EnumSetExample {public static void main(String[] args) {// creating a setEnumSet<Gfg> set1, set2, set3, set4;// Adding elementsset1 = EnumSet.of(Gfg.QUIZ, Gfg.CONTRIBUTE, Gfg.LEARN, Gfg.CODE);set2 = EnumSet.complementOf(set1);set3 = EnumSet.allOf(Gfg.class);set4 = EnumSet.range(Gfg.CODE, Gfg.CONTRIBUTE);System.out.println("Set 1: " + set1);System.out.println("Set 2: " + set2);System.out.println("Set 3: " + set3);System.out.println("Set 4: " + set4);}}cs Output:
Enum set은 추상클래스이기 때문에 바로 인스턴스화 할 수 없다. 이를 implement한 클래스가 필요한데
JDK에서는 RegularEnumSet과 JumboEnumSet을 지원하고 있다
RegularEnumSet은 long 타입의 Object로써 8바이트의 크기 즉 64비트의 크기를 가진다. 그에따라 64개의 다른 요소들을 저장 할 수 있다.
JumboEnumSet은 EnumSet의 요소를 저장하기 위해 long의 배열을 사용한다. 따라서 64개의 값보다 더 많은 값을 저장 할 수 있다.
EnumSet은 public constructor를 지원하지 않고 정적 팩토리 메소드를 통해서만 인스턴스를 생성할 수 있다.
정적 팩토리 메소드는 다음과 같다
allOf(size)
elementType에 주어진 모든 값을 포함하는 enum set을 만드는 메소드
Definition
public static <E extends Enum<E>> EnumSet<E> allOf(Class<E> elementType);
Return Value
어떠한 값도 리턴하지 않는다.
Exception
elementType이 Null일 경우 NullPointerException을 반환한다
noneOf(size)
elementType의 자료형을 가진 null set을 만들어내는 메소드
Definition
public static <E extends Enum<E>> EnumSet<E> noneOf(Class<E> elementType)
Return Value
어떠한 값도 리턴하지 않는다
Exception
elementType이 Null일 경우 NullPointerExcetpion을 반환한다.
range(e1, e2)
파라미터로 주어진 특정한 범위 안의 요소들을 통해 enum set을 만드는 메소드
Syntax
Enum_set = EnumSet.range(E start_point, E end_point)
Return Value
인자로 주어진 범위내의 요소들을 토대로 만들어진 enum set을 반환한다.
Exception
NullPointer Exception - start_point나 end_point가 Null일 경우
IllegalArgumentException - 첫번째 요소가 두번째 요소보다 더 클 경우
of()
특정 임의의 요소를 선택하여 Enum set을 만들 때 사용되는 메소드
Syntax
Enum_set = EnumSet.of(E ele1, E ele2, E ele3, ...)
Return Values
인수로 주어진 요소들을 통해 초기화 되어진 enum set
Exception:
NullPointerException - 인수로 주어진 것 중 NULL이 있을 경우
1. 요소 추가하기
위의 메소드를 통해 Enumset을 생성한 후에 .add() 메소드나 .addAll() 메소드를 사용해 인자를 추가 할 수 있다.
Enum set에 요소 추가 Example)
123456789101112131415161718192021222324252627// Java program to add elements to an Enumsetimport java.util.EnumSet;public class EnumSetExample {enum Game { CRICKET, HOCKEY, TENNIS };public static void main(String[] args) {// Creating an EnumSet using allOf()EnumSet<Game> games1 = EnumSet.allOf(Game.class);// Creating an EnumSet using noneOf()EnumSet<Game> games2 = EnumSet.noneOf(Game.class);// Using add methodgames2.add(Game.HOCKEY);// printing the elements to the consoleSystem.out.println("EnumSet Using add(): " + games2);// Using addAll() methodgames2.addAll(games1);// printing the elements to the consoleSystem.out.println("EnumSet Using addAll(): " + games2);}}cs Output:
2. 요소 접근하기
인자 접근은 iterator() 메소드를 통해 할 수 있다.
access to enum set Example)
12345678910111213141516171819202122232425// Java program to access the elements of EnumSetimport java.util.EnumSet;import java.util.Iterator;public class AccessingElementsOfEnumSet {enum Game { CRICKET, HOCKEY, TENNIS };public static void main(String[] args) {// Creating an EnumSet using allOf()EnumSet<Game> games = EnumSet.allOf(Game.class);// create an Iterator on gamesIterator<Game> iterate = games.iterator();// Iterate and print elements to the consoleSystem.out.print("EnumSet: ");while(iterate.hasNext()) {System.out.print(iterate.next());System.out.print(", ");}}}cs Output:
3. 요소 제거하기
remove 메소드나 removeAll() 메소드를 사용해 요소들을 지울 수 있다.
remove element of Enumset Example)
12345678910111213141516171819202122232425// Java program to remove elements from EnumSetimport java.util.EnumSet;public class RemovingElementsOfEnumSet {enum Game { CRICKET, HOCKEY, TENNIS }public static void main(String args[]) {// Creating EnumSet using allOf()EnumSet<Game> games = EnumSet.allOf(Game.class);System.out.println("EnumSet: " + games);// Using remove()boolean value1 = games.remove(Game.CRICKET);// printing elements to the consoleSystem.out.println("IS CRICKET removed? " + value1);// Using removeAll()boolean value2 = games.removeAll(games);// printing elements to the consoleSystem.out.println("Are all elements removed? " + value2);}}cs Output:
Reference
docs.oracle.com/javase/tutorial/java/javaOO/enum.html
docs.oracle.com/javase/8/docs/api/
www.geeksforgeeks.org/enumset-class-java/
'자바 스터디' 카테고리의 다른 글
Annotation (0) 2021.03.01 멀티쓰레드 프로그래밍 (0) 2021.02.02 예외 처리 (0) 2021.01.30 인터페이스 (0) 2021.01.28 패키지 (0) 2021.01.22