EnumSet은 Java의 특수한 컬렉션 클래스로, enum 타입의 요소들을 효율적으로 저장하고 처리할 수 있습니다⁷. EnumSet은 내부적으로 비트 벡터를 사용하여 enum 요소들을 관리합니다⁶. 비트 벡터는 long 타입의 변수로 구현되는데, long 타입은 64비트를 가집니다. 따라서 64개 이하의 enum 요소들을 저장할 수 있습니다.
EnumSet은 정적 팩토리 메서드를 통해 인스턴스를 생성할 수 있습니다. 그 중에는 of 메서드가 있는데, 이 메서드는 enum 요소들을 직접 매개변수로 전달하여 EnumSet을 만듭니다⁵. 예를 들어,
EnumSet<DayOfWeek> weekend = EnumSet.of(DayOfWeek.SATURDAY, DayOfWeek.SUNDAY);
이 코드는 DayOfWeek이라는 enum 타입에서 토요일과 일요일만 포함하는 EnumSet을 생성합니다.
그런데 of 메서드에는 다섯 개까지의 매개변수를 받는 오버로딩된 버전이 있습니다. 왜 다섯 개인지 궁금하신가요? 그 이유는 성능과 관련이 있습니다. 만약 가변 매개변수를 사용한다면, 매개변수로 전달된 enum 요소들을 배열로 변환해야 합니다. 배열 변환은 시간과 공간적인 비용이 듭니다. 하지만 다섯 개 이하의 매개변수라면 배열 변환 없이도 각각의 매개변수를 처리할 수 있습니다.
실제로 EnumSet 클래스의 소스 코드⁵를 보면,
public static <E extends Enum<E>> EnumSet<E> of(E e1) {
...
}
public static <E extends Enum<E>> EnumSet<E> of(E e1, E e2) {
...
}
public static <E extends Enum<E>> EnumSet<E> of(E e1, E e2, E e3) {
...
}
public static <E extends Enum<E>> EnumSet<E> of(E e1, E e2, E e3, E e4) {
...
}
public static <E extends Enum<E>> EnumSet<E> of(E first, E... rest) {
...
}
위와 같이 다섯 개까지 오버로딩된 버전이 존재하고 마지막에 가변 매개변수 버전이 있는 것을 확인할 수 있습니다.
결론적으로 Java에서는 성능 최적화를 위해 다섯 개까지 오버로딩된 버전을 제공하고 그 이상은 가변 매개변수 버전을 사용하는 것입니다.