EnumSet
은 enum 클래스로 동작하는 특수한 Set 컬렉션으로 대부분의 메서드를 재정의한다.
NullPointerException
이 발생한다.ConcurrentModificationException
이 발생하지 않는다.enum 값을 저장할 때 다른 Set 구현체보다 EnumSet
을 우선시해야 한다.
1) 구현 세부사항
EnumSet
은 인스턴스를 생성 할 수있는 여러 정적 팩토리 메소드를 포함하는 추상 클래스다.RegularEnumSet
과 JumboEnumSet
을 제공한다.
EnumSet
팩토리 메소드는 enum 의 요소 수에 맞는 구현체로 인스턴스를 생성한다.
(컬렉션에 저장 될 요소의 개수가 아니라 enum 클래스 요소의 수로 결정한다.)public static <E extends Enum<E>> EnumSet<E> noneOf(Class<E> elementType) {
Enum<?>[] universe = getUniverse(elementType);
if (universe == null)
throw new ClassCastException(elementType + " not an enum");
if (universe.length <= 64)
return new RegularEnumSet<>(elementType, universe);
else
return new JumboEnumSet<>(elementType, universe);
}
2) 장점
EnumSet
의 모든 메서드는 산술 비트 연산을 사용하여 구현되므로 연산 속도가 매우 빨라 상수 시간내에 실행된다.EnumSet
을 다른 Set 구현체와 비교하면 값이 예측 가능한 순서로 저장되고 각 계산마다 1비트만 검사하면 되기때문에 일반적으로 더 빠르다. HashSet과 달리 버킷을 찾기 위해 해시 코드를 계산할 필요가 없다.EnumSet
은 매우 작고 효율적이므로 메모리를 적게 사용하면서 모든 이점을 얻을 수 있다.
public enum DayOfWeek {
MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY;
}
// 비어있는 생성자
// :
EnumSet<DayOfWeek> none = EnumSet.noneOf(DayOfWeek.class);
// 모든 요소를 지닌 생성자
// : MONDAY TUESDAY WEDNESDAY THURSDAY FRIDAY SATURDAY SUNDAY
EnumSet<DayOfWeek> everyday = EnumSet.allOf(DayOfWeek.class);
// 특정 요소로만 이루어진 생성자
// : SATURDAY SUNDAY
EnumSet<DayOfWeek> weekend = EnumSet.Of(DayOfWeek.SATURDAY, DayOfWeek.SUNDAY);
// 모든 요소 중에 전달받은 요소들을 제외한 생성자
// : MONDAY TUESDAY WEDNESDAY THURSDAY FRIDAY
EnumSet<DayOfWeek> weekday = EnumSet.complementOf(weekend);
// enum에 선언된 순서의 범위로 이루어진 생성자
// : MONDAY TUESDAY WEDNESDAY THURSDAY FRIDAY
EnumSet<DayOfWeek> weekday = EnumSet.range(DayOfWeek.MONDAY, DayOfWeek.FRIDAY);
// 포함
assertThat(weekday.contains(DayOfWeek.WEDNESDAY)).isTrue();
assertThat(weekday.contains(DayOfWeek.SUNDAY)).isFalse();
// 추가
weekday.add(DayOfWeek.SUNDAY);
assertThat(weekday.contains(DayOfWeek.SUNDAY)).isTrue();
// 삭제
weekday.remove(DayOfWeek.WEDNESDAY);
assertThat(weekday.contains(DayOfWeek.WEDNESDAY)).isFalse();
// 복사
List<DayOfWeek> list = new ArrayList<>();
list.add(DayOfWeek.SATURDAY);
list.add(DayOfWeek.SUNDAY);
EnumSet<DayOfWeek> listCopy = EnumSet.copyOf(list);
assertThat(listCopy.containsAll(weekend)).isTrue();