java.util.bitset - set()は予想どおりに機能しません
-
27-09-2019 - |
質問
痛いほど明白なものが足りないのですか?それとも、世界の誰も実際にjava.util.bitsetを使用していませんか?
次のテストに失敗します:
@Test
public void testBitSet() throws Exception {
BitSet b = new BitSet();
b.set(0, true);
b.set(1, false);
assertEquals(2, b.length());
}
長さ2と値10のビットセットにならない理由は本当に不明です。Java.util.bitsetのソースを覗きました。カジュアルな検査では、少し区別できないようです。それは虚偽で設定されており、一度も価値に設定されたことがありません...
(コンストラクター内のビットセットのサイズを明示的に設定しても効果がないことに注意してください。
BitSet b = new BitSet(2);
解決
人々は使用します BitSet
;しかし、彼らはあなたが意図するもの以外の何かにそれを使用します。おそらく考えるのが最善です BitSet
の非常にコンパクトな、メモリ効率の高い形として Set<Integer>
それはあなたがそれに負の数を入れることができない独特の特性を持っています。
それは非常に一般的です BitSet
sのパターンでそれらを使用します
for (int id = set.nextSetBit(0); id >= 0; id = set.nextSetBit(id + 1)) {
// do stuff to a set index
}
あなたがそれらを満たすために何かをした後。これは、 Set
.
他のヒント
最高のビットセット(「セット1」のように)はビット0です。したがって、長さは1でなければなりません。
を参照してください 長さのjavadoc:
public int length()
このビットセットの「論理サイズ」を返します:ビットセットと1つの最高のセットビットのインデックス。ビットセットにセットビットが含まれていない場合、ゼロを返します。
多分あなたは探しています サイズ そうかもしれませんが より高い 特定の解像度でビットが割り当てられている場合(16ビット境界など)。
これも私を困惑させました。ビットセットの現在のかなり予想外の機能の背後にある理論的根拠がわかりませんでした。ただし、最終ではないため、抱きしめて戦術を拡張し、以下を実行して、予想どおりに長さのセマンティクスを備えた固定ビットセットを取得できます。
import java.util.BitSet;
/**
* Variation of BitSet which does NOT interpret the highest bit synonymous with
* its length.
*
* @author casper.bang@gmail.com
*/
public class FixedBitSet extends BitSet{
int fixedLength;
public FixedBitSet(int fixedLength){
super(fixedLength);
this.fixedLength = fixedLength;
}
@Override
public int length() {
return fixedLength;
}
}
ビットセットが長い[]に裏付けられていることを考えると、最小サイズは64です(1つの長さは64ビットであるため)。サイズは64の倍数によって増加し、何らかの理由で、INTを使用するコンストラクターを使用するときに表現するビットの#を維持していません。
// Abhay Dandekar
import java.util.BitSet;
public class TestBitSet {
public static void main(String[] args) {
BitSet bitSet = new BitSet();
System.out.println("State 0 : " + bitSet.size() + " : " + bitSet.length() );
bitSet.set(0, true);
bitSet.set(1, true);
System.out.println("State 1 : " + bitSet.size() + " : " + bitSet.length() );
bitSet.set(2, false);
bitSet.set(3, false);
System.out.println("State 2 : " + bitSet.size() + " : " + bitSet.length() );
bitSet.set(4, true);
System.out.println("State 3 : " + bitSet.size() + " : " + bitSet.length() );
}
}
内部で何が起こるかを示す簡単なJavaプログラム。注意すべき点:
ビットセットは長い間バッキングされています
すべてのデフォルト値はfalseです
長さを返している間、セットの最高の「真の」値のインデックス+1を返します。
以下の出力は、それ自体を説明できるはずです。
State 0 : 64 : 0
State 1 : 64 : 2
State 2 : 64 : 2
State 3 : 64 : 5
結論を出すことを指します:
長さを使用して、修正されたビットのnoを締めくくないでください
ブルームフィルターなどのシナリオで使用できます。ブルームフィルターの詳細はグーグルできます。;)
お役に立てれば
よろしく、
Abhay Dandekar
良いキャスパー!あなたの小さな改善は、実際に元のBitset Java defに存在するはずです!また、これ(append()とconcat()がさまざまな使用に役立つことをお勧めします)
import java.util.BitSet;
public class fixBitSet extends BitSet {
public int fsize = 0;
public void set(int k, boolean value) {
if (k >= fsize)
fsize = k + 1;
super.set(k, value);
}
public void append(fixBitSet bs) {
for (int k = 0; k < bs.fsize; k++)
super.set(fsize + k, bs.get(k));
fsize += bs.fsize;
}
public static fixBitSet concat(fixBitSet[] vbs) {
final fixBitSet bs = new fixBitSet();
for (fixBitSet xbs : vbs)
bs.append(xbs);
return (bs);
}
}