FileDocCategorySizeDatePackage
BitSet.javaAPI DocAndroid 1.5 API26842Wed May 06 22:41:04 BST 2009java.util

BitSet

public class BitSet extends Object implements Serializable, Cloneable
The {@code BitSet} class implements a bit field. Each element in a {@code BitSet} can be on(1) or off(0). A {@code BitSet} is created with a given size and grows if this size is exceeded. Growth is always rounded to a 64 bit boundary.
since
Android 1.0

Fields Summary
private static final long
serialVersionUID
private static final int
ELM_SIZE
private long[]
bits
Constructors Summary
public BitSet()
Create a new {@code BitSet} with size equal to 64 bits.

see
#clear(int)
see
#set(int)
see
#clear()
see
#clear(int, int)
see
#set(int, boolean)
see
#set(int, int)
see
#set(int, int, boolean)
since
Android 1.0


                                           
      
        this(64);
    
public BitSet(int nbits)
Create a new {@code BitSet} with size equal to nbits. If nbits is not a multiple of 64, then create a {@code BitSet} with size nbits rounded to the next closest multiple of 64.

param
nbits the size of the bit set.
throws
NegativeArraySizeException if {@code nbits} is negative.
see
#clear(int)
see
#set(int)
see
#clear()
see
#clear(int, int)
see
#set(int, boolean)
see
#set(int, int)
see
#set(int, int, boolean)
since
Android 1.0

        if (nbits >= 0) {
            bits = new long[(nbits / ELM_SIZE) + (nbits % ELM_SIZE > 0 ? 1 : 0)];
        } else {
            throw new NegativeArraySizeException();
        }
    
private BitSet(long[] bits)
Private constructor called from get(int, int) method

param
bits the size of the bit set

        this.bits = bits;
    
Methods Summary
public voidand(java.util.BitSet bs)
Performs the logical AND of this {@code BitSet} with another {@code BitSet}. The values of this {@code BitSet} are changed accordingly.

param
bs {@code BitSet} to AND with.
see
#or
see
#xor
since
Android 1.0

        long[] bsBits = bs.bits;
        int length1 = bits.length, length2 = bsBits.length;
        if (length1 <= length2) {
            for (int i = 0; i < length1; i++) {
                bits[i] &= bsBits[i];
            }
        } else {
            for (int i = 0; i < length2; i++) {
                bits[i] &= bsBits[i];
            }
            for (int i = length2; i < length1; i++) {
                bits[i] = 0;
            }
        }
    
public voidandNot(java.util.BitSet bs)
Clears all bits in the receiver which are also set in the parameter {@code BitSet}. The values of this {@code BitSet} are changed accordingly.

param
bs {@code BitSet} to ANDNOT with.
since
Android 1.0

        long[] bsBits = bs.bits;
        int range = bits.length < bsBits.length ? bits.length : bsBits.length;
        for (int i = 0; i < range; i++) {
            bits[i] &= ~bsBits[i];
        }
    
public intcardinality()
Returns the number of bits that are {@code true} in this {@code BitSet}.

return
the number of {@code true} bits in the set.
since
Android 1.0

        int count = 0;
        for (int idx = 0; idx < bits.length; idx++) {
            long temp = bits[idx];
            if (temp != 0L) {
                for (int i = 0; i < ELM_SIZE; i++) {
                    if ((temp & (1L << i)) != 0L) {
                        count++;
                    }
                }
            }
        }
        return count;
    
public voidclear()
Clears all the bits in this {@code BitSet}.

see
#clear(int)
see
#clear(int, int)
since
Android 1.0

        for (int i = 0; i < bits.length; i++) {
            bits[i] = 0L;
        }
    
public voidclear(int pos)
Clears the bit at index {@code pos}. Grows the {@code BitSet} if {@code pos > size}.

param
pos the index of the bit to clear.
throws
IndexOutOfBoundsException if {@code pos} is negative.
see
#clear(int, int)
since
Android 1.0

        if (pos >= 0) {
            if (pos < bits.length * ELM_SIZE) {
                bits[pos / ELM_SIZE] &= ~(1L << (pos % ELM_SIZE));
            }
        } else {
            // Negative index specified
            throw new IndexOutOfBoundsException(Msg.getString("K0006")); //$NON-NLS-1$
        }
    
public voidclear(int pos1, int pos2)
Clears the bits starting from {@code pos1} to {@code pos2}. Grows the {@code BitSet} if {@code pos2 > size}.

