Java/Java Concept

[Java] EnumSet에 대해서

SeungbeomKim 2023. 11. 13. 17:59
반응형

캡스톤디자인2 Allercheck 프로젝트에서 핵심 기능을 구현하기 위해 EnumSet을 활용하였습니다. 

 

핵심 기능의 일부를 위해 EnumSet을 적용하였는데, 간략하게 설명드리자면 데이터베이스에 음식에 관한 알러지 정보를 저장하기 위해 사용하였습니다. JPA에서는 EnumSet 자료 구조에 JSON 직렬화, 역직렬화를 제공하지 않아 직접 이 기능을 구현해야 하는 번거로움이 있었습니다. 이제 EnumSet이 무엇이고 왜 사용하는지에 대해 설명드리겠습니다.

 

EnumSet

  • EnumSet은 Enum 클래스와 함께 작동하는 특수한 Set Collection입니다.
  • Set 인터페이스를 구현하고 AbstractSet에서 확장됩니다.
  • 인스턴스를 생성할 수 있는 여러 정적 팩토리 메서드가 포함된 추상 클래스입니다.

EnumSet-Image
EnumSet의 인터페이스 및 세부 구조

 

  • AbstractSet 및 AbstractCollection은 Set 및 Collection Interface의 거의 모든 메서드에 대한 구현을 제공하지만, EnumSet은 대부분을 재정의합니다.

 

EnumSet을 사용할 때의 고려사항

  1. 열거형 값만을 포함할 수 있으며 모든 값은 동일한 열거형에 속해야 합니다.
  2. null 값을 추가하는 것을 허용하지 않으며, 만약 null 값을 추가할 시 NullPointerException이 발생합니다.
  3. Thread로부터 안전하지 않으므로 필요한 경우, 외부에서 동기화해야 합니다.
  4. 요소는 열거형에 선언된 순서에 따라 지정됩니다.
  5. 복사본에서 작동하는 안전한 반복자를 사용하므로 컬렉션을 반복할 때, 컬렉션이 수정되면 ConcurrentModificationException이 발생하지 않습니다.

2가지 구현 

if (universe.length <= 64)
    return new RegularEnumSet<>(elementType, universe);
else
    return new JumboEnumSet<>(elementType, universe);
  • RegularEnumSet: 단일 long을 사용하여 비트 벡터를 나타내기에, long 요소의 각 비트를 Enum의 값으로 나타냅니다. -> 열거형의 i번째 값은 i번째 비트에 저장되므로 값이 있는지의 여부를 아는 것은 매우 쉽습니다 (long:64bit)
  • JumboEnumSet: 긴 요소의 배열을 비트벡터로 사용하고, 이를 통해 64개 이상의 요소를 저장할 수 있습니다.

 

EnumSet의 이점

  • EnumSet의 모든 메서드는 산술 비트 단위 연산을 사용하여 구현하기에 시간복잡도가 매우 우수합니다.
  • 올바른 버킷을 찾기 위해 Hashcode를 계산할 필요도 없으며, 비트 벡터를 사용하기에 메모리 효율도 뛰어납니다.

 

EnumSet의 사용 방법

  • EnumSet의 메서드 대부분은 인스턴스를 생성하는 메서드를 제외하고 다른 Set처럼 작동합니다.

 

사용 예시

public enum Color {
    RED, YELLOW, GREEN, BLUE, BLACK, WHITE
}

EnumSet.allOf(Color.class); 

EnumSet.noneOf(Color.class); 

EnumSet.range(Color.YELLOW, Color.BLUE);
// [YELLOW, GREEN, BLUE]

EnumSet.complementOf(EnumSet.of(Color.BLACK, Color.WHITE)
// [RED, YELLOW, GREEN, BLUE]

EnumSet.copyOf(EnumSet.of(Color.BLACK, Color.WHITE));
// [BLACK, WHITE]

// 기타 작업 (빈 EnumSet을 만들고 일부 요소 추가 및 제거)
EnumSet<Color> set = EnumSet.noneOf(Color.class);
set.add(Color.RED);
set.add(Color.YELLOW);
set.forEach(System.out::println);
set.remove(System.out::println);
  • EnumSet.allOf(Color.class): Color class의 모든 요소를 포함하여 EnumSet Collection을 생성해 주는 메서드
  • EnumSet.noneOf(Color.class): 빈 Collection을 생성해주는 메서드
  • EnumSet.range(Color.YELLOW, Color.BLUE): 특정 범위까지만 만들 수 있는 메서드
  • EnumSet.complementOf(EnumSet.of(Color.BLACK, Color.WHITE): 매개변수로 들어온 값들을 제외해 주는 메서드
  • EnumSet.copyOf(EnumSet.of(Color.BLACK, Color.WHITE): EnumSet의 모든 요소를 복사하여 EnumSet Collection을 생성해 주는 메서드

 

<참고 자료>

https://www.baeldung.com/java-enumset

 

반응형