Methods Summary |
---|
public void | and(java.util.BitSet set)Performs a logical AND of this target bit set with the
argument bit set. This bit set is modified so that each bit in it
has the value true if and only if it both initially
had the value true and the corresponding bit in the
bit set argument also had the value true .
if (this == set)
return;
// Perform logical AND on bits in common
int oldUnitsInUse = unitsInUse;
unitsInUse = Math.min(unitsInUse, set.unitsInUse);
int i;
for(i=0; i<unitsInUse; i++)
bits[i] &= set.bits[i];
// Clear out units no longer used
for( ; i < oldUnitsInUse; i++)
bits[i] = 0;
// Recalculate units in use if necessary
if (unitsInUse > 0 && bits[unitsInUse - 1] == 0)
recalculateUnitsInUse();
|
public void | andNot(java.util.BitSet set)Clears all of the bits in this BitSet whose corresponding
bit is set in the specified BitSet .
int unitsInCommon = Math.min(unitsInUse, set.unitsInUse);
// Perform logical (a & !b) on bits in common
for (int i=0; i<unitsInCommon; i++) {
bits[i] &= ~set.bits[i];
}
recalculateUnitsInUse();
|
private static long | bit(int bitIndex)Given a bit index, return a unit that masks that bit in its unit.
return 1L << (bitIndex & BIT_INDEX_MASK);
|
private static int | bitCount(long val)Returns the number of bits set in val.
For a derivation of this algorithm, see
"Algorithms and data structures with applications to
graphics and geometry", by Jurg Nievergelt and Klaus Hinrichs,
Prentice Hall, 1993.
val -= (val & 0xaaaaaaaaaaaaaaaaL) >>> 1;
val = (val & 0x3333333333333333L) + ((val >>> 2) & 0x3333333333333333L);
val = (val + (val >>> 4)) & 0x0f0f0f0f0f0f0f0fL;
val += val >>> 8;
val += val >>> 16;
return ((int)(val) + (int)(val >>> 32)) & 0xff;
|
private static int | bitLen(int w)bitLen(val) is the number of bits in val.
// Binary search - decision tree (5 tests, rarely 6)
return
(w < 1<<15 ?
(w < 1<<7 ?
(w < 1<<3 ?
(w < 1<<1 ? (w < 1<<0 ? (w<0 ? 32 : 0) : 1) : (w < 1<<2 ? 2 : 3)) :
(w < 1<<5 ? (w < 1<<4 ? 4 : 5) : (w < 1<<6 ? 6 : 7))) :
(w < 1<<11 ?
(w < 1<<9 ? (w < 1<<8 ? 8 : 9) : (w < 1<<10 ? 10 : 11)) :
(w < 1<<13 ? (w < 1<<12 ? 12 : 13) : (w < 1<<14 ? 14 : 15)))) :
(w < 1<<23 ?
(w < 1<<19 ?
(w < 1<<17 ? (w < 1<<16 ? 16 : 17) : (w < 1<<18 ? 18 : 19)) :
(w < 1<<21 ? (w < 1<<20 ? 20 : 21) : (w < 1<<22 ? 22 : 23))) :
(w < 1<<27 ?
(w < 1<<25 ? (w < 1<<24 ? 24 : 25) : (w < 1<<26 ? 26 : 27)) :
(w < 1<<29 ? (w < 1<<28 ? 28 : 29) : (w < 1<<30 ? 30 : 31)))));
|
private static long | bitsLeftOf(int x)Returns a long that has all the bits that are more significant
than or equal to the specified index set to 1. All other bits are 0.
return WORD_MASK << x;
|
private static long | bitsRightOf(int x)Returns a long that has all bits that are less significant
than the specified index set to 1. All other bits are 0.
return (x==0 ? 0 : WORD_MASK >>> (64-x));
|
public int | cardinality()Returns the number of bits set to true in this
BitSet .
int sum = 0;
for (int i=0; i<unitsInUse; i++)
sum += bitCount(bits[i]);
return sum;
|
public void | clear(int bitIndex)Sets the bit specified by the index to false .
if (bitIndex < 0)
throw new IndexOutOfBoundsException("bitIndex < 0: " + bitIndex);
int unitIndex = unitIndex(bitIndex);
if (unitIndex >= unitsInUse)
return;
bits[unitIndex] &= ~bit(bitIndex);
if (bits[unitsInUse-1] == 0)
recalculateUnitsInUse();
|
public void | clear(int fromIndex, int toIndex)Sets the bits from the specified fromIndex(inclusive) to the
specified toIndex(exclusive) to false .
if (fromIndex < 0)
throw new IndexOutOfBoundsException("fromIndex < 0: " + fromIndex);
if (toIndex < 0)
throw new IndexOutOfBoundsException("toIndex < 0: " + toIndex);
if (fromIndex > toIndex)
throw new IndexOutOfBoundsException("fromIndex: " + fromIndex +
" > toIndex: " + toIndex);
int startUnitIndex = unitIndex(fromIndex);
if (startUnitIndex >= unitsInUse)
return;
int endUnitIndex = unitIndex(toIndex);
long bitMask = 0;
if (startUnitIndex == endUnitIndex) {
// Case 1: One word
bitMask = (1L << (toIndex & BIT_INDEX_MASK)) -
(1L << (fromIndex & BIT_INDEX_MASK));
bits[startUnitIndex] &= ~bitMask;
if (bits[unitsInUse-1] == 0)
recalculateUnitsInUse();
return;
}
// Case 2: Multiple words
// Handle first word
bitMask = bitsLeftOf(fromIndex & BIT_INDEX_MASK);
bits[startUnitIndex] &= ~bitMask;
// Handle intermediate words, if any
if (endUnitIndex - startUnitIndex > 1) {
for(int i=startUnitIndex+1; i<endUnitIndex; i++) {
if (i < unitsInUse)
bits[i] = 0;
}
}
// Handle last word
if (endUnitIndex < unitsInUse) {
bitMask = bitsRightOf(toIndex & BIT_INDEX_MASK);
bits[endUnitIndex] &= ~bitMask;
}
if (bits[unitsInUse-1] == 0)
recalculateUnitsInUse();
|
public void | clear()Sets all of the bits in this BitSet to false .
while (unitsInUse > 0)
bits[--unitsInUse] = 0;
|
public java.lang.Object | clone()Cloning this BitSet produces a new BitSet
that is equal to it.
The clone of the bit set is another bit set that has exactly the
same bits set to true as this bit set and the same
current size.
Overrides the clone method of Object .
BitSet result = null;
try {
result = (BitSet) super.clone();
} catch (CloneNotSupportedException e) {
throw new InternalError();
}
result.bits = new long[bits.length];
System.arraycopy(bits, 0, result.bits, 0, unitsInUse);
return result;
|
private void | ensureCapacity(int unitsRequired)Ensures that the BitSet can hold enough units.
if (bits.length < unitsRequired) {
// Allocate larger of doubled size or required size
int request = Math.max(2 * bits.length, unitsRequired);
long newBits[] = new long[request];
System.arraycopy(bits, 0, newBits, 0, unitsInUse);
bits = newBits;
}
|
public boolean | equals(java.lang.Object obj)Compares this object against the specified object.
The result is true if and only if the argument is
not null and is a Bitset object that has
exactly the same set of bits set to true as this bit
set. That is, for every nonnegative int index k ,
((BitSet)obj).get(k) == this.get(k)
must be true. The current sizes of the two bit sets are not compared.
Overrides the equals method of Object .
if (!(obj instanceof BitSet))
return false;
if (this == obj)
return true;
BitSet set = (BitSet) obj;
int minUnitsInUse = Math.min(unitsInUse, set.unitsInUse);
// Check units in use by both BitSets
for (int i = 0; i < minUnitsInUse; i++)
if (bits[i] != set.bits[i])
return false;
// Check any units in use by only one BitSet (must be 0 in other)
if (unitsInUse > minUnitsInUse) {
for (int i = minUnitsInUse; i<unitsInUse; i++)
if (bits[i] != 0)
return false;
} else {
for (int i = minUnitsInUse; i<set.unitsInUse; i++)
if (set.bits[i] != 0)
return false;
}
return true;
|
public void | flip(int bitIndex)Sets the bit at the specified index to the complement of its
current value.
if (bitIndex < 0)
throw new IndexOutOfBoundsException("bitIndex < 0: " + bitIndex);
int unitIndex = unitIndex(bitIndex);
int unitsRequired = unitIndex+1;
if (unitsInUse < unitsRequired) {
ensureCapacity(unitsRequired);
bits[unitIndex] ^= bit(bitIndex);
unitsInUse = unitsRequired;
} else {
bits[unitIndex] ^= bit(bitIndex);
if (bits[unitsInUse-1] == 0)
recalculateUnitsInUse();
}
|
public void | flip(int fromIndex, int toIndex)Sets each bit from the specified fromIndex(inclusive) to the
specified toIndex(exclusive) to the complement of its current
value.
if (fromIndex < 0)
throw new IndexOutOfBoundsException("fromIndex < 0: " + fromIndex);
if (toIndex < 0)
throw new IndexOutOfBoundsException("toIndex < 0: " + toIndex);
if (fromIndex > toIndex)
throw new IndexOutOfBoundsException("fromIndex: " + fromIndex +
" > toIndex: " + toIndex);
// Increase capacity if necessary
int endUnitIndex = unitIndex(toIndex);
int unitsRequired = endUnitIndex + 1;
if (unitsInUse < unitsRequired) {
ensureCapacity(unitsRequired);
unitsInUse = unitsRequired;
}
int startUnitIndex = unitIndex(fromIndex);
long bitMask = 0;
if (startUnitIndex == endUnitIndex) {
// Case 1: One word
bitMask = (1L << (toIndex & BIT_INDEX_MASK)) -
(1L << (fromIndex & BIT_INDEX_MASK));
bits[startUnitIndex] ^= bitMask;
if (bits[unitsInUse-1] == 0)
recalculateUnitsInUse();
return;
}
// Case 2: Multiple words
// Handle first word
bitMask = bitsLeftOf(fromIndex & BIT_INDEX_MASK);
bits[startUnitIndex] ^= bitMask;
// Handle intermediate words, if any
if (endUnitIndex - startUnitIndex > 1) {
for(int i=startUnitIndex+1; i<endUnitIndex; i++)
bits[i] ^= WORD_MASK;
}
// Handle last word
bitMask = bitsRightOf(toIndex & BIT_INDEX_MASK);
bits[endUnitIndex] ^= bitMask;
// Check to see if we reduced size
if (bits[unitsInUse-1] == 0)
recalculateUnitsInUse();
|
public boolean | get(int bitIndex)Returns the value of the bit with the specified index. The value
is true if the bit with the index bitIndex
is currently set in this BitSet ; otherwise, the result
is false .
if (bitIndex < 0)
throw new IndexOutOfBoundsException("bitIndex < 0: " + bitIndex);
boolean result = false;
int unitIndex = unitIndex(bitIndex);
if (unitIndex < unitsInUse)
result = ((bits[unitIndex] & bit(bitIndex)) != 0);
return result;
|
public java.util.BitSet | get(int fromIndex, int toIndex)Returns a new BitSet composed of bits from this BitSet
from fromIndex(inclusive) to toIndex(exclusive).
if (fromIndex < 0)
throw new IndexOutOfBoundsException("fromIndex < 0: " + fromIndex);
if (toIndex < 0)
throw new IndexOutOfBoundsException("toIndex < 0: " + toIndex);
if (fromIndex > toIndex)
throw new IndexOutOfBoundsException("fromIndex: " + fromIndex +
" > toIndex: " + toIndex);
// If no set bits in range return empty bitset
if (length() <= fromIndex || fromIndex == toIndex)
return new BitSet(0);
// An optimization
if (length() < toIndex)
toIndex = length();
BitSet result = new BitSet(toIndex - fromIndex);
int startBitIndex = fromIndex & BIT_INDEX_MASK;
int endBitIndex = toIndex & BIT_INDEX_MASK;
int targetWords = (toIndex - fromIndex + 63)/64;
int sourceWords = unitIndex(toIndex) - unitIndex(fromIndex) + 1;
int inverseIndex = 64 - startBitIndex;
int targetIndex = 0;
int sourceIndex = unitIndex(fromIndex);
// Process all words but the last word
while (targetIndex < targetWords - 1)
result.bits[targetIndex++] =
(bits[sourceIndex++] >>> startBitIndex) |
((inverseIndex==64) ? 0 : bits[sourceIndex] << inverseIndex);
// Process the last word
result.bits[targetIndex] = (sourceWords == targetWords ?
(bits[sourceIndex] & bitsRightOf(endBitIndex)) >>> startBitIndex :
(bits[sourceIndex++] >>> startBitIndex) | ((inverseIndex==64) ? 0 :
(getBits(sourceIndex) & bitsRightOf(endBitIndex)) << inverseIndex));
// Set unitsInUse correctly
result.unitsInUse = targetWords;
result.recalculateUnitsInUse();
return result;
|
private long | getBits(int j)Returns the unit of this bitset at index j as if this bitset had an
infinite amount of storage.
return (j < unitsInUse) ? bits[j] : 0;
|
public int | hashCode()Returns a hash code value for this bit set. The has code
depends only on which bits have been set within this
BitSet . The algorithm used to compute it may
be described as follows.
Suppose the bits in the BitSet were to be stored
in an array of long integers called, say,
bits , in such a manner that bit k is
set in the BitSet (for nonnegative values of
k ) if and only if the expression
((k>>6) < bits.length) && ((bits[k>>6] & (1L << (bit & 0x3F))) != 0)
is true. Then the following definition of the hashCode
method would be a correct implementation of the actual algorithm:
public int hashCode() {
long h = 1234;
for (int i = bits.length; --i >= 0; ) {
h ^= bits[i] * (i + 1);
}
return (int)((h >> 32) ^ h);
}
Note that the hash code values change if the set of bits is altered.
Overrides the hashCode method of Object .
long h = 1234;
for (int i = bits.length; --i >= 0; )
h ^= bits[i] * (i + 1);
return (int)((h >> 32) ^ h);
|
public boolean | intersects(java.util.BitSet set)Returns true if the specified BitSet has any bits set to
true that are also set to true in this
BitSet .
for(int i = Math.min(unitsInUse, set.unitsInUse)-1; i>=0; i--)
if ((bits[i] & set.bits[i]) != 0)
return true;
return false;
|
public boolean | isEmpty()Returns true if this BitSet contains no bits that are set
to true .
return (unitsInUse == 0);
|
public int | length()Returns the "logical size" of this BitSet : the index of
the highest set bit in the BitSet plus one. Returns zero
if the BitSet contains no set bits.
if (unitsInUse == 0)
return 0;
long highestUnit = bits[unitsInUse - 1];
int highPart = (int)(highestUnit >>> 32);
return 64 * (unitsInUse - 1) +
(highPart == 0 ? bitLen((int)highestUnit)
: 32 + bitLen((int)highPart));
|
public int | nextClearBit(int fromIndex)Returns the index of the first bit that is set to false
that occurs on or after the specified starting index.
if (fromIndex < 0)
throw new IndexOutOfBoundsException("fromIndex < 0: " + fromIndex);
int u = unitIndex(fromIndex);
if (u >= unitsInUse)
return fromIndex;
int testIndex = (fromIndex & BIT_INDEX_MASK);
long unit = bits[u] >> testIndex;
if (unit == (WORD_MASK >> testIndex))
testIndex = 0;
while((unit==WORD_MASK) && (u < unitsInUse-1))
unit = bits[++u];
if (unit == WORD_MASK)
return length();
if (unit == 0)
return u * BITS_PER_UNIT + testIndex;
testIndex += trailingZeroCnt(~unit);
return ((u * BITS_PER_UNIT) + testIndex);
|
public int | nextSetBit(int fromIndex)Returns the index of the first bit that is set to true
that occurs on or after the specified starting index. If no such
bit exists then -1 is returned.
To iterate over the true bits in a BitSet ,
use the following loop:
for(int i=bs.nextSetBit(0); i>=0; i=bs.nextSetBit(i+1)) {
// operate on index i here
}
if (fromIndex < 0)
throw new IndexOutOfBoundsException("fromIndex < 0: " + fromIndex);
int u = unitIndex(fromIndex);
if (u >= unitsInUse)
return -1;
int testIndex = (fromIndex & BIT_INDEX_MASK);
long unit = bits[u] >> testIndex;
if (unit == 0)
testIndex = 0;
while((unit==0) && (u < unitsInUse-1))
unit = bits[++u];
if (unit == 0)
return -1;
testIndex += trailingZeroCnt(unit);
return ((u * BITS_PER_UNIT) + testIndex);
|
public void | or(java.util.BitSet set)Performs a logical OR of this bit set with the bit set
argument. This bit set is modified so that a bit in it has the
value true if and only if it either already had the
value true or the corresponding bit in the bit set
argument has the value true .
if (this == set)
return;
ensureCapacity(set.unitsInUse);
// Perform logical OR on bits in common
int unitsInCommon = Math.min(unitsInUse, set.unitsInUse);
int i;
for(i=0; i<unitsInCommon; i++)
bits[i] |= set.bits[i];
// Copy any remaining bits
for(; i<set.unitsInUse; i++)
bits[i] = set.bits[i];
if (unitsInUse < set.unitsInUse)
unitsInUse = set.unitsInUse;
|
private void | readObject(java.io.ObjectInputStream in)This override of readObject makes sure unitsInUse is set properly
when deserializing a bitset
in.defaultReadObject();
// Assume maximum length then find real length
// because recalculateUnitsInUse assumes maintenance
// or reduction in logical size
unitsInUse = bits.length;
recalculateUnitsInUse();
|
private void | recalculateUnitsInUse()Set the field unitsInUse with the logical size in units of the bit
set. WARNING:This function assumes that the number of units actually
in use is less than or equal to the current value of unitsInUse!
// Traverse the bitset until a used unit is found
int i;
for (i = unitsInUse-1; i >= 0; i--)
if(bits[i] != 0)
break;
unitsInUse = i+1; // The new logical size
|
public void | set(int bitIndex)Sets the bit at the specified index to true .
if (bitIndex < 0)
throw new IndexOutOfBoundsException("bitIndex < 0: " + bitIndex);
int unitIndex = unitIndex(bitIndex);
int unitsRequired = unitIndex + 1;
if (unitsInUse < unitsRequired) {
ensureCapacity(unitsRequired);
bits[unitIndex] |= bit(bitIndex);
unitsInUse = unitsRequired;
} else {
bits[unitIndex] |= bit(bitIndex);
}
|
public void | set(int bitIndex, boolean value)Sets the bit at the specified index to the specified value.
if (value)
set(bitIndex);
else
clear(bitIndex);
|
public void | set(int fromIndex, int toIndex)Sets the bits from the specified fromIndex(inclusive) to the
specified toIndex(exclusive) to true .
if (fromIndex < 0)
throw new IndexOutOfBoundsException("fromIndex < 0: " + fromIndex);
if (toIndex < 0)
throw new IndexOutOfBoundsException("toIndex < 0: " + toIndex);
if (fromIndex > toIndex)
throw new IndexOutOfBoundsException("fromIndex: " + fromIndex +
" > toIndex: " + toIndex);
// Increase capacity if necessary
int endUnitIndex = unitIndex(toIndex);
int unitsRequired = endUnitIndex + 1;
if (unitsInUse < unitsRequired) {
ensureCapacity(unitsRequired);
unitsInUse = unitsRequired;
}
int startUnitIndex = unitIndex(fromIndex);
long bitMask = 0;
if (startUnitIndex == endUnitIndex) {
// Case 1: One word
bitMask = (1L << (toIndex & BIT_INDEX_MASK)) -
(1L << (fromIndex & BIT_INDEX_MASK));
bits[startUnitIndex] |= bitMask;
return;
}
// Case 2: Multiple words
// Handle first word
bitMask = bitsLeftOf(fromIndex & BIT_INDEX_MASK);
bits[startUnitIndex] |= bitMask;
// Handle intermediate words, if any
if (endUnitIndex - startUnitIndex > 1) {
for(int i=startUnitIndex+1; i<endUnitIndex; i++)
bits[i] |= WORD_MASK;
}
// Handle last word
bitMask = bitsRightOf(toIndex & BIT_INDEX_MASK);
bits[endUnitIndex] |= bitMask;
|
public void | set(int fromIndex, int toIndex, boolean value)Sets the bits from the specified fromIndex(inclusive) to the
specified toIndex(exclusive) to the specified value.
if (value)
set(fromIndex, toIndex);
else
clear(fromIndex, toIndex);
|
public int | size()Returns the number of bits of space actually in use by this
BitSet to represent bit values.
The maximum element in the set is the size - 1st element.
return bits.length << ADDRESS_BITS_PER_UNIT;
|
public java.lang.String | toString()Returns a string representation of this bit set. For every index
for which this BitSet contains a bit in the set
state, the decimal representation of that index is included in
the result. Such indices are listed in order from lowest to
highest, separated by ", " (a comma and a space) and
surrounded by braces, resulting in the usual mathematical
notation for a set of integers.
Overrides the toString method of Object .
Example:
BitSet drPepper = new BitSet();
Now drPepper.toString() returns "{} ".
drPepper.set(2);
Now drPepper.toString() returns "{2} ".
drPepper.set(4);
drPepper.set(10);
Now drPepper.toString() returns "{2, 4, 10} ".
int numBits = unitsInUse << ADDRESS_BITS_PER_UNIT;
StringBuffer buffer = new StringBuffer(8*numBits + 2);
String separator = "";
buffer.append('{");
for (int i = 0 ; i < numBits; i++) {
if (get(i)) {
buffer.append(separator);
separator = ", ";
buffer.append(i);
}
}
buffer.append('}");
return buffer.toString();
|
private static int | trailingZeroCnt(long val)
// Loop unrolled for performance
int byteVal = (int)val & 0xff;
if (byteVal != 0)
return trailingZeroTable[byteVal];
byteVal = (int)(val >>> 8) & 0xff;
if (byteVal != 0)
return trailingZeroTable[byteVal] + 8;
byteVal = (int)(val >>> 16) & 0xff;
if (byteVal != 0)
return trailingZeroTable[byteVal] + 16;
byteVal = (int)(val >>> 24) & 0xff;
if (byteVal != 0)
return trailingZeroTable[byteVal] + 24;
byteVal = (int)(val >>> 32) & 0xff;
if (byteVal != 0)
return trailingZeroTable[byteVal] + 32;
byteVal = (int)(val >>> 40) & 0xff;
if (byteVal != 0)
return trailingZeroTable[byteVal] + 40;
byteVal = (int)(val >>> 48) & 0xff;
if (byteVal != 0)
return trailingZeroTable[byteVal] + 48;
byteVal = (int)(val >>> 56) & 0xff;
return trailingZeroTable[byteVal] + 56;
|
private static int | unitIndex(int bitIndex)Given a bit index return unit index containing it.
return bitIndex >> ADDRESS_BITS_PER_UNIT;
|
public void | xor(java.util.BitSet set)Performs a logical XOR of this bit set with the bit set
argument. This bit set is modified so that a bit in it has the
value true if and only if one of the following
statements holds:
- The bit initially has the value
true , and the
corresponding bit in the argument has the value false .
- The bit initially has the value
false , and the
corresponding bit in the argument has the value true .
int unitsInCommon;
if (unitsInUse >= set.unitsInUse) {
unitsInCommon = set.unitsInUse;
} else {
unitsInCommon = unitsInUse;
int newUnitsInUse = set.unitsInUse;
ensureCapacity(newUnitsInUse);
unitsInUse = newUnitsInUse;
}
// Perform logical XOR on bits in common
int i;
for (i=0; i<unitsInCommon; i++)
bits[i] ^= set.bits[i];
// Copy any remaining bits
for ( ; i<set.unitsInUse; i++)
bits[i] = set.bits[i];
recalculateUnitsInUse();
|