param
pos1 beginning position.
param
pos2 ending position.
throws
IndexOutOfBoundsException if {@code pos1} or {@code pos2} is negative, or if {@code pos2} is smaller than {@code pos1}.
see
#clear(int)
since
Android 1.0

        if (pos1 >= 0 && pos2 >= 0 && pos2 >= pos1) {
            int last = (bits.length * ELM_SIZE);
            if (pos1 >= last || pos1 == pos2) {
                return;
            }
            if (pos2 > last) {
                pos2 = last;
            }

            int idx1 = pos1 / ELM_SIZE;
            int idx2 = (pos2 - 1) / ELM_SIZE;
            long factor1 = (~0L) << (pos1 % ELM_SIZE);
            long factor2 = (~0L) >>> (ELM_SIZE - (pos2 % ELM_SIZE));

            if (idx1 == idx2) {
                bits[idx1] &= ~(factor1 & factor2);
            } else {
                bits[idx1] &= ~factor1;
                bits[idx2] &= ~factor2;
                for (int i = idx1 + 1; i < idx2; i++) {
                    bits[i] = 0L;
                }
            }
        } else {
            throw new IndexOutOfBoundsException(Msg.getString("K0006")); //$NON-NLS-1$
        }
    
public java.lang.Objectclone()
Creates a copy of this {@code BitSet}.

return
a copy of this {@code BitSet}.
since
Android 1.0

        try {
            BitSet clone = (BitSet) super.clone();
            clone.bits = bits.clone();
            return clone;
        } catch (CloneNotSupportedException e) {
            return null;
        }
    
public booleanequals(java.lang.Object obj)
Compares the argument to this {@code BitSet} and returns whether they are equal. The object must be an instance of {@code BitSet} with the same bits set.

param
obj the {@code BitSet} object to compare.
return
a {@code boolean} indicating whether or not this {@code BitSet} and {@code obj} are equal.
see
#hashCode
since
Android 1.0

        if (this == obj) {
            return true;
        }
        if (obj instanceof BitSet) {
            long[] bsBits = ((BitSet) obj).bits;
            int length1 = bits.length, length2 = bsBits.length;
            // If one of the BitSets is larger than the other, check to see if
            // any of
            // its extra bits are set. If so return false.
            if (length1 <= length2) {
                for (int i = 0; i < length1; i++) {
                    if (bits[i] != bsBits[i]) {
                        return false;
                    }
                }
                for (int i = length1; i < length2; i++) {
                    if (bsBits[i] != 0) {
                        return false;
                    }
                }
            } else {
                for (int i = 0; i < length2; i++) {
                    if (bits[i] != bsBits[i]) {
                        return false;
                    }
                }
                for (int i = length2; i < length1; i++) {
                    if (bits[i] != 0) {
                        return false;
                    }
                }
            }
            return true;
        }
        return false;
    
public voidflip(int pos)
Flips the bit at index {@code pos}. Grows the {@code BitSet} if {@code pos > size}.

param
pos the index of the bit to flip.
throws
IndexOutOfBoundsException if {@code pos} is negative.
see
#flip(int, int)
since
Android 1.0

        if (pos >= 0) {
            if (pos >= bits.length * ELM_SIZE) {
                growBits(pos);
            }
            bits[pos / ELM_SIZE] ^= 1L << (pos % ELM_SIZE);
        } else {
            throw new IndexOutOfBoundsException(Msg.getString("K0006")); //$NON-NLS-1$
        }
    
public voidflip(int pos1, int pos2)
Flips the bits starting from {@code pos1} to {@code pos2}. Grows the {@code BitSet} if {@code pos2 > size}.

param
pos1 beginning position.
param
pos2 ending position.
throws
IndexOutOfBoundsException if {@code pos1} or {@code pos2} is negative, or if {@code pos2} is smaller than {@code pos1}.
see
#flip(int)
since
Android 1.0

        if (pos1 >= 0 && pos2 >= 0 && pos2 >= pos1) {
            if (pos1 == pos2) {
                return;
            }
            if (pos2 >= bits.length * ELM_SIZE) {
                growBits(pos2);
            }

            int idx1 = pos1 / ELM_SIZE;
            int idx2 = (pos2 - 1) / ELM_SIZE;
            long factor1 = (~0L) << (pos1 % ELM_SIZE);
            long factor2 = (~0L) >>> (ELM_SIZE - (pos2 % ELM_SIZE));

            if (idx1 == idx2) {
                bits[idx1] ^= (factor1 & factor2);
            } else {
                bits[idx1] ^= factor1;
                bits[idx2] ^= factor2;
                for (int i = idx1 + 1; i < idx2; i++) {
                    bits[i] ^= (~0L);
                }
            }
        } else {
            throw new IndexOutOfBoundsException(Msg.getString("K0006")); //$NON-NLS-1$
        }
    
