36. 비트 필드 대신 EnumSet을 사용하라
핵심 요약
열거 타입 상수의 집합을 표현할 때, 과거에 사용되던 비트 필드(Bit Field) 방식 사용했습니다.
현대 자바에서는 EnumSet 을 사용하는 것이 훨씬 안전하고 효율적이며 가독성 높은 방법입니다.
EnumSet은 타입 안전성을 보장하고 비트 필드 수준의 성능을 제공하면서도 사용하기 쉽습니다.
비트 필드
정의
열거한 값들을 주로 집합으로 사용할 경우, 각 상수에 서로 다른 2의 거듭제곱 값을 할당한 정수 열거 패턴을 사용
비트별 OR(
|) 연산을 통해 여러 상수를 하나의 집합(정수 값)으로 표현
예시 코드
특징
비트별 연산(OR, AND 등)을 사용하여 합집합, 교집합 등의 집합 연산을 효율적으로 수행 가능 (과거 관점).
장점
(과거 기준) 비트 연산을 통한 효율적인 집합 연산.
단점
타입 안전성 부재
단순
int값이므로 관련 없는 값을 전달해도 컴파일 오류 미발생
가독성 저하
숫자만으로 스타일 정보 추론?
순회 어려움
집합에 포함된 개별 원소(스타일)를 순회하기 까다로움
확장성 제한
최대 원소 개수를 미리 예측하여
int나long타입을 선택비트 수 확장할 때 API 변경이 필요
오류 가능성
비트 연산은 직접 다루기 까다롭고 오류가 발생 가능성
EnumSet
정의
열거 타입(Enum) 상수들로 구성된 집합을 표현하기 위해 특별히 설계된
Set인터페이스의 고성능 구현체Set 인터페이스를 완벽히 구현, 타입 안전하고, 다른 어떤 Set 구현체와도 함께 사용 가능
비트 필드를 대체하는 현대적이고 우수한 대안
java.util패키지
예시 코드
특징
내부적으로 비트 벡터를 사용하여 데이터를 저장
비트 벡터는 주로 단일
long변수매우 효율적
Set인터페이스를 완벽하게 구현하며, 다른Set구현체와 함께 사용 가능다양한 정적 팩터리 메서드를 제공하여 편리한 인스턴스 생성
EnumSet.of(),EnumSet.allOf(),EnumSet.noneOf()등
장점
타입 안전성
정의된 열거 타입의 상수만 포함
컴파일 시점에 타입 오류를 방지
가독성
코드가 명확, 직관적
출력 예시
[BOLD, ITALIC]
고성능
내부 구현 방식 덕분에 비트 필드에 비견될 만한 성능을 제공
대량 작업도 비트 연산을 활용해 효율적으로 처리
removeAll, retainAll 등
사용 편의성
복잡한 비트 연산 내부 구현
안전하고 편리한 집합 연산 제공
유지보수 용이
열거 타입 상수 추가시
EnumSet코드는 대부분 수정 없이 작동
단점
(과거) 불변
EnumSet을 직접 생성 불가 (Java 9 이전)현재는 해결
핵심 정리 및 부가 정보
핵심 정리
결론적으로, 열거 타입 상수의 집합을 사용할 때는 명료성, 성능, 타입 안전성, 유지보수성 등 모든 면에서 비트 필드 대신
EnumSet을 사용하는 것이 압도적으로 좋습니다.
API 설계 팁:
EnumSet<E>대신Set<E>을 사용하는 것이 더 유연하고 좋은 설계클라이언트가 다른
Set구현체를 사용할 가능성
불변성(Immutability) 처리:
Collections.unmodifiableSet(EnumSet.of(...))Java 9 이전에는 불변
EnumSet을 만드는 표준적인 방법이 없어서 사용원본
EnumSet이 변경되면 같이 변경될 수 있는 '뷰'를 제공할 뿐명확성, 성능 조금 희생
Set.copyOf(enumSet)Java 10 이후 도입
해당
EnumSet의 내용을 복사하여 진정한 불변Set을 생성더 안전하고, 특히
EnumSet의 경우 내부적으로 최적화되어 성능상 이점
Last updated