도당탕탕
Item36 : bit 필드 대신 EnumSet을 사용하라. 본문
다음은 비트 필드는 enum 타입에 집합연산을 사용할 때 주로 사용한다.
public class Text{
public static final int STYLE_BOLD = 1 << 0; // 1
public static final int STYLE_ITALIC = 1 << 1; // 2
public static final int STYLE_UNDERLINE = 1 << 2; // 4
public static final int STYLE_STRIKETHROUGH = 1 << 3; // 5
public void applyStyle(int styles){...}
}
text.applySyles(STYLE_BOLD | STYLE_ITALIC)
처럼 OR연산을 사용할 수 있고 AND 연산 또한 사용할 수 있다.
위 방법의 문제점은 아래와 같다.
- 비트 필드를 해석하는 것이 어렵다.
- 비트필드가 나타내는 각각의 요소들을 루프로 순회하기 어렵다.
- 필요한 비트수를 예상해야 한다. 그리고 32 or 64 비트 자릿수를 넘어서는 안된다.
EnumSet
위 문제를 해결하기 위해서 EnumSet을 사용할 수 있다. 내부적으로 EnumSet은 비트 벡터로 구현이 되어있다. 그리고 64개 이하의 enum type을 저장할 수 있다. 전체 EnumSet은 하나의 long 값으로 표현될 수 있으므로, 성능이 비트 필드만큼 우수하다.
removeAll
, retainAll
과 같은 bulk 작업들은 bitwise 계산을 사용해서 구현되어 있다. 따라서 사용자가 이러한 기능을 직접 구현할 필요가 없다.
public class Text {
public enum Style {BOLD, ITALIC, UNDERLINE, STRIKETHROUGH}
public void applyStyles(Set<Style> styles) {
System.out.printf("Applying styles %s to text%n",
Objects.requireNonNull(styles));
}
public static void main(String[] args) {
Text text = new Text();
text.applyStyles(EnumSet.of(Style.BOLD, Style.ITALIC));
}
}
정리
enum type에 집합연산을 사용할 때는 비트필드 대신, EnumSet을 사용하라. EnumSet은 타입안전성과 비트 필드의 성능 두 가지 장점 모두 가지고 있다.
'JAVA' 카테고리의 다른 글
Item38 : 인터페이스를 사용해서 확장성있는 ENUM을 재현하라. (0) | 2022.12.29 |
---|---|
Item37: ordinal 인덱싱 대신 EnumMap을 사용하라 (0) | 2022.12.29 |
Item35 : ordinal 메서드 대신 인스턴스 필드를 사용하라 (0) | 2022.12.28 |
Item34 : INT 상수 대신 ENUM을 사용하라. (0) | 2022.12.27 |
Item33 : 타입 안전 이종 컨테이너를 고려하라 (2) | 2022.12.27 |
Comments