public booleanget(int pos)
Retrieves the bit at index {@code pos}. Grows the {@code BitSet} if {@code pos > size}.

param
pos the index of the bit to be retrieved.
return
{@code true} if the bit at {@code pos} is set, {@code false} otherwise.
throws
IndexOutOfBoundsException if {@code pos} is negative.
see
#clear(int)
see
#set(int)
see
#clear()
see
#clear(int, int)
see
#set(int, boolean)
see
#set(int, int)
see
#set(int, int, boolean)
since
Android 1.0

        if (pos >= 0) {
            if (pos < bits.length * ELM_SIZE) {
                return (bits[pos / ELM_SIZE] & (1L << (pos % ELM_SIZE))) != 0;
            }
            return false;
        }
        // Negative index specified
        throw new IndexOutOfBoundsException(Msg.getString("K0006")); //$NON-NLS-1$
    
public java.util.BitSetget(int pos1, int pos2)
Retrieves the bits starting from {@code pos1} to {@code pos2} and returns back a new bitset made of these bits. Grows the {@code BitSet} if {@code pos2 > size}.

param
pos1 beginning position.
param
pos2 ending position.
return
new bitset of the range specified.
throws
IndexOutOfBoundsException if {@code pos1} or {@code pos2} is negative, or if {@code pos2} is smaller than {@code pos1}.
see
#get(int)
since
Android 1.0

        if (pos1 >= 0 && pos2 >= 0 && pos2 >= pos1) {
            int last = (bits.length * ELM_SIZE);
            if (pos1 >= last || pos1 == pos2) {
                return new BitSet(0);
            }
            if (pos2 > last) {
                pos2 = last;
            }

            int idx1 = pos1 / ELM_SIZE;
            int idx2 = (pos2 - 1) / ELM_SIZE;
            long factor1 = (~0L) << (pos1 % ELM_SIZE);
            long factor2 = (~0L) >>> (ELM_SIZE - (pos2 % ELM_SIZE));

            if (idx1 == idx2) {
                long result = (bits[idx1] & (factor1 & factor2)) >>> (pos1 % ELM_SIZE);
                return new BitSet(new long[] { result });
            }
            long[] newbits = new long[idx2 - idx1 + 1];
            // first fill in the first and last indexes in the new bitset
            newbits[0] = bits[idx1] & factor1;
            newbits[newbits.length - 1] = bits[idx2] & factor2;

            // fill in the in between elements of the new bitset
            for (int i = 1; i < idx2 - idx1; i++) {
                newbits[i] = bits[idx1 + i];
            }

            // shift all the elements in the new bitset to the right by pos1
            // % ELM_SIZE
            int numBitsToShift = pos1 % ELM_SIZE;
            if (numBitsToShift != 0) {
                for (int i = 0; i < newbits.length; i++) {
                    // shift the current element to the right regardless of
                    // sign
                    newbits[i] = newbits[i] >>> (numBitsToShift);

                    // apply the last x bits of newbits[i+1] to the current
                    // element
                    if (i != newbits.length - 1) {
                        newbits[i] |= newbits[i + 1] << (ELM_SIZE - (numBitsToShift));
                    }
                }
            }
            return new BitSet(newbits);
        }
        throw new IndexOutOfBoundsException(Msg.getString("K0006")); //$NON-NLS-1$
    
private voidgrowBits(int pos)
Increase the size of the internal array to accommodate {@code pos} bits. The new array max index will be a multiple of 64.

param
pos the index the new array needs to be able to access.
since
Android 1.0

        pos++; // Inc to get correct bit count
        long[] tempBits = new long[(pos / ELM_SIZE)
                + (pos % ELM_SIZE > 0 ? 1 : 0)];
        System.arraycopy(bits, 0, tempBits, 0, bits.length);
        bits = tempBits;
    
public inthashCode()
Computes the hash code for this {@code BitSet}. If two {@code BitSet}s are equal the have to return the same result for {@code hashCode()}.

return
the {@code int} representing the hash code for this bit set.
see
#equals
see
java.util.Hashtable
since
Android 1.0

        long x = 1234;
        // for (int i = 0, length = bits.length; i < length; i+=2)
        // x ^= (bits[i] + ((long)bits[i+1] << 32)) * (i/2 + 1);
        for (int i = 0, length = bits.length; i < length; i++) {
            x ^= bits[i] * (i + 1);
        }
        return (int) ((x >> 32) ^ x);
    
public booleanintersects(java.util.BitSet bs)
Checks if these two {@code BitSet}s have at least one bit set to true in the same position.

