add user agent parser and update build configuration
This commit is contained in:
536
docs/BitSet.md
Normal file
536
docs/BitSet.md
Normal file
@@ -0,0 +1,536 @@
|
||||
# **BitSet 클래스란?**
|
||||
|
||||
`BitSet`은 **비트(bit) 단위의 데이터를 효율적으로 저장하고 조작할 수 있도록 설계된 클래스**이다.
|
||||
기본적인 `boolean[]` 배열과 유사하지만, **각 요소를 1비트로 저장**하기 때문에 **메모리를 훨씬 적게 사용**한다.
|
||||
|
||||
이 클래스는 **대량의 불리언 데이터를 다룰 때** 유용하며, **비트 연산을 활용하는 알고리즘**(예: 비트마스크, 소수 판별, 집합 연산 등)에서도 사용된다.
|
||||
|
||||
---
|
||||
|
||||
## **1. BitSet의 주요 특징**
|
||||
✔ **1비트 단위로 저장** → `boolean[]`보다 메모리 절약
|
||||
✔ **자동 확장 가능** → 크기를 명시할 필요 없음
|
||||
✔ **비트 연산 지원** → AND, OR, XOR 등 논리 연산 가능
|
||||
✔ **빠른 검색** → 특정 비트의 ON/OFF를 빠르게 확인 가능
|
||||
|
||||
---
|
||||
|
||||
## **2. BitSet의 주요 메서드 정리**
|
||||
|
||||
| 메서드 | 설명 |
|
||||
|--------|------|
|
||||
| `BitSet()` | 빈 `BitSet` 생성 (기본 크기 64비트) |
|
||||
| `BitSet(int nbits)` | 최소 `nbits` 크기의 `BitSet` 생성 |
|
||||
| `set(int index)` | 특정 위치의 비트를 `1(true)`로 설정 |
|
||||
| `set(int fromIndex, int toIndex)` | 특정 범위의 비트를 `1(true)`로 설정 |
|
||||
| `clear(int index)` | 특정 위치의 비트를 `0(false)`로 설정 |
|
||||
| `clear(int fromIndex, int toIndex)` | 특정 범위의 비트를 `0(false)`로 설정 |
|
||||
| `flip(int index)` | 특정 위치의 비트를 반전 |
|
||||
| `flip(int fromIndex, int toIndex)` | 특정 범위의 비트를 반전 |
|
||||
| `get(int index)` | 특정 위치의 비트 값을 반환 (`true/false`) |
|
||||
| `get(int fromIndex, int toIndex)` | 특정 범위의 비트 값을 `BitSet`으로 반환 |
|
||||
| `and(BitSet set)` | AND 연산 수행 |
|
||||
| `or(BitSet set)` | OR 연산 수행 |
|
||||
| `xor(BitSet set)` | XOR 연산 수행 |
|
||||
| `cardinality()` | `1(true)`로 설정된 비트의 개수 반환 |
|
||||
| `length()` | 가장 높은 `1(true)` 비트의 인덱스 + 1 반환 |
|
||||
| `size()` | 내부 비트 배열의 전체 크기 반환 |
|
||||
| `isEmpty()` | 모든 비트가 `0(false)`인지 확인 |
|
||||
| `nextSetBit(int index)` | `index` 이후 첫 번째 `1(true)` 비트의 위치 반환 |
|
||||
| `nextClearBit(int index)` | `index` 이후 첫 번째 `0(false)` 비트의 위치 반환 |
|
||||
|
||||
---
|
||||
|
||||
## **3. BitSet 사용 예제**
|
||||
|
||||
### **(1) 기본적인 비트 설정 및 조회**
|
||||
```java
|
||||
import java.util.BitSet;
|
||||
|
||||
public class BitSetExample {
|
||||
public static void main(String[] args) {
|
||||
BitSet bitSet = new BitSet(); // 기본 크기 64비트
|
||||
|
||||
bitSet.set(0); // 0번째 비트 ON
|
||||
bitSet.set(2); // 2번째 비트 ON
|
||||
bitSet.set(4); // 4번째 비트 ON
|
||||
|
||||
System.out.println("BitSet: " + bitSet); // {0, 2, 4}
|
||||
|
||||
// 특정 비트 확인
|
||||
System.out.println("0번째 비트: " + bitSet.get(0)); // true
|
||||
System.out.println("1번째 비트: " + bitSet.get(1)); // false
|
||||
}
|
||||
}
|
||||
```
|
||||
✔ `BitSet`을 출력하면 **1(true)인 비트의 위치만 표시**된다.
|
||||
|
||||
---
|
||||
|
||||
### **(2) `flip()`을 활용한 비트 반전**
|
||||
```java
|
||||
import java.util.BitSet;
|
||||
|
||||
public class BitSetFlipExample {
|
||||
public static void main(String[] args) {
|
||||
BitSet bitSet = new BitSet();
|
||||
bitSet.set(1);
|
||||
bitSet.set(3);
|
||||
bitSet.set(5);
|
||||
System.out.println("초기 BitSet: " + bitSet); // {1, 3, 5}
|
||||
|
||||
bitSet.flip(0, 6); // 0~5까지 비트 반전
|
||||
System.out.println("flip(0,6) 후: " + bitSet); // {0, 2, 4}
|
||||
}
|
||||
}
|
||||
```
|
||||
✔ `flip()`을 사용하면 **지정된 범위의 비트가 반전**된다.
|
||||
|
||||
---
|
||||
|
||||
### **(3) 비트 연산 (AND, OR, XOR)**
|
||||
```java
|
||||
import java.util.BitSet;
|
||||
|
||||
public class BitSetOperations {
|
||||
public static void main(String[] args) {
|
||||
BitSet set1 = new BitSet();
|
||||
BitSet set2 = new BitSet();
|
||||
|
||||
set1.set(0);
|
||||
set1.set(1);
|
||||
set1.set(2);
|
||||
System.out.println("Set1: " + set1); // {0, 1, 2}
|
||||
|
||||
set2.set(1);
|
||||
set2.set(2);
|
||||
set2.set(3);
|
||||
System.out.println("Set2: " + set2); // {1, 2, 3}
|
||||
|
||||
BitSet andSet = (BitSet) set1.clone();
|
||||
andSet.and(set2);
|
||||
System.out.println("AND 연산: " + andSet); // {1, 2}
|
||||
|
||||
BitSet orSet = (BitSet) set1.clone();
|
||||
orSet.or(set2);
|
||||
System.out.println("OR 연산: " + orSet); // {0, 1, 2, 3}
|
||||
|
||||
BitSet xorSet = (BitSet) set1.clone();
|
||||
xorSet.xor(set2);
|
||||
System.out.println("XOR 연산: " + xorSet); // {0, 3}
|
||||
}
|
||||
}
|
||||
```
|
||||
✔ **AND 연산:** `1(true)`인 비트만 유지
|
||||
✔ **OR 연산:** 하나라도 `1(true)`이면 유지
|
||||
✔ **XOR 연산:** `1(true)`가 서로 다르면 유지
|
||||
|
||||
---
|
||||
|
||||
### **(4) `cardinality()`, `nextSetBit()`, `nextClearBit()` 활용**
|
||||
```java
|
||||
import java.util.BitSet;
|
||||
|
||||
public class BitSetMethods {
|
||||
public static void main(String[] args) {
|
||||
BitSet bitSet = new BitSet();
|
||||
bitSet.set(1);
|
||||
bitSet.set(3);
|
||||
bitSet.set(5);
|
||||
|
||||
System.out.println("BitSet: " + bitSet); // {1, 3, 5}
|
||||
System.out.println("1의 개수: " + bitSet.cardinality()); // 3
|
||||
|
||||
System.out.println("다음 1(true) 비트 위치: " + bitSet.nextSetBit(0)); // 1
|
||||
System.out.println("다음 0(false) 비트 위치: " + bitSet.nextClearBit(0)); // 0
|
||||
}
|
||||
}
|
||||
```
|
||||
✔ `cardinality()`는 `1(true)`의 개수를 반환
|
||||
✔ `nextSetBit()`는 **다음 `1(true)`인 비트 위치** 반환
|
||||
✔ `nextClearBit()`는 **다음 `0(false)`인 비트 위치** 반환
|
||||
|
||||
---
|
||||
|
||||
## **4. BitSet vs. boolean 배열**
|
||||
| 비교 항목 | `BitSet` | `boolean[]` |
|
||||
|----------|---------|------------|
|
||||
| 메모리 사용 | **1비트(압축됨)** | 1바이트(8배 큼) |
|
||||
| 크기 조정 | **자동 확장** | **고정 크기** |
|
||||
| 비트 연산 | AND, OR, XOR 지원 | 직접 구현 필요 |
|
||||
| 성능 | 비트 연산이 빠름 | 단순한 경우 유리 |
|
||||
|
||||
✔ `BitSet`은 **메모리를 절약하면서도 대량의 비트 연산을 효율적으로 수행**할 수 있다.
|
||||
✔ 다만, **단순한 배열이 필요하다면 `boolean[]`이 더 직관적**일 수 있다.
|
||||
|
||||
---
|
||||
|
||||
## **5. 결론**
|
||||
`BitSet`은 **대량의 불리언 데이터를 비트 단위로 저장하고 처리하는 데 유용**하며,
|
||||
비트 연산이 필요한 **비트마스크, 소수 판별, 집합 연산, 압축 데이터 처리** 등에 많이 활용된다.
|
||||
단순한 `boolean[]`보다 **메모리를 절약**하면서도 **연산 속도가 빠르다**는 점이 강점이다.
|
||||
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
|
||||
### `BitSet` 클래스의 메서드 정리 및 설명
|
||||
|
||||
자바의 `BitSet` 클래스는 `java.util` 패키지에 포함된 클래스로, 비트 단위로 데이터를 효율적으로 관리하기 위한 자료 구조입니다. 이는 이진수 데이터를 다룰 때 메모리를 절약하며, 비트 연산(AND, OR, XOR 등)을 쉽게 수행할 수 있도록 설계되었습니다. `BitSet`은 가변 크기의 비트 배열로 동작하며, 인덱스는 0부터 시작합니다.
|
||||
|
||||
아래에서 `BitSet`의 주요 메서드를 표로 정리하고, 각 메서드의 사용법과 예시를 설명하겠습니다.
|
||||
|
||||
---
|
||||
|
||||
### `BitSet` 클래스 메서드 표
|
||||
|
||||
| 메서드명 | 반환 타입 | 설명 |
|
||||
|------------------------------------|-------------|------------------------------------------------------------------------------------------|
|
||||
| `BitSet()` | - | 빈 `BitSet` 객체를 생성 (기본 크기 64비트) |
|
||||
| `BitSet(int nbits)` | - | 지정된 초기 크기(`nbits`)로 `BitSet` 생성 |
|
||||
| `set(int bitIndex)` | `void` | 지정된 인덱스의 비트를 `true`(1)로 설정 |
|
||||
| `set(int bitIndex, boolean value)`| `void` | 지정된 인덱스의 비트를 주어진 값(`true` 또는 `false`)으로 설정 |
|
||||
| `set(int fromIndex, int toIndex)` | `void` | 지정된 범위(`fromIndex`부터 `toIndex-1`까지)의 비트를 `true`로 설정 |
|
||||
| `clear(int bitIndex)` | `void` | 지정된 인덱스의 비트를 `false`(0)로 설정 |
|
||||
| `clear(int fromIndex, int toIndex)` | `void` | 지정된 범위의 비트를 `false`로 설정 |
|
||||
| `clear()` | `void` | 모든 비트를 `false`로 설정 |
|
||||
| `get(int bitIndex)` | `boolean` | 지정된 인덱스의 비트 값을 반환 |
|
||||
| `get(int fromIndex, int toIndex)` | `BitSet` | 지정된 범위의 비트를 포함하는 새로운 `BitSet` 반환 |
|
||||
| `flip(int bitIndex)` | `void` | 지정된 인덱스의 비트를 반전 (`true` ↔ `false`) |
|
||||
| `flip(int fromIndex, int toIndex)`| `void` | 지정된 범위의 비트를 반전 |
|
||||
| `and(BitSet set)` | `void` | 현재 `BitSet`과 주어진 `BitSet` 간 비트 단위 AND 연산 수행 |
|
||||
| `or(BitSet set)` | `void` | 현재 `BitSet`과 주어진 `BitSet` 간 비트 단위 OR 연산 수행 |
|
||||
| `xor(BitSet set)` | `void` | 현재 `BitSet`과 주어진 `BitSet` 간 비트 단위 XOR 연산 수행 |
|
||||
| `andNot(BitSet set)` | `void` | 현재 `BitSet`에서 주어진 `BitSet`의 비트를 제거 (AND NOT 연산) |
|
||||
| `cardinality()` | `int` | `true`인 비트의 개수 반환 |
|
||||
| `length()` | `int` | 마지막 `true` 비트의 인덱스 + 1 반환 (논리적 크기) |
|
||||
| `size()` | `int` | 내부적으로 할당된 비트 수 반환 (물리적 크기, 64의 배수) |
|
||||
| `isEmpty()` | `boolean` | 모든 비트가 `false`인지 확인 |
|
||||
| `intersects(BitSet set)` | `boolean` | 주어진 `BitSet`과 공통된 `true` 비트가 있는지 확인 |
|
||||
| `nextSetBit(int fromIndex)` | `int` | 지정된 인덱스 이후 첫 번째 `true` 비트의 인덱스 반환, 없으면 -1 |
|
||||
| `nextClearBit(int fromIndex)` | `int` | 지정된 인덱스 이후 첫 번째 `false` 비트의 인덱스 반환 |
|
||||
| `previousSetBit(int fromIndex)` | `int` | 지정된 인덱스 이전의 마지막 `true` 비트의 인덱스 반환, 없으면 -1 |
|
||||
| `previousClearBit(int fromIndex)` | `int` | 지정된 인덱스 이전의 마지막 `false` 비트의 인덱스 반환 |
|
||||
| `toByteArray()` | `byte[]` | `BitSet`을 바이트 배열로 변환 |
|
||||
| `toLongArray()` | `long[]` | `BitSet`을 `long` 배열로 변환 |
|
||||
| `valueOf(byte[] bytes)` | `BitSet` | 바이트 배열에서 `BitSet` 생성 (정적 메서드) |
|
||||
| `valueOf(long[] longs)` | `BitSet` | `long` 배열에서 `BitSet` 생성 (정적 메서드) |
|
||||
| `clone()` | `Object` | `BitSet`의 복사본 반환 |
|
||||
| `equals(Object obj)` | `boolean` | 주어진 객체와 동일한지 비교 |
|
||||
| `toString()` | `String` | `true` 비트의 인덱스를 포함한 문자열 반환 (예: "{0, 2, 4}") |
|
||||
|
||||
---
|
||||
|
||||
### `BitSet` 설명 및 예시
|
||||
|
||||
`BitSet`은 비트 단위로 데이터를 표현하므로 메모리 효율성이 높고, 비트 연산이 필요한 경우 유용합니다. 주요 사용 사례는 플래그 관리, 집합 표현, 데이터 압축 등입니다. 아래에서 주요 메서드의 사용법을 예시로 설명합니다.
|
||||
|
||||
#### 1. 비트 설정 및 확인
|
||||
비트를 설정하고 값을 확인합니다.
|
||||
|
||||
```java
|
||||
import java.util.BitSet;
|
||||
|
||||
public class BitSetBasicExample {
|
||||
public static void main(String[] args) {
|
||||
BitSet bits = new BitSet();
|
||||
bits.set(0); // 0번 비트 = true
|
||||
bits.set(2); // 2번 비트 = true
|
||||
bits.set(4, 6); // 4~5번 비트 = true
|
||||
|
||||
System.out.println("Bit at 0: " + bits.get(0)); // true
|
||||
System.out.println("Bit at 1: " + bits.get(1)); // false
|
||||
System.out.println("Bits: " + bits); // {0, 2, 4, 5}
|
||||
}
|
||||
}
|
||||
```
|
||||
- **출력**:
|
||||
```
|
||||
Bit at 0: true
|
||||
Bit at 1: false
|
||||
Bits: {0, 2, 4, 5}
|
||||
```
|
||||
|
||||
#### 2. 비트 연산
|
||||
`and`, `or`, `xor` 연산을 수행합니다.
|
||||
|
||||
```java
|
||||
import java.util.BitSet;
|
||||
|
||||
public class BitSetOperationExample {
|
||||
public static void main(String[] args) {
|
||||
BitSet bits1 = new BitSet();
|
||||
bits1.set(0);
|
||||
bits1.set(1);
|
||||
BitSet bits2 = new BitSet();
|
||||
bits2.set(1);
|
||||
bits2.set(2);
|
||||
|
||||
BitSet andResult = (BitSet) bits1.clone();
|
||||
andResult.and(bits2);
|
||||
System.out.println("AND: " + andResult); // {1}
|
||||
|
||||
BitSet orResult = (BitSet) bits1.clone();
|
||||
orResult.or(bits2);
|
||||
System.out.println("OR: " + orResult); // {0, 1, 2}
|
||||
|
||||
BitSet xorResult = (BitSet) bits1.clone();
|
||||
xorResult.xor(bits2);
|
||||
System.out.println("XOR: " + xorResult); // {0, 2}
|
||||
}
|
||||
}
|
||||
```
|
||||
- **출력**:
|
||||
```
|
||||
AND: {1}
|
||||
OR: {0, 1, 2}
|
||||
XOR: {0, 2}
|
||||
```
|
||||
|
||||
#### 3. 비트 탐색
|
||||
다음 `true` 또는 `false` 비트를 찾습니다.
|
||||
|
||||
```java
|
||||
import java.util.BitSet;
|
||||
|
||||
public class BitSetSearchExample {
|
||||
public static void main(String[] args) {
|
||||
BitSet bits = new BitSet();
|
||||
bits.set(2);
|
||||
bits.set(5);
|
||||
|
||||
int nextSet = bits.nextSetBit(0); // 2
|
||||
int nextClear = bits.nextClearBit(2); // 3
|
||||
System.out.println("Next set bit from 0: " + nextSet);
|
||||
System.out.println("Next clear bit from 2: " + nextClear);
|
||||
}
|
||||
}
|
||||
```
|
||||
- **출력**:
|
||||
```
|
||||
Next set bit from 0: 2
|
||||
Next clear bit from 2: 3
|
||||
```
|
||||
|
||||
#### 4. 바이트 배열 변환
|
||||
`BitSet`을 바이트 배열로 변환하고 역변환합니다.
|
||||
|
||||
```java
|
||||
import java.util.BitSet;
|
||||
|
||||
public class BitSetToByteExample {
|
||||
public static void main(String[] args) {
|
||||
BitSet bits = new BitSet();
|
||||
bits.set(0);
|
||||
bits.set(3);
|
||||
bits.set(7);
|
||||
|
||||
byte[] byteArray = bits.toByteArray();
|
||||
System.out.print("Byte array: ");
|
||||
for (byte b : byteArray) {
|
||||
System.out.printf("%02X ", b); // 09 80 (00001001 10000000)
|
||||
}
|
||||
System.out.println();
|
||||
|
||||
BitSet fromBytes = BitSet.valueOf(byteArray);
|
||||
System.out.println("From bytes: " + fromBytes); // {0, 3, 7}
|
||||
}
|
||||
}
|
||||
```
|
||||
- **출력**:
|
||||
```
|
||||
Byte array: 09 80
|
||||
From bytes: {0, 3, 7}
|
||||
```
|
||||
|
||||
#### 5. 상태 확인
|
||||
`BitSet`의 크기와 개수를 확인합니다.
|
||||
|
||||
```java
|
||||
import java.util.BitSet;
|
||||
|
||||
public class BitSetStatusExample {
|
||||
public static void main(String[] args) {
|
||||
BitSet bits = new BitSet();
|
||||
bits.set(2);
|
||||
bits.set(5);
|
||||
|
||||
System.out.println("Cardinality: " + bits.cardinality()); // 2
|
||||
System.out.println("Length: " + bits.length()); // 6
|
||||
System.out.println("Size: " + bits.size()); // 64
|
||||
System.out.println("Is empty: " + bits.isEmpty()); // false
|
||||
}
|
||||
}
|
||||
```
|
||||
- **출력**:
|
||||
```
|
||||
Cardinality: 2
|
||||
Length: 6
|
||||
Size: 64
|
||||
Is empty: false
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### `BitSet`의 특징과 주의점
|
||||
- **장점**:
|
||||
- 메모리 효율성: `true` 비트만 저장하며, 필요한 만큼 동적으로 확장.
|
||||
- 비트 연산 지원: 집합 연산(합집합, 교집합 등)을 쉽게 구현.
|
||||
- **주의점**:
|
||||
- 인덱스 음수 불가: `IllegalArgumentException` 발생.
|
||||
- 동기화 없음: 멀티스레드 환경에서 `Collections.synchronizedSet`으로 감싸야 함.
|
||||
- 크기: `size()`는 물리적 크기(64비트 단위), `length()`는 논리적 크기.
|
||||
|
||||
---
|
||||
|
||||
### 결론
|
||||
`BitSet`은 비트 단위 작업을 효율적으로 처리하며, 설정(`set`), 확인(`get`), 연산(`and`, `or`, `xor`), 변환(`toByteArray`) 등 다양한 기능을 제공합니다. 위 예시를 통해 비트 관리, 집합 연산, 데이터 변환 등에 활용해 보세요! 필요 시 크기 조정이나 동기화 처리를 추가해 사용하면 더욱 강력한 도구가 됩니다.
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
### `BitSet`의 인덱스 순서에 대한 설명
|
||||
|
||||
자바의 `BitSet` 클래스는 비트 단위로 데이터를 관리하는 자료 구조로, 각 비트는 0부터 시작하는 정수 인덱스에 의해 식별됩니다. 이 인덱스 순서는 비트의 위치를 나타내며, `BitSet`의 동작 방식과 데이터 표현에 중요한 영향을 미칩니다. 아래에서 `BitSet`의 인덱스 순서에 대해 자세히 설명하고, 예시를 통해 이해를 돕겠습니다.
|
||||
|
||||
---
|
||||
|
||||
### 1. **인덱스 순서의 기본 개념**
|
||||
- **`BitSet`의 인덱스**: 0부터 시작하는 정수로, 비트의 위치를 나타냅니다.
|
||||
- 인덱스 0은 가장 낮은 비트(least significant bit, LSB)를 의미하며, 인덱스가 증가할수록 더 높은 비트(most significant bit, MSB)로 이동합니다.
|
||||
- **순서**: 논리적으로 왼쪽에서 오른쪽으로 증가하는 순서가 아니라, 내부적으로는 오른쪽에서 왼쪽으로 비트가 배치됩니다. 하지만 사용자가 접근할 때는 인덱스 0이 시작점으로 간주됩니다.
|
||||
- **크기**: `BitSet`은 필요에 따라 동적으로 확장되며, 초기 크기는 64비트 단위로 할당됩니다.
|
||||
|
||||
#### 비트와 인덱스 매핑 예시
|
||||
- 8비트 기준으로 생각하면:
|
||||
```
|
||||
인덱스: 7 6 5 4 3 2 1 0
|
||||
비트: [0, 0, 0, 0, 1, 0, 1, 0] // 10진수 10
|
||||
```
|
||||
- 인덱스 1이 `true`이고, 인덱스 3이 `true`이면 값은 `00001010` (10진수로 10).
|
||||
|
||||
---
|
||||
|
||||
### 2. **인덱스 순서와 메서드 동작**
|
||||
`BitSet`의 메서드는 이 인덱스 순서를 기반으로 동작합니다. 주요 메서드와 인덱스 순서의 관계를 살펴보겠습니다.
|
||||
|
||||
#### `set(int bitIndex)`와 `get(int bitIndex)`
|
||||
- `set(3)`은 인덱스 3의 비트를 `true`로 설정하며, 이는 오른쪽에서 네 번째 비트에 해당합니다.
|
||||
- `get(3)`은 인덱스 3의 비트 값을 반환합니다.
|
||||
|
||||
#### `nextSetBit(int fromIndex)`와 `previousSetBit(int fromIndex)`
|
||||
- `nextSetBit(0)`은 인덱스 0부터 시작해 첫 번째 `true` 비트의 인덱스를 반환합니다. 순서는 낮은 인덱스에서 높은 인덱스로 진행.
|
||||
- `previousSetBit(5)`는 인덱스 5 이전의 마지막 `true` 비트의 인덱스를 반환하며, 높은 인덱스에서 낮은 인덱스로 역방향 탐색.
|
||||
|
||||
#### `toByteArray()`와 바이트 순서
|
||||
- `BitSet`을 바이트 배열로 변환할 때, 낮은 인덱스가 낮은 바이트에 먼저 매핑됩니다.
|
||||
- 예: 인덱스 0~7이 첫 번째 바이트, 8~15가 두 번째 바이트로 변환.
|
||||
- 바이트 내부에서는 비트가 LSB에서 MSB로 배치됩니다 (즉, 인덱스 0이 바이트의 최하위 비트).
|
||||
|
||||
---
|
||||
|
||||
### 3. **인덱스 순서 예시**
|
||||
#### 예시 1: 비트 설정과 확인
|
||||
```java
|
||||
import java.util.BitSet;
|
||||
|
||||
public class BitSetIndexOrder {
|
||||
public static void main(String[] args) {
|
||||
BitSet bits = new BitSet();
|
||||
bits.set(0); // 인덱스 0 = true
|
||||
bits.set(3); // 인덱스 3 = true
|
||||
bits.set(7); // 인덱스 7 = true
|
||||
|
||||
System.out.println("Bits: " + bits); // {0, 3, 7}
|
||||
System.out.println("Bit at 0: " + bits.get(0)); // true
|
||||
System.out.println("Bit at 1: " + bits.get(1)); // false
|
||||
}
|
||||
}
|
||||
```
|
||||
- **출력**:
|
||||
```
|
||||
Bits: {0, 3, 7}
|
||||
Bit at 0: true
|
||||
Bit at 1: false
|
||||
```
|
||||
- **설명**: 인덱스 0, 3, 7이 `true`로 설정되며, 이는 8비트 기준으로 `10001001` (10진수 137)과 같습니다.
|
||||
|
||||
#### 예시 2: 바이트 배열 변환
|
||||
```java
|
||||
import java.util.BitSet;
|
||||
|
||||
public class BitSetToByteOrder {
|
||||
public static void main(String[] args) {
|
||||
BitSet bits = new BitSet();
|
||||
bits.set(0); // 00000001
|
||||
bits.set(3); // 00001000
|
||||
bits.set(7); // 10000000
|
||||
|
||||
byte[] bytes = bits.toByteArray();
|
||||
for (byte b : bytes) {
|
||||
System.out.printf("%02X ", b); // 09 (00001001)
|
||||
}
|
||||
System.out.println();
|
||||
}
|
||||
}
|
||||
```
|
||||
- **출력**: `09`
|
||||
- **설명**:
|
||||
- 인덱스 0~7이 첫 번째 바이트로 변환.
|
||||
- `00001001` (인덱스 7이 MSB, 인덱스 0이 LSB) = 16진수 `09`.
|
||||
|
||||
#### 예시 3: 비트 탐색
|
||||
```java
|
||||
import java.util.BitSet;
|
||||
|
||||
public class BitSetSearchOrder {
|
||||
public static void main(String[] args) {
|
||||
BitSet bits = new BitSet();
|
||||
bits.set(2);
|
||||
bits.set(5);
|
||||
bits.set(10);
|
||||
|
||||
int next = bits.nextSetBit(0); // 2
|
||||
int nextFrom3 = bits.nextSetBit(3); // 5
|
||||
int prevFrom10 = bits.previousSetBit(10); // 10
|
||||
|
||||
System.out.println("Next set from 0: " + next);
|
||||
System.out.println("Next set from 3: " + nextFrom3);
|
||||
System.out.println("Previous set from 10: " + prevFrom10);
|
||||
}
|
||||
}
|
||||
```
|
||||
- **출력**:
|
||||
```
|
||||
Next set from 0: 2
|
||||
Next set from 3: 5
|
||||
Previous set from 10: 10
|
||||
```
|
||||
- **설명**: 인덱스 순서에 따라 낮은 인덱스에서 높은 인덱스로(또는 그 반대로) 탐색.
|
||||
|
||||
---
|
||||
|
||||
### 4. **인덱스 순서와 바이트 순서의 관계**
|
||||
- **내부 표현**: `BitSet`은 `long[]` 배열로 비트를 저장하며, 각 `long`은 64비트를 표현합니다.
|
||||
- 첫 번째 `long`은 인덱스 0~63, 두 번째는 64~127을 다룹니다.
|
||||
- 바이트로 변환 시, 낮은 인덱스가 낮은 바이트에 매핑되며, 바이트 내에서는 LSB에서 MSB로 진행.
|
||||
- **예**: 인덱스 0~15 설정 시:
|
||||
```
|
||||
BitSet: {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}
|
||||
Byte array: FF FF (11111111 11111111)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 5. **주의점**
|
||||
- **음수 인덱스**: `BitSet`은 음수 인덱스를 허용하지 않으며, `IllegalArgumentException` 발생.
|
||||
- **바이트 순서**: `toByteArray()` 결과는 little-endian 스타일로, 인덱스 0이 첫 바이트의 LSB에 매핑.
|
||||
- **논리적 vs 물리적 크기**: `length()`는 마지막 `true` 비트의 인덱스 + 1, `size()`는 할당된 비트 수(64의 배수).
|
||||
|
||||
---
|
||||
|
||||
### 결론
|
||||
`BitSet`의 인덱스 순서는 0부터 시작하며, 낮은 인덱스가 LSB, 높은 인덱스가 MSB에 해당합니다. 메서드는 이 순서를 기반으로 비트를 설정, 확인, 연산하며, 바이트 변환 시에도 인덱스 순서가 반영됩니다. 위 예시를 통해 인덱스 순서가 데이터 표현과 탐색에 어떻게 적용되는지 확인할 수 있습니다. 비트 단위 작업 시 이 순서를 이해하면 `BitSet`을 더 효과적으로 활용할 수 있습니다!
|
||||
Reference in New Issue
Block a user