반응형
728x90
반응형
비트 필드 열거 상수
열거한 값들이 주로 집합으로 사용될 경우 예전에는 각 상수에 서로 다른 2의 거듭제곱 값을 할당한 정수 열거 패턴을 사용해왔다.
오래된 기법
package com.java.effective.item36;
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_STRIKERTHROUGH = 1 << 3; // 8
// 매개변수 styles 는 0개 이상의 STYLE_ 상수를 비트별 OR 한 값이다.
public void applyStyles(int style) {
}
}
아래의 식으로 비트별 OR을 사용해 여러 상수를 하나의 집합으로 모을 수 있으며, 이렇게 만들어진 집합을 비트 필드라 한다.
text.applyStyles(STYLE_BOLD | STYLE_ITALIC);
비트 필드를 사용하면 비트별 연산을 사용해 합집합과 교집합과 같은 집합 연산을 효율적으로 수행할 수 있다. 하지만 비트 필드는 정수 열거 상수의 단점을 그대로 지닌다. 비트 필드 값이 그대로 출력되면 단순한 정수 열거 상수를 출력할 때보다 해석하기 훨씬 어렵다.
비트 필드를 사용해야할때, 사용하려고할때 이를 사용하지 말고 더 나은 방법인 java.util 클래스의 EnumSet 을 사용하자.
EnumSet
EnumSet.java
public abstract class EnumSet<E extends Enum<E>> extends AbstractSet<E>
implements Cloneable, java.io.Serializable
{
...
}
public abstract class AbstractSet<E> extends AbstractCollection<E> implements Set<E> {
...
}
public interface Set<E> extends Collection<E> {
...
}
EnumSet 클래스는 열거 타입 상수의 값으로 구성된 집합을 효과적으로 표현해준다. Set 인터페이스를 완벽히 구현하며, 타입 안전하고, 다른 어떤 Set 구현체와도 함께 사용할 수 있다. 하지만 EnumSet의 내부는 비트 벡터로 되어있어있어, 대부분의 경우에 EnumSet 전체를 long 변수 하나로 표현하여 비트 필드에 비견되는 성능을 보여준다.
package com.java.effective.item36;
import java.util.Set;
public class TextEnumSet {
public enum Style {
BOLD,
ITALIC,
UNDERLINE,
STRIKETHROUGH
}
// 어떤 Set을 넘겨도 되나, EnumSet 이 가장 좋다.
public void applyStyles(Set<Style> styles) {
}
}
클라이언트
text.applyStyles(EnumSet.of(Style.BOLD, Style.ITALIC));
applyStyles 메서드가 EnumSet<Style>이 아닌 Set<Style>을 받은 이유를 생각해보자.
public interface Set<E> extends Collection<E> {
...
}
모든 클라이언트가 EnumSet을 건네리라 짐작되는 상황이라도 이왕이면 인터페이스로 받아서 어떤 Set 구현체를 넘기더라도 처리할 수 있게하자.
반응형
'Book > Effective Java' 카테고리의 다른 글
[교재 EffectiveJava] 아이템 38. 확장할 수 있는 열거 타입이 필요하면 인터페이스를 사용하라 (0) | 2021.11.05 |
---|---|
[교재 EffectiveJava] 아이템 37. ordinal 인덱싱 대신 EnumMap을 사용하라 (0) | 2021.11.05 |
[교재 EffectiveJava] 아이템 35. ordinal 메서드 대신 인스턴스 필드를 사용하라 (0) | 2021.11.05 |
[교재 EffectiveJava] 아이템 34. int 상수 대신 열거 타입을 사용하라 (0) | 2021.11.05 |
[교재 EffectiveJava] 아이템 33. 타입 안전 이종 컨테이너를 고려하라 (0) | 2021.11.04 |