param
bs {@code BitSet} used to calculate the intersection.
return
{@code true} if bs intersects with this {@code BitSet}, {@code false} otherwise.
since
Android 1.0

        long[] bsBits = bs.bits;
        int length1 = bits.length, length2 = bsBits.length;

        if (length1 <= length2) {
            for (int i = 0; i < length1; i++) {
                if ((bits[i] & bsBits[i]) != 0L) {
                    return true;
                }
            }
        } else {
            for (int i = 0; i < length2; i++) {
                if ((bits[i] & bsBits[i]) != 0L) {
                    return true;
                }
            }
        }

        return false;
    
public booleanisEmpty()
Returns true if all the bits in this {@code BitSet} are set to false.

return
{@code true} if the {@code BitSet} is empty, {@code false} otherwise.
since
Android 1.0

        for (int idx = 0; idx < bits.length; idx++) {
            if (bits[idx] != 0L) {
                return false;
            }
        }

        return true;
    
public intlength()
Returns the number of bits up to and including the highest bit set.

return
the length of the {@code BitSet}.
since
Android 1.0

        int idx = bits.length - 1;
        while (idx >= 0 && bits[idx] == 0) {
            --idx;
        }
        if (idx == -1) {
            return 0;
        }
        int i = ELM_SIZE - 1;
        long val = bits[idx];
        while ((val & (1L << i)) == 0 && i > 0) {
            i--;
        }
        return idx * ELM_SIZE + i + 1;
    
public intnextClearBit(int pos)
Returns the position of the first bit that is {@code false} on or after {@code pos}.

param
pos the starting position (inclusive).
return
the position of the next bit set to {@code false}, even if it is further than this {@code BitSet}'s size.
since
Android 1.0

        if (pos >= 0) {
            int bssize = bits.length * ELM_SIZE;
            if (pos >= bssize) {
                return pos;
            }

            int idx = pos / ELM_SIZE;
            // first check in the same bit set element
            if (bits[idx] != (~0L)) {
                for (int j = pos % ELM_SIZE; j < ELM_SIZE; j++) {
                    if (((bits[idx] & (1L << j)) == 0)) {
                        return idx * ELM_SIZE + j;
                    }
                }

            }
            idx++;
            while (idx < bits.length && bits[idx] == (~0L)) {
                idx++;
            }
            if (idx == bits.length) {
                return bssize;
            }

            // we know for sure there is a bit set to true in this element
            // since the bitset value is not 0L
            for (int j = 0; j < ELM_SIZE; j++) {
                if (((bits[idx] & (1L << j)) == 0)) {
                    return idx * ELM_SIZE + j;
                }
            }

            return bssize;
        }
        throw new IndexOutOfBoundsException(Msg.getString("K0006")); //$NON-NLS-1$
    
public intnextSetBit(int pos)
Returns the position of the first bit that is {@code true} on or after {@code pos}.

param
pos the starting position (inclusive).
return
-1 if there is no bits that are set to {@code true} on or after {@code pos}.
since
Android 1.0

        if (pos >= 0) {
            if (pos >= bits.length * ELM_SIZE) {
                return -1;
            }

            int idx = pos / ELM_SIZE;
            // first check in the same bit set element
            if (bits[idx] != 0L) {
                for (int j = pos % ELM_SIZE; j < ELM_SIZE; j++) {
                    if (((bits[idx] & (1L << j)) != 0)) {
                        return idx * ELM_SIZE + j;
                    }
                }

            }
            idx++;
            while (idx < bits.length && bits[idx] == 0L) {
                idx++;
            }
            if (idx == bits.length) {
                return -1;
            }

            // we know for sure there is a bit set to true in this element
            // since the bitset value is not 0L
            for (int j = 0; j < ELM_SIZE; j++) {
                if (((bits[idx] & (1L << j)) != 0)) {
                    return idx * ELM_SIZE + j;
                }
            }

            return -1;
        }
        throw new IndexOutOfBoundsException(Msg.getString("K0006")); //$NON-NLS-1$
    
public voidor(java.util.BitSet bs)
Performs the logical OR of this {@code BitSet} with another {@code BitSet}. The values of this {@code BitSet} are changed accordingly.

param
bs {@code BitSet} to OR with.
see
#xor
see
#and
since
Android 1.0

        int nbits = bs.length();
        int length = nbits / ELM_SIZE + (nbits % ELM_SIZE > 0 ? 1 : 0);
        if (length > bits.length) {
            growBits(nbits - 1);
        }
        long[] bsBits = bs.bits;
        for (int i = 0; i < length; i++) {
            bits[i] |= bsBits[i];
        }
    
