Java Enum

Enum

  • JDK 1.5부터 추가
  • Enum은 서로 관련된 상수를 편리하게 선언하기 위한 것으로 상수를 여러 개 정의할 때 사용
  • 여러 상수를 정의한 후, 정의된 것 이외의 값은 허용하지 않는다.
  • 서로 다른 개념끼리 이름 충돌을 없애고 컴파일 단계에서 비교하는 코드를 사용하지 못하게 방지한다.

Enum 정의

  • Enum에 정의된 상수들은 해당 Enum type의 객체이다.
  • 생성자와 메서드를 추가할 수 있다.
  • Enum 생성자의 접근제어자는 private 이기 때문에 외부에서 상수를 추가할 수 없다. 따라서 생성자를 통해
  • 사용자 정의 타입은 switch 문의 조건에 들어갈 수 없지만 Enum은 가능하다.
  • Enum은 equals()가 아닌 ‘==’로 비교가 가능하므로 그만큼 성능에서 이점이 있다.
  public enum Language {
    PYTHON("파이썬"), JAVA("자바"), KOTLIN("코틀린"), C("씨"), JAVASCRIPT("자바스크립트");

    private String name;

    Language(String name) {
      this.name = name;
    }

    public String getName() {
      return this.name;
    }
  }

  public class EnumDemo {
    public static void main(String[] args) throws Exception {
      printTest(Language.JAVA);
      printTest(Language.C);
    }
    private static void printTest(Language language) {
      // TODO Auto-generated method stub
      switch (language) {
      case JAVA:
        System.out.println("자바");
        break;
      case C:
        System.out.println("씨");
        break;
      case JAVASCRIPT:
        System.out.println("자바스크립트");
        break;
      case KOTLIN:
        System.out.println("코틀린");
        break;
      case PYTHON:
        System.out.println("파이썬");
        break;
      default:
        throw new IllegalArgumentException("에러");
      }
    }
  }
자바
씨

Enum 추상메서드

public enum Language {
  PYTHON("파이썬") {
    @Override
    void print() {
      System.out.println("파이썬");
    }
  },
  JAVA("자바") {
    @Override
    void print() {
      System.out.println("자바");
    }
  },
  KOTLIN("코틀린") {
    @Override
    void print() {
      System.out.println("코틀린");
    }
  },
  C("씨") {
    @Override
    void print() {
      System.out.println("씨");
    }
  },
  JAVASCRIPT("자바스크립트") {
    @Override
    void print() {
      System.out.println("자바스크립트");
    }
  };
  private String name;

  Language(String name) {
    this.name = name;
  }

  public String getName() {
    return this.name;
  }
  abstract void print();
}

Enum 클래스로 표현

  public class LanguageClass {

    private String name;

    public LanguageClass(String name) {
      // TODO Auto-generated constructor stub
      this.name = name;
    }
  }
  public static final LanguageClass C = new LanguageClass("씨");
  public static final LanguageClass PYTHON = new LanguageClass("파이썬");
  public static final LanguageClass JAVA = new LanguageClass("자바");
  public static final LanguageClass KOTLIN = new LanguageClass("코틀린");
	

Enum 값 조회

System.out.println(Language.C);
System.out.println(Language.valueOf("C"));
System.out.println(Enum.valueOf(Language.class, "C"));

Enum은 언제?

필요한 원소를 컴파일 타임에 모두 알 수 있는 상수 집합이라면 항상 열거타입을 사용하는 것이 좋다. 열거 타입에 정의된 상수 개수가 영원히 불변일 필요는 없다. 열거타입은 나중에 상수가 추가되더라도 바이너리 수준에서 호환되도록 설계되었다.

Enum 메서드

메서드 설명
values() 해당 enum 타입에 정의된 상수 배열을 반환
getDeclaringClass() 열거형의 객체를 반환
name() 열거형 상수의 이름을 문자열로 반환
ordinal() 열거형 상수가 정의된 순서를 반환
valueOf(Class<T> enumType, String name) 지정된 열거형에서 name과 일치하는 열거형 상수를 반환

values()

  Language.values();
  for(Enum name : Language.values()) {
    System.out.println(name);
  }
PYTHON
JAVA
KOTLIN
C
JAVASCRIPT

ordinal()

  • ordinal()은 EnumSet과 EnumMap 같이 열거 타입 기반의 범용 자료구조에 쓸 목적으로 설계되었다.
  • 개발자가 이 메서드에 의존하는 코드를 작성하는 것은 안티패턴이다.
  for(Enum name : Language.values()) {
    System.out.println(name.ordinal());
  }
0
1
2
3
4

valueOf(Class enumType, String name)

  • 지정된 열거형에서 name과 일치하는 열거형을 반환
  Language c = Enum.valueOf(Language.class, "C");
  Language java = Language.valueOf("JAVA");
  System.out.println(c + "   "+ java);
  
C   JAVA

EnumSet

  • 열거형을 위해 고안된 특별한 Set 인터페이스 구현체
  • HashSet과 비교했을 때 성능상의 이점이 많기 때문에 열거형 데이터를 위한 Set이 필요한 경우 사용된다.
  • EnumSet은 AbstractSet 클래스를 상속하고 Set 인터페이스를 구현한다.
  • 오직 열거형 상수만을 값으로 가질 수 있다. 또한 모든 값은 enum type
  • Null 요소를 허용하지 않는다.
  • ordinal 값의 순서대로 요소가 저장된다.
  • thread-safe 하지 않다. 동기적으로 사용하려면 Collections.synchronizedMap을 사용하거나 외부에서 동기화를 구현
  • 기본 연산의 시간 복잡도는 O(1)
  public abstract class EnumSet<E extends Enum<E>> extends AbstractSet<E>
    implements Cloneable, java.io.Serializable {}
  EnumSet<Language> set1, set2, set3, set4;
	
  set1 = EnumSet.allOf(Language.class);
  set2 = EnumSet.of(Language.C, Language.JAVA, Language.JAVASCRIPT);
  set3 = EnumSet.complementOf(set2);
  set4 = EnumSet.range(Language.PYTHON, Language.KOTLIN);
	
  System.out.println("set1 = " + set1);
  System.out.println("set2 = " + set2);
  System.out.println("set3 = " + set3);
  System.out.println("set4 = " + set4);
set1 = [PYTHON, JAVA, KOTLIN, C, JAVASCRIPT]
set2 = [JAVA, C, JAVASCRIPT]
set3 = [PYTHON, KOTLIN]
set4 = [PYTHON, JAVA, KOTLIN]

EnumMap

  • enum type 키와 함께 사용하기 위한 특수한 Map 구현체
  • enum map의 모든 키는 map이 생성될 때 명시적으로 또는 암시적으로 지정된 단일 열거형 타입을 가져오는데 enum map은 내부적으로 배열로 표시된다.
  • 열거형 상수가 선언된 순서로 키의 순서가 유지된다.
  • Null 요소를 허용하지 않는다.
  • 대부분의 컬렉션 구현과 마찬가지로 EnumMap은 동기화되지 않는다. 여러 쓰레드가 동시에 enum map에 접근하고 쓰레드 중 하나 이상이 map을 수정하는 경우 외부에서 동기화해야한다. 또는 Collections.synchronizedMap(Map<K,V>) 메서드를 사용하여 맵을 래핑하여 실수로 동기화되지 않은 접근을 방지
  public class EnumMap<K extends Enum<K>, V> extends AbstractMap<K, V>
    implements java.io.Serializable, Cloneable {}

Categories:

Updated:

Comments