Java EnumSet: 생성, 연산, 성능 팁
Java EnumSet
실전 코드 예제와 모범 사례 통찰로 Java EnumSet 컬렉션 생성, 조작, 최적화를 안내합니다.
EnumSet 클래스는 열거형 타입 전용으로 설계된 고성능 집합 구현체입니다. java.util.Set 인터페이스를 구현하며 Cloneable과 Serializable도 상속받아 다재다능하고 효율적입니다.
EnumSet에 뛰어들기 전에 Java 열거형에 익숙해지세요. 집합은 단일 열거형 타입과 밀접하게 결합되어 있습니다.
EnumSet 생성하기
다른 집합 구현체와 달리 EnumSet은 public 생성자를 노출하지 않습니다. 대신 정적 팩토리 메서드로 집합을 구성합니다.
1. EnumSet.allOf() 사용
allOf() 메서드는 지정된 열거형 타입의 모든 상수를 포함하는 집합을 생성합니다.
import java.util.EnumSet;
class Main {
enum Size { SMALL, MEDIUM, LARGE, EXTRALARGE }
public static void main(String[] args) {
EnumSet<Size> sizes = EnumSet.allOf(Size.class);
System.out.println("EnumSet: " + sizes);
}
}
출력
EnumSet: [SMALL, MEDIUM, LARGE, EXTRALARGE]
2. EnumSet.noneOf() 사용
지정된 열거형 타입의 값만 포함할 수 있는 빈 집합 생성.
import java.util.EnumSet;
class Main {
enum Size { SMALL, MEDIUM, LARGE, EXTRALARGE }
public static void main(String[] args) {
EnumSet<Size> sizes = EnumSet.noneOf(Size.class);
System.out.println("Empty EnumSet: " + sizes);
}
}
출력
Empty EnumSet: []
참고: Size.class로 인스턴스화되었으므로 결과 집합은 Size 상수만 허용합니다.
3. EnumSet.range() 사용
하한에서 상한까지(포함) 모든 열거형 상수를 포함하는 집합 생성.
import java.util.EnumSet;
class Main {
enum Size { SMALL, MEDIUM, LARGE, EXTRALARGE }
public static void main(String[] args) {
EnumSet<Size> sizes = EnumSet.range(Size.MEDIUM, Size.EXTRALARGE);
System.out.println("EnumSet: " + sizes);
}
}
출력
EnumSet: [MEDIUM, LARGE, EXTRALARGE]
4. EnumSet.of() 사용
하나 이상의 특정 열거형 상수를 포함하는 집합 생성.
import java.util.EnumSet;
class Main {
enum Size { SMALL, MEDIUM, LARGE, EXTRALARGE }
public static void main(String[] args) {
EnumSet<Size> sizes1 = EnumSet.of(Size.MEDIUM);
System.out.println("EnumSet1: " + sizes1);
EnumSet<Size> sizes2 = EnumSet.of(Size.SMALL, Size.LARGE);
System.out.println("EnumSet2: " + sizes2);
}
}
출력
EnumSet1: [MEDIUM] EnumSet2: [SMALL, LARGE]
EnumSet 공통 연산
요소 추가
add() – 단일 열거형 상수 삽입
addAll() – 같은 열거형 타입의 다른 컬렉션 병합
import java.util.EnumSet;
class Main {
enum Size { SMALL, MEDIUM, LARGE, EXTRALARGE }
public static void main(String[] args) {
EnumSet<Size> all = EnumSet.allOf(Size.class);
EnumSet<Size> selected = EnumSet.noneOf(Size.class);
selected.add(Size.MEDIUM);
System.out.println("After add(): " + selected);
selected.addAll(all);
System.out.println("After addAll(): " + selected);
}
}
출력
After add(): [MEDIUM] After addAll(): [SMALL, MEDIUM, LARGE, EXTRALARGE]
addAll()은 같은 열거형 타입을 포함하는 한 리스트나 집합 등 모든 Collection<Size>를 허용합니다.
요소 순회
Iterator로 집합 순회:
import java.util.EnumSet;
import java.util.Iterator;
class Main {
enum Size { SMALL, MEDIUM, LARGE, EXTRALARGE }
public static void main(String[] args) {
EnumSet<Size> sizes = EnumSet.allOf(Size.class);
Iterator<Size> it = sizes.iterator();
System.out.print("EnumSet: ");
while (it.hasNext()) {
System.out.print(it.next() + ", ");
}
}
}
출력
EnumSet: SMALL, MEDIUM, LARGE, EXTRALARGE,
요소 제거
remove() – 특정 상수 삭제
removeAll() – 자기 자신 전달 시 집합 비우기
import java.util.EnumSet;
class Main {
enum Size { SMALL, MEDIUM, LARGE, EXTRALARGE }
public static void main(String[] args) {
EnumSet<Size> sizes = EnumSet.allOf(Size.class);
System.out.println("EnumSet: " + sizes);
boolean removed = sizes.remove(Size.MEDIUM);
System.out.println("Is MEDIUM removed? " + removed);
boolean cleared = sizes.removeAll(sizes);
System.out.println("Are all elements removed? " + cleared);
}
}
출력
EnumSet: [SMALL, MEDIUM, LARGE, EXTRALARGE] Is MEDIUM removed? true Are all elements removed? true
추가 헬퍼 메서드
| 메서드 | 설명 |
copyOf() | 같은 요소를 포함하는 새 EnumSet 생성 |
contains() | 특정 상수 존재 여부 확인 |
isEmpty() | 요소 없으면 true 반환 |
size() | 요소 수 반환 |
clear() | 모든 요소 제거 |
Cloneable과 Serializable
EnumSet은 Cloneable을 구현하여 clone()으로 얕은 복사본 생성이 가능합니다. 또한 Serializable을 구현하여 네트워크 전송이나 디스크 지속에 안전합니다.
왜 EnumSet을 사용하는가?
EnumSet은 값을 비트 벡터로 저장하므로 add, remove, contains 연산이 최소 메모리 오버헤드로 상수 시간에 실행됩니다. JVM은 주어진 열거형의 가능한 상수 집합을 정확히 알기 때문에 EnumSet은 HashSet이나 TreeSet 같은 제네릭 구현체보다 훨씬 효율적입니다.
실무에서는 열거형 값의 고성능 집합이 필요할 때마다 EnumSet을 선택하세요.