public voidset(int pos)
Sets the bit at index {@code pos} to 1. Grows the {@code BitSet} if {@code pos > size}.

param
pos the index of the bit to set.
throws
IndexOutOfBoundsException if {@code pos} is negative.
see
#clear(int)
see
#clear()
see
#clear(int, int)
since
Android 1.0

        if (pos >= 0) {
            if (pos >= bits.length * ELM_SIZE) {
                growBits(pos);
            }
            bits[pos / ELM_SIZE] |= 1L << (pos % ELM_SIZE);
        } else {
            throw new IndexOutOfBoundsException(Msg.getString("K0006")); //$NON-NLS-1$
        }
    
public voidset(int pos, boolean val)
Sets the bit at index {@code pos} to {@code val}. Grows the {@code BitSet} if {@code pos > size}.

param
pos the index of the bit to set.
param
val value to set the bit.
throws
IndexOutOfBoundsException if {@code pos} is negative.
see
#set(int)
since
Android 1.0

        if (val) {
            set(pos);
        } else {
            clear(pos);
        }
    
public voidset(int pos1, int pos2)
Sets the bits starting from {@code pos1} to {@code pos2}. Grows the {@code BitSet} if {@code pos2 > size}.

param
pos1 beginning position.
param
pos2 ending position.
throws
IndexOutOfBoundsException if {@code pos1} or {@code pos2} is negative, or if {@code pos2} is smaller than {@code pos1}.
see
#set(int)
since
Android 1.0

        if (pos1 >= 0 && pos2 >= 0 && pos2 >= pos1) {
            if (pos1 == pos2) {
                return;
            }
            if (pos2 >= bits.length * ELM_SIZE) {
                growBits(pos2);
            }

            int idx1 = pos1 / ELM_SIZE;
            int idx2 = (pos2 - 1) / ELM_SIZE;
            long factor1 = (~0L) << (pos1 % ELM_SIZE);
            long factor2 = (~0L) >>> (ELM_SIZE - (pos2 % ELM_SIZE));

            if (idx1 == idx2) {
                bits[idx1] |= (factor1 & factor2);
            } else {
                bits[idx1] |= factor1;
                bits[idx2] |= factor2;
                for (int i = idx1 + 1; i < idx2; i++) {
                    bits[i] |= (~0L);
                }
            }
        } else {
            throw new IndexOutOfBoundsException(Msg.getString("K0006")); //$NON-NLS-1$
        }
    
public voidset(int pos1, int pos2, boolean val)
Sets the bits starting from {@code pos1} to {@code pos2} to the given {@code val}. Grows the {@code BitSet} if {@code pos2 > size}.

param
pos1 beginning position.
param
pos2 ending position.
param
val value to set these bits.
throws
IndexOutOfBoundsException if {@code pos1} or {@code pos2} is negative, or if {@code pos2} is smaller than {@code pos1}.
see
#set(int,int)
since
Android 1.0

        if (val) {
            set(pos1, pos2);
        } else {
            clear(pos1, pos2);
        }
    
public intsize()
Returns the number of bits this {@code BitSet} has.

return
the number of bits contained in this {@code BitSet}.
see
#length
since
Android 1.0

        return bits.length * ELM_SIZE;
    
public java.lang.StringtoString()
Returns a string containing a concise, human-readable description of the receiver.

return
a comma delimited list of the indices of all bits that are set.
since
Android 1.0

        StringBuffer sb = new StringBuffer(bits.length / 2);
        int bitCount = 0;
        sb.append('{");
        boolean comma = false;
        for (int i = 0; i < bits.length; i++) {
            if (bits[i] == 0) {
                bitCount += ELM_SIZE;
                continue;
            }
            for (int j = 0; j < ELM_SIZE; j++) {
                if (((bits[i] & (1L << j)) != 0)) {
                    if (comma) {
                        sb.append(", "); //$NON-NLS-1$
                    }
                    sb.append(bitCount);
                    comma = true;
                }
                bitCount++;
            }
        }
        sb.append('}");
        return sb.toString();
    
public voidxor(java.util.BitSet bs)
Performs the logical XOR of this {@code BitSet} with another {@code BitSet}. The values of this {@code BitSet} are changed accordingly.

param
bs {@code BitSet} to XOR with.
see
#or
see
#and
since
Android 1.0

        int nbits = bs.length();
        int length = nbits / ELM_SIZE + (nbits % ELM_SIZE > 0 ? 1 : 0);
        if (length > bits.length) {
            growBits(nbits - 1);
        }
        long[] bsBits = bs.bits;
        for (int i = 0; i < length; i++) {
            bits[i] ^= bsBits[i];
        }