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; // 8
// 매개변수는 0개 이상의 STYLE_ 상수를 OR 한 값
public void applyStyle(int styles) {
}
}
// OR 연산을 통해 2개의 비트를 하나의 비트로 만들어 집합 전달
text.applyStyles(STYLE_BOLD | STYLE_ITALIC);
비트 필드를 사용하는 이유 ?
n개의 열거값을 저장하기 위해 변수를 사용할때 최소한의 메모리를 사용해서 저장할 수 있다. 열거 변수 타입이 int 인 경우 저장 가능한 상태 값은 32개, long 은 64개 이다.
스타일
연산
비트필드
BOLD + ITALIC
1 | 2 = 3
0011
BOLD + UNDERLINE
1 | 4 = 5
0101
ITALIC + UNDERLINE
2 | 4 = 6
0110
장점
비트 연산을 통해 합집합, 교집합과 같은 집합을 아주 효율적으로 수행할 수 있다.
단점
정수 열거 상수(#34 )의 단점을 그대로 지닌다.
변수 값을 그대로 출려할 경우 해석이 어렵다. 해석을 위해서는 비트 필드로 변환 필요
집합의 순회 연산이 어렵다.
저장 가능한 최대 집합 수는 변수의 최대 크기로 결정 되기 때문에 미리 예측해 적절한 타입으로 설정해야 한다.
EnumSet
우리에겐 java.util.EnumSet 이 있다.
Set 인터페이스 완벽히 구현
타입 안전(type safety)
다른 Set 구현체와 사용 가능
EnumSet 내부는 피트 벡터로 구현
집합 개수가 64 개를 넘지 않는다면 long 형 하나로 표현 가능하기 때문에 비트 필드에 비견되는 성능
비트를 직접 다룰 때 겪는 오류 해방
EnumSet 의 구현이 해당 부분을 이미 구현 해둠
public static class Text {
public enum Style {
BOLD, ITALIC, UNDERLINE, STRIKETHROUGH
}
public void addStyles(Set<Style> styles) {
}
}
text.addStyles(EnumSet.of(Text.Style.BOLD, Text.Style.ITALIC));
addStyles() 메소드가 Set<Style> 을 받는 이유는 세부적인 구현체를 사용해서 제한하기 보다는 인터페이스를 받아 다른 구현체도 받기 위함이다. (#64 )
EnumSet 은 비트 필드 수준의 명료함과 성능을 제공하고 enum 의 장점까지 제공해 준다.
단점은 불변 EnumSet 을 만들 수 없다는 점이 있다. 코드는 약간 복잡해 지지만 아래의 방법으로는 가능하다.
Set<Style> immutableEnumSet = Collections.unmodifiableSet(EnumSet.of(Style.BOLD, Style.UNDERLINE));
// add, remove, clear 등의 수정 발생시 UnsupportedOperationException 발생
한줄 요약
EnumSet
을 사용하자!비트 필드
열거한 값들이 주로 집합으로 사용되는 경우 열거 패턴(#34 )사용해서 표현 가능하다.
장점
단점
정수 열거 상수
(#34 )의 단점을 그대로 지닌다.EnumSet
우리에겐
java.util.EnumSet
이 있다.Set
인터페이스 완벽히 구현Set
구현체와 사용 가능EnumSet
내부는 피트 벡터로 구현64
개를 넘지 않는다면long
형 하나로 표현 가능하기 때문에 비트 필드에 비견되는 성능EnumSet
의 구현이 해당 부분을 이미 구현 해둠addStyles()
메소드가Set<Style>
을 받는 이유는 세부적인 구현체를 사용해서 제한하기 보다는 인터페이스를 받아 다른 구현체도 받기 위함이다. (#64 )EnumSet
은 비트 필드 수준의 명료함과 성능을 제공하고enum
의 장점까지 제공해 준다.EnumSet
을 만들 수 없다는 점이 있다. 코드는 약간 복잡해 지지만 아래의 방법으로는 가능하다.