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;
while (wordsInUse > set.wordsInUse)
words[--wordsInUse] = 0;
// Perform logical AND on words in common
for (int i = 0; i < wordsInUse; i++)
words[i] &= set.words[i];
recalculateWordsInUse();
checkInvariants();
|
public void | andNot(java.util.BitSet set)Clears all of the bits in this BitSet whose corresponding
bit is set in the specified BitSet .
// Perform logical (a & !b) on words in common
for (int i = Math.min(wordsInUse, set.wordsInUse) - 1; i >= 0; i--)
words[i] &= ~set.words[i];
recalculateWordsInUse();
checkInvariants();
|
public int | cardinality()Returns the number of bits set to true in this
BitSet .
int sum = 0;
for (int i = 0; i < wordsInUse; i++)
sum += Long.bitCount(words[i]);
return sum;
|
private void | checkInvariants()Every public method must preserve these invariants.
assert(wordsInUse == 0 || words[wordsInUse - 1] != 0);
assert(wordsInUse >= 0 && wordsInUse <= words.length);
assert(wordsInUse == words.length || words[wordsInUse] == 0);
|
private static void | checkRange(int fromIndex, int toIndex)Checks that fromIndex ... toIndex is a valid range of bit indices.
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);
|
public void | clear(int bitIndex)Sets the bit specified by the index to false .
if (bitIndex < 0)
throw new IndexOutOfBoundsException("bitIndex < 0: " + bitIndex);
int wordIndex = wordIndex(bitIndex);
if (wordIndex >= wordsInUse)
return;
words[wordIndex] &= ~(1L << bitIndex);
recalculateWordsInUse();
checkInvariants();
|
public void | clear(int fromIndex, int toIndex)Sets the bits from the specified fromIndex (inclusive) to the
specified toIndex (exclusive) to false .
checkRange(fromIndex, toIndex);
if (fromIndex == toIndex)
return;
int startWordIndex = wordIndex(fromIndex);
if (startWordIndex >= wordsInUse)
return;
int endWordIndex = wordIndex(toIndex - 1);
if (endWordIndex >= wordsInUse) {
toIndex = length();
endWordIndex = wordsInUse - 1;
}
long firstWordMask = WORD_MASK << fromIndex;
long lastWordMask = WORD_MASK >>> -toIndex;
if (startWordIndex == endWordIndex) {
// Case 1: One word
words[startWordIndex] &= ~(firstWordMask & lastWordMask);
} else {
// Case 2: Multiple words
// Handle first word
words[startWordIndex] &= ~firstWordMask;
// Handle intermediate words, if any
for (int i = startWordIndex+1; i < endWordIndex; i++)
words[i] = 0;
// Handle last word
words[endWordIndex] &= ~lastWordMask;
}
recalculateWordsInUse();
checkInvariants();
|
public void | clear()Sets all of the bits in this BitSet to false .
while (wordsInUse > 0)
words[--wordsInUse] = 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.
Overrides the clone method of Object .
if (! sizeIsSticky)
trimToSize();
try {
BitSet result = (BitSet) super.clone();
result.words = words.clone();
result.checkInvariants();
return result;
} catch (CloneNotSupportedException e) {
throw new InternalError();
}
|
private void | ensureCapacity(int wordsRequired)Ensures that the BitSet can hold enough words.
if (words.length < wordsRequired) {
// Allocate larger of doubled size or required size
int request = Math.max(2 * words.length, wordsRequired);
words = Arrays.copyOf(words, request);
sizeIsSticky = false;
}
|
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;
checkInvariants();
set.checkInvariants();
if (wordsInUse != set.wordsInUse)
return false;
// Check words in use by both BitSets
for (int i = 0; i < wordsInUse; i++)
if (words[i] != set.words[i])
return false;
return true;
|
private void | expandTo(int wordIndex)Ensures that the BitSet can accommodate a given wordIndex,
temporarily violating the invariants. The caller must
restore the invariants before returning to the user,
possibly using recalculateWordsInUse().
int wordsRequired = wordIndex+1;
if (wordsInUse < wordsRequired) {
ensureCapacity(wordsRequired);
wordsInUse = wordsRequired;
}
|
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 wordIndex = wordIndex(bitIndex);
expandTo(wordIndex);
words[wordIndex] ^= (1L << bitIndex);
recalculateWordsInUse();
checkInvariants();
|
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.
checkRange(fromIndex, toIndex);
if (fromIndex == toIndex)
return;
int startWordIndex = wordIndex(fromIndex);
int endWordIndex = wordIndex(toIndex - 1);
expandTo(endWordIndex);
long firstWordMask = WORD_MASK << fromIndex;
long lastWordMask = WORD_MASK >>> -toIndex;
if (startWordIndex == endWordIndex) {
// Case 1: One word
words[startWordIndex] ^= (firstWordMask & lastWordMask);
} else {
// Case 2: Multiple words
// Handle first word
words[startWordIndex] ^= firstWordMask;
// Handle intermediate words, if any
for (int i = startWordIndex+1; i < endWordIndex; i++)
words[i] ^= WORD_MASK;
// Handle last word
words[endWordIndex] ^= lastWordMask;
}
recalculateWordsInUse();
checkInvariants();
|
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);
checkInvariants();
int wordIndex = wordIndex(bitIndex);
return (wordIndex < wordsInUse)
&& ((words[wordIndex] & (1L << bitIndex)) != 0);
|
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).
checkRange(fromIndex, toIndex);
checkInvariants();
int len = length();
// If no set bits in range return empty bitset
if (len <= fromIndex || fromIndex == toIndex)
return new BitSet(0);
// An optimization
if (toIndex > len)
toIndex = len;
BitSet result = new BitSet(toIndex - fromIndex);
int targetWords = wordIndex(toIndex - fromIndex - 1) + 1;
int sourceIndex = wordIndex(fromIndex);
boolean wordAligned = ((fromIndex & BIT_INDEX_MASK) == 0);
// Process all words but the last word
for (int i = 0; i < targetWords - 1; i++, sourceIndex++)
result.words[i] = wordAligned ? words[sourceIndex] :
(words[sourceIndex] >>> fromIndex) |
(words[sourceIndex+1] << -fromIndex);
// Process the last word
long lastWordMask = WORD_MASK >>> -toIndex;
result.words[targetWords - 1] =
((toIndex-1) & BIT_INDEX_MASK) < (fromIndex & BIT_INDEX_MASK)
? /* straddles source words */
((words[sourceIndex] >>> fromIndex) |
(words[sourceIndex+1] & lastWordMask) << -fromIndex)
:
((words[sourceIndex] & lastWordMask) >>> fromIndex);
// Set wordsInUse correctly
result.wordsInUse = targetWords;
result.recalculateWordsInUse();
result.checkInvariants();
return result;
|
public int | hashCode()Returns a hash code value for this bit set. The hash 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,
words , 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) < words.length) && ((words[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 = words.length; --i >= 0; ) {
h ^= words[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 = wordsInUse; --i >= 0; )
h ^= words[i] * (i + 1);
return (int)((h >> 32) ^ h);
|
private void | initWords(int nbits)
words = new long[wordIndex(nbits-1) + 1];
|
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(wordsInUse, set.wordsInUse) - 1; i >= 0; i--)
if ((words[i] & set.words[i]) != 0)
return true;
return false;
|
public boolean | isEmpty()Returns true if this BitSet contains no bits that are set
to true .
return wordsInUse == 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 (wordsInUse == 0)
return 0;
return BITS_PER_WORD * (wordsInUse - 1) +
(BITS_PER_WORD - Long.numberOfLeadingZeros(words[wordsInUse - 1]));
|
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.
// Neither spec nor implementation handle bitsets of maximal length.
// See 4816253.
if (fromIndex < 0)
throw new IndexOutOfBoundsException("fromIndex < 0: " + fromIndex);
checkInvariants();
int u = wordIndex(fromIndex);
if (u >= wordsInUse)
return fromIndex;
long word = ~words[u] & (WORD_MASK << fromIndex);
while (true) {
if (word != 0)
return (u * BITS_PER_WORD) + Long.numberOfTrailingZeros(word);
if (++u == wordsInUse)
return wordsInUse * BITS_PER_WORD;
word = ~words[u];
}
|
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);
checkInvariants();
int u = wordIndex(fromIndex);
if (u >= wordsInUse)
return -1;
long word = words[u] & (WORD_MASK << fromIndex);
while (true) {
if (word != 0)
return (u * BITS_PER_WORD) + Long.numberOfTrailingZeros(word);
if (++u == wordsInUse)
return -1;
word = words[u];
}
|
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;
int wordsInCommon = Math.min(wordsInUse, set.wordsInUse);
if (wordsInUse < set.wordsInUse) {
ensureCapacity(set.wordsInUse);
wordsInUse = set.wordsInUse;
}
// Perform logical OR on words in common
for (int i = 0; i < wordsInCommon; i++)
words[i] |= set.words[i];
// Copy any remaining words
if (wordsInCommon < set.wordsInUse)
System.arraycopy(set.words, wordsInCommon,
words, wordsInCommon,
wordsInUse - wordsInCommon);
// recalculateWordsInUse() is unnecessary
checkInvariants();
|
private void | readObject(java.io.ObjectInputStream s)Reconstitute the BitSet instance from a stream (i.e.,
deserialize it).
ObjectInputStream.GetField fields = s.readFields();
words = (long[]) fields.get("bits", null);
// Assume maximum length then find real length
// because recalculateWordsInUse assumes maintenance
// or reduction in logical size
wordsInUse = words.length;
recalculateWordsInUse();
sizeIsSticky = (words.length > 0 && words[words.length-1] == 0L); // heuristic
checkInvariants();
|
private void | recalculateWordsInUse()Set the field wordsInUse with the logical size in words of the bit
set. WARNING:This method assumes that the number of words actually
in use is less than or equal to the current value of wordsInUse!
// Traverse the bitset until a used word is found
int i;
for (i = wordsInUse-1; i >= 0; i--)
if (words[i] != 0)
break;
wordsInUse = 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 wordIndex = wordIndex(bitIndex);
expandTo(wordIndex);
words[wordIndex] |= (1L << bitIndex); // Restores invariants
checkInvariants();
|
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 .
checkRange(fromIndex, toIndex);
if (fromIndex == toIndex)
return;
// Increase capacity if necessary
int startWordIndex = wordIndex(fromIndex);
int endWordIndex = wordIndex(toIndex - 1);
expandTo(endWordIndex);
long firstWordMask = WORD_MASK << fromIndex;
long lastWordMask = WORD_MASK >>> -toIndex;
if (startWordIndex == endWordIndex) {
// Case 1: One word
words[startWordIndex] |= (firstWordMask & lastWordMask);
} else {
// Case 2: Multiple words
// Handle first word
words[startWordIndex] |= firstWordMask;
// Handle intermediate words, if any
for (int i = startWordIndex+1; i < endWordIndex; i++)
words[i] = WORD_MASK;
// Handle last word (restores invariants)
words[endWordIndex] |= lastWordMask;
}
checkInvariants();
|
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 words.length * BITS_PER_WORD;
|
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} ".
checkInvariants();
int numBits = (wordsInUse > 128) ?
cardinality() : wordsInUse * BITS_PER_WORD;
StringBuilder b = new StringBuilder(6*numBits + 2);
b.append('{");
int i = nextSetBit(0);
if (i != -1) {
b.append(i);
for (i = nextSetBit(i+1); i >= 0; i = nextSetBit(i+1)) {
int endOfRun = nextClearBit(i);
do { b.append(", ").append(i); }
while (++i < endOfRun);
}
}
b.append('}");
return b.toString();
|
private void | trimToSize()Attempts to reduce internal storage used for the bits in this bit set.
Calling this method may, but is not required to, affect the value
returned by a subsequent call to the {@link #size()} method.
if (wordsInUse != words.length) {
words = Arrays.copyOf(words, wordsInUse);
checkInvariants();
}
|
private static int | wordIndex(int bitIndex)Given a bit index, return word index containing it.
return bitIndex >> ADDRESS_BITS_PER_WORD;
|
private void | writeObject(java.io.ObjectOutputStream s)Save the state of the BitSet instance to a stream (i.e.,
serialize it).
checkInvariants();
if (! sizeIsSticky)
trimToSize();
ObjectOutputStream.PutField fields = s.putFields();
fields.put("bits", words);
s.writeFields();
|
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 wordsInCommon = Math.min(wordsInUse, set.wordsInUse);
if (wordsInUse < set.wordsInUse) {
ensureCapacity(set.wordsInUse);
wordsInUse = set.wordsInUse;
}
// Perform logical XOR on words in common
for (int i = 0; i < wordsInCommon; i++)
words[i] ^= set.words[i];
// Copy any remaining words
if (wordsInCommon < set.wordsInUse)
System.arraycopy(set.words, wordsInCommon,
words, wordsInCommon,
set.wordsInUse - wordsInCommon);
recalculateWordsInUse();
checkInvariants();
|