Closed zpqmdh closed 1 month ago
Q.
비트 벡터라는 개념이 생소해서 그런데, 비트 벡터의 간단한 개념과 비트 필드와의 차이점을 설명해주실 수 있나요? 추가로 EnumSet 의 내부가 어떻게 구현되어 있는지도 궁금합니다 !
A.
중복되지 않은 수들을 비트로 나타내는 방식을 비트 벡터라고 정의해놓고 있는데 책에서 서술한 내용을 보면 정수 열거 패턴에서 중복되지 않은 수들을 비트로 나타내는 방식을 사용하고 있습니다.
public class Text {
public static final int STYLE_BOLD = 1 << 0;
public static final int STYLE_ITALIC = 1 << 1;
public static final int STYLE_UNDERLINE = 1 << 2;
public static final int STYLE_STRIKETHROUGH = 1 << 3;
public void apply(int styles) {
...
}
}
public class Client { public static void main(String[] args) { Text text = new Text();
text.apply(Text.STYLE_BOLD | Text.STYLE_ITALIC);
}
}
- 책에서는 이 방식을 비트 필드라고 하고 있으므로 전체적으로 보았을 때 비트 벡터와 비트 필드는 동의어라고 간주할 수 있습니다.
- `EnumSet`은 두 가지의 구현체로 나뉘는데 하나는 `RegularEnumSet`과 다른 하나는 `JumboEnumSet`이 있습니다.
- `EnumSet`은 자신이 가지는 원소의 수를 사용하여 어떤 구현체를 사용할지 결정합니다. 만약 원소가 64개 이하라면 `RegularEnumSet`을 사용하고 64개를 초과하면 `JumboEnumSet`을 사용합니다.
- 64개가 기준인 이유는 내부 구현으로 Bit Field를 사용하기 때문인데 하나의 정수 타입으로 나타낼 수 있는 최대 원소의 개수가 64개이기 때문입니다.(1비트에 하나의 원소를 나타낸다고 한다면 `long`은 64비트이기 때문에 64개가 되겠죠?)
- `RegularEnumSet`은 64개 이하의 원소에 대해 집합을 표현합니다. 따라서 `long` 타입 변수 하나를 사용하여 데이터를 저장하게 되며 이때 `ordinal`이 사용될 수 있습니다. 코드로 표현하면 대략적으로 다음과 같습니다.
```java
public boolean add(E e) {
typeCheck(e);
long oldElements = elements;
elements |= (1L << ((Enum<?>)e).ordinal());
return elements != oldElements;
}
ordinal
이 사용되는 것을 확인할 수 있습니다.JumboEnumSet
은 조금 다른데요 64개를 초과하기 때문에 long
변수 하나가 아닌 long
배열을 사용합니다. 이 때에도 ordinal
이 사용되는데 바로 비트 연산을 수행하는 것이 아닌 offset
을 계산하여 비트 연산을 수행한다는 차이가 있습니다.
책 224페이지에는
라고 언급하고 있습니다.
비트 벡터라는 개념이 생소해서 그런데, 비트 벡터의 간단한 개념과 비트 필드와의 차이점을 설명해주실 수 있나요? 추가로
EnumSet
의 내부가 어떻게 구현되어 있는지도 궁금합니다 !