源码分析之BitSet

来源:互联网 发布:对淘宝店铺描述怎么写 编辑:程序博客网 时间:2024/05/16 05:45

BitSet

public class BitSet implements Cloneable, java.io.Serializable {    /*     * BitSets are packed into arrays of "words."  Currently a word is     * a long, which consists of 64 bits, requiring 6 address bits.     * The choice of word size is determined purely by performance concerns.     */    private final static int ADDRESS_BITS_PER_WORD = 6;    private final static int BITS_PER_WORD = 1 << ADDRESS_BITS_PER_WORD;    private final static int BIT_INDEX_MASK = BITS_PER_WORD - 1;    /* Used to shift left or right for a partial word mask */    private static final long WORD_MASK = 0xffffffffffffffffL;    /**     * @serialField bits long[]     *     * The bits in this BitSet.  The ith bit is stored in bits[i/64] at     * bit position i % 64 (where bit position 0 refers to the least     * significant bit and 63 refers to the most significant bit).     */    private static final ObjectStreamField[] serialPersistentFields = {new ObjectStreamField("bits", long[].class),    };    /**     * The internal field corresponding to the serialField "bits".     */    private long[] words;    /**     * The number of words in the logical size of this BitSet.     */    private transient int wordsInUse = 0;    /**     * Whether the size of "words" is user-specified.  If so, we assume     * the user knows what he's doing and try harder to preserve it.     */    private transient boolean sizeIsSticky = false;    /* use serialVersionUID from JDK 1.0.2 for interoperability */    private static final long serialVersionUID = 7997698588986878753L;    /**     * Given a bit index, return word index containing it.     */    private static int wordIndex(int bitIndex) {        return bitIndex >> ADDRESS_BITS_PER_WORD;    }    /**     * Every public method must preserve these invariants.     */    private void checkInvariants() {assert(wordsInUse == 0 || words[wordsInUse - 1] != 0);assert(wordsInUse >= 0 && wordsInUse <= words.length);assert(wordsInUse == words.length || words[wordsInUse] == 0);    }    /**     * 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!     */    private void recalculateWordsInUse() {        // 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    }    /**     * Creates a new bit set. All bits are initially <code>false</code>.     */    public BitSet() {initWords(BITS_PER_WORD);sizeIsSticky = false;    }    /**     * Creates a bit set whose initial size is large enough to explicitly     * represent bits with indices in the range <code>0</code> through     * <code>nbits-1</code>. All bits are initially <code>false</code>.     *     * @param     nbits   the initial size of the bit set.     * @exception NegativeArraySizeException if the specified initial size     *               is negative.     */    public BitSet(int nbits) {// nbits can't be negative; size 0 is OKif (nbits < 0)    throw new NegativeArraySizeException("nbits < 0: " + nbits);initWords(nbits);sizeIsSticky = true;    }    private void initWords(int nbits) {words = new long[wordIndex(nbits-1) + 1];    }    /**     * Ensures that the BitSet can hold enough words.     * @param wordsRequired the minimum acceptable number of words.     */    private void ensureCapacity(int wordsRequired) {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;        }    }    /**     * 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().     * @paramwordIndex the index to be accommodated.     */    private void expandTo(int wordIndex) {int wordsRequired = wordIndex+1;if (wordsInUse < wordsRequired) {    ensureCapacity(wordsRequired);    wordsInUse = wordsRequired;}    }    /**     * Checks that fromIndex ... toIndex is a valid range of bit indices.     */    private static void checkRange(int fromIndex, int toIndex) {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);    }    /**     * Sets the bit at the specified index to the complement of its     * current value.     *     * @param   bitIndex the index of the bit to flip.     * @exception IndexOutOfBoundsException if the specified index is negative.     * @since   1.4     */    public void flip(int bitIndex) {if (bitIndex < 0)    throw new IndexOutOfBoundsException("bitIndex < 0: " + bitIndex);int wordIndex = wordIndex(bitIndex);expandTo(wordIndex);words[wordIndex] ^= (1L << bitIndex);recalculateWordsInUse();checkInvariants();    }    /**     * Sets each bit from the specified <tt>fromIndex</tt> (inclusive) to the     * specified <tt>toIndex</tt> (exclusive) to the complement of its current     * value.     *     * @param     fromIndex   index of the first bit to flip.     * @param     toIndex index after the last bit to flip.     * @exception IndexOutOfBoundsException if <tt>fromIndex</tt> is negative,     *            or <tt>toIndex</tt> is negative, or <tt>fromIndex</tt> is     *            larger than <tt>toIndex</tt>.     * @since   1.4     */    public void flip(int fromIndex, int toIndex) {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();    }    /**     * Sets the bit at the specified index to <code>true</code>.     *     * @param     bitIndex   a bit index.     * @exception IndexOutOfBoundsException if the specified index is negative.     * @since     JDK1.0     */    public void set(int bitIndex) {if (bitIndex < 0)    throw new IndexOutOfBoundsException("bitIndex < 0: " + bitIndex);        int wordIndex = wordIndex(bitIndex);expandTo(wordIndex);words[wordIndex] |= (1L << bitIndex); // Restores invariantscheckInvariants();    }    /**     * Sets the bit at the specified index to the specified value.     *     * @param     bitIndex   a bit index.     * @param     value a boolean value to set.     * @exception IndexOutOfBoundsException if the specified index is negative.     * @since     1.4     */    public void set(int bitIndex, boolean value) {        if (value)            set(bitIndex);        else            clear(bitIndex);    }    /**     * Sets the bits from the specified <tt>fromIndex</tt> (inclusive) to the     * specified <tt>toIndex</tt> (exclusive) to <code>true</code>.     *     * @param     fromIndex   index of the first bit to be set.     * @param     toIndex index after the last bit to be set.     * @exception IndexOutOfBoundsException if <tt>fromIndex</tt> is negative,     *            or <tt>toIndex</tt> is negative, or <tt>fromIndex</tt> is     *            larger than <tt>toIndex</tt>.     * @since     1.4     */    public void set(int fromIndex, int toIndex) {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();    }    /**     * Sets the bits from the specified <tt>fromIndex</tt> (inclusive) to the     * specified <tt>toIndex</tt> (exclusive) to the specified value.     *     * @param     fromIndex   index of the first bit to be set.     * @param     toIndex index after the last bit to be set     * @param     value value to set the selected bits to     * @exception IndexOutOfBoundsException if <tt>fromIndex</tt> is negative,     *            or <tt>toIndex</tt> is negative, or <tt>fromIndex</tt> is     *            larger than <tt>toIndex</tt>.     * @since     1.4     */    public void set(int fromIndex, int toIndex, boolean value) {if (value)            set(fromIndex, toIndex);        else            clear(fromIndex, toIndex);    }    /**     * Sets the bit specified by the index to <code>false</code>.     *     * @param     bitIndex   the index of the bit to be cleared.     * @exception IndexOutOfBoundsException if the specified index is negative.     * @since     JDK1.0     */    public void clear(int bitIndex) {if (bitIndex < 0)    throw new IndexOutOfBoundsException("bitIndex < 0: " + bitIndex);int wordIndex = wordIndex(bitIndex);if (wordIndex >= wordsInUse)    return;words[wordIndex] &= ~(1L << bitIndex);recalculateWordsInUse();checkInvariants();    }    /**     * Sets the bits from the specified <tt>fromIndex</tt> (inclusive) to the     * specified <tt>toIndex</tt> (exclusive) to <code>false</code>.     *     * @param     fromIndex   index of the first bit to be cleared.     * @param     toIndex index after the last bit to be cleared.     * @exception IndexOutOfBoundsException if <tt>fromIndex</tt> is negative,     *            or <tt>toIndex</tt> is negative, or <tt>fromIndex</tt> is     *            larger than <tt>toIndex</tt>.     * @since     1.4     */    public void clear(int fromIndex, int toIndex) {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();    }    /**     * Sets all of the bits in this BitSet to <code>false</code>.     *     * @since   1.4     */    public void clear() {        while (wordsInUse > 0)            words[--wordsInUse] = 0;    }    /**     * Returns the value of the bit with the specified index. The value     * is <code>true</code> if the bit with the index <code>bitIndex</code>     * is currently set in this <code>BitSet</code>; otherwise, the result     * is <code>false</code>.     *     * @param     bitIndex   the bit index.     * @return    the value of the bit with the specified index.     * @exception IndexOutOfBoundsException if the specified index is negative.     */    public boolean get(int bitIndex) {if (bitIndex < 0)    throw new IndexOutOfBoundsException("bitIndex < 0: " + bitIndex);checkInvariants();int wordIndex = wordIndex(bitIndex);return (wordIndex < wordsInUse)    && ((words[wordIndex] & (1L << bitIndex)) != 0);    }    /**     * Returns a new <tt>BitSet</tt> composed of bits from this <tt>BitSet</tt>     * from <tt>fromIndex</tt> (inclusive) to <tt>toIndex</tt> (exclusive).     *     * @param     fromIndex   index of the first bit to include.     * @param     toIndex     index after the last bit to include.     * @return    a new <tt>BitSet</tt> from a range of this <tt>BitSet</tt>.     * @exception IndexOutOfBoundsException if <tt>fromIndex</tt> is negative,     *            or <tt>toIndex</tt> is negative, or <tt>fromIndex</tt> is     *            larger than <tt>toIndex</tt>.     * @since   1.4     */    public BitSet get(int fromIndex, int toIndex) {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 wordlong 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;    }    /**     * Returns the index of the first bit that is set to <code>true</code>     * that occurs on or after the specified starting index. If no such     * bit exists then -1 is returned.     *     * To iterate over the <code>true</code> bits in a <code>BitSet</code>,     * use the following loop:     *     * <pre>     * for (int i = bs.nextSetBit(0); i >= 0; i = bs.nextSetBit(i+1)) {     *     // operate on index i here     * }</pre>     *     * @param   fromIndex the index to start checking from (inclusive).     * @return  the index of the next set bit.     * @throws  IndexOutOfBoundsException if the specified index is negative.     * @since   1.4     */    public int nextSetBit(int fromIndex) {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];}    }    /**     * Returns the index of the first bit that is set to <code>false</code>     * that occurs on or after the specified starting index.     *     * @param   fromIndex the index to start checking from (inclusive).     * @return  the index of the next clear bit.     * @throws  IndexOutOfBoundsException if the specified index is negative.     * @since   1.4     */    public int nextClearBit(int fromIndex) {// 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];}    }    /**     * Returns the "logical size" of this <code>BitSet</code>: the index of     * the highest set bit in the <code>BitSet</code> plus one. Returns zero     * if the <code>BitSet</code> contains no set bits.     *     * @return  the logical size of this <code>BitSet</code>.     * @since   1.2     */    public int length() {        if (wordsInUse == 0)            return 0;        return BITS_PER_WORD * (wordsInUse - 1) +    (BITS_PER_WORD - Long.numberOfLeadingZeros(words[wordsInUse - 1]));    }    /**     * Returns true if this <code>BitSet</code> contains no bits that are set     * to <code>true</code>.     *     * @return    boolean indicating whether this <code>BitSet</code> is empty.     * @since     1.4     */    public boolean isEmpty() {        return wordsInUse == 0;    }    /**     * Returns true if the specified <code>BitSet</code> has any bits set to     * <code>true</code> that are also set to <code>true</code> in this     * <code>BitSet</code>.     *     * @paramset <code>BitSet</code> to intersect with     * @return  boolean indicating whether this <code>BitSet</code> intersects     *          the specified <code>BitSet</code>.     * @since   1.4     */    public boolean intersects(BitSet set) {        for (int i = Math.min(wordsInUse, set.wordsInUse) - 1; i >= 0; i--)            if ((words[i] & set.words[i]) != 0)                return true;        return false;    }    /**     * Returns the number of bits set to <tt>true</tt> in this     * <code>BitSet</code>.     *     * @return  the number of bits set to <tt>true</tt> in this     *          <code>BitSet</code>.     * @since   1.4     */    public int cardinality() {        int sum = 0;        for (int i = 0; i < wordsInUse; i++)            sum += Long.bitCount(words[i]);        return sum;    }    /**     * Performs a logical <b>AND</b> of this target bit set with the     * argument bit set. This bit set is modified so that each bit in it     * has the value <code>true</code> if and only if it both initially     * had the value <code>true</code> and the corresponding bit in the     * bit set argument also had the value <code>true</code>.     *     * @param   set   a bit set.     */    public void and(BitSet set) {if (this == set)    return;while (wordsInUse > set.wordsInUse)    words[--wordsInUse] = 0;// Perform logical AND on words in commonfor (int i = 0; i < wordsInUse; i++)    words[i] &= set.words[i];recalculateWordsInUse();checkInvariants();    }    /**     * Performs a logical <b>OR</b> of this bit set with the bit set     * argument. This bit set is modified so that a bit in it has the     * value <code>true</code> if and only if it either already had the     * value <code>true</code> or the corresponding bit in the bit set     * argument has the value <code>true</code>.     *     * @param   set   a bit set.     */    public void or(BitSet set) {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 commonfor (int i = 0; i < wordsInCommon; i++)    words[i] |= set.words[i];// Copy any remaining wordsif (wordsInCommon < set.wordsInUse)    System.arraycopy(set.words, wordsInCommon,     words, wordsInCommon,     wordsInUse - wordsInCommon);// recalculateWordsInUse() is unnecessarycheckInvariants();    }    /**     * Performs a logical <b>XOR</b> of this bit set with the bit set     * argument. This bit set is modified so that a bit in it has the     * value <code>true</code> if and only if one of the following     * statements holds:     * <ul>     * <li>The bit initially has the value <code>true</code>, and the     *     corresponding bit in the argument has the value <code>false</code>.     * <li>The bit initially has the value <code>false</code>, and the     *     corresponding bit in the argument has the value <code>true</code>.     * </ul>     *     * @param   set   a bit set.     */    public void xor(BitSet set) {        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 wordsif (wordsInCommon < set.wordsInUse)    System.arraycopy(set.words, wordsInCommon,     words, wordsInCommon,     set.wordsInUse - wordsInCommon);        recalculateWordsInUse();checkInvariants();    }    /**     * Clears all of the bits in this <code>BitSet</code> whose corresponding     * bit is set in the specified <code>BitSet</code>.     *     * @param     set the <code>BitSet</code> with which to mask this     *            <code>BitSet</code>.     * @since     1.2     */    public void andNot(BitSet set) {// 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();    }    /**     * Returns a hash code value for this bit set. The hash code     * depends only on which bits have been set within this     * <code>BitSet</code>. The algorithm used to compute it may     * be described as follows.<p>     * Suppose the bits in the <code>BitSet</code> were to be stored     * in an array of <code>long</code> integers called, say,     * <code>words</code>, in such a manner that bit <code>k</code> is     * set in the <code>BitSet</code> (for nonnegative values of     * <code>k</code>) if and only if the expression     * <pre>((k>>6) < words.length) && ((words[k>>6] & (1L << (bit & 0x3F))) != 0)</pre>     * is true. Then the following definition of the <code>hashCode</code>     * method would be a correct implementation of the actual algorithm:     * <pre>     * public int hashCode() {     *      long h = 1234;     *      for (int i = words.length; --i >= 0; ) {     *           h ^= words[i] * (i + 1);     *      }     *      return (int)((h >> 32) ^ h);     * }</pre>     * Note that the hash code values change if the set of bits is altered.     * <p>Overrides the <code>hashCode</code> method of <code>Object</code>.     *     * @return  a hash code value for this bit set.     */    public int hashCode() {long h = 1234;for (int i = wordsInUse; --i >= 0; )            h ^= words[i] * (i + 1);return (int)((h >> 32) ^ h);    }    /**     * Returns the number of bits of space actually in use by this     * <code>BitSet</code> to represent bit values.     * The maximum element in the set is the size - 1st element.     *     * @return  the number of bits currently in this bit set.     */    public int size() {return words.length * BITS_PER_WORD;    }    /**     * Compares this object against the specified object.     * The result is <code>true</code> if and only if the argument is     * not <code>null</code> and is a <code>Bitset</code> object that has     * exactly the same set of bits set to <code>true</code> as this bit     * set. That is, for every nonnegative <code>int</code> index <code>k</code>,     * <pre>((BitSet)obj).get(k) == this.get(k)</pre>     * must be true. The current sizes of the two bit sets are not compared.     * <p>Overrides the <code>equals</code> method of <code>Object</code>.     *     * @param   obj   the object to compare with.     * @return  <code>true</code> if the objects are the same;     *          <code>false</code> otherwise.     * @see     java.util.BitSet#size()     */    public boolean equals(Object obj) {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 BitSetsfor (int i = 0; i < wordsInUse; i++)    if (words[i] != set.words[i])return false;return true;    }    /**     * Cloning this <code>BitSet</code> produces a new <code>BitSet</code>     * that is equal to it.     * The clone of the bit set is another bit set that has exactly the     * same bits set to <code>true</code> as this bit set.     *     * <p>Overrides the <code>clone</code> method of <code>Object</code>.     *     * @return  a clone of this bit set.     * @see     java.util.BitSet#size()     */    public Object clone() {if (! sizeIsSticky)    trimToSize();try {    BitSet result = (BitSet) super.clone();    result.words = words.clone();    result.checkInvariants();    return result;} catch (CloneNotSupportedException e) {    throw new InternalError();}    }    /**     * 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.     */    private void trimToSize() {if (wordsInUse != words.length) {            words = Arrays.copyOf(words, wordsInUse);    checkInvariants();}    }    /**     * Save the state of the <tt>BitSet</tt> instance to a stream (i.e.,     * serialize it).     */    private void writeObject(ObjectOutputStream s)throws IOException {checkInvariants();if (! sizeIsSticky)    trimToSize();ObjectOutputStream.PutField fields = s.putFields();fields.put("bits", words);s.writeFields();    }    /**     * Reconstitute the <tt>BitSet</tt> instance from a stream (i.e.,     * deserialize it).     */    private void readObject(ObjectInputStream s)        throws IOException, ClassNotFoundException {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); // heuristiccheckInvariants();    }    /**     * Returns a string representation of this bit set. For every index     * for which this <code>BitSet</code> 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.<p>     * Overrides the <code>toString</code> method of <code>Object</code>.     * <p>Example:     * <pre>     * BitSet drPepper = new BitSet();</pre>     * Now <code>drPepper.toString()</code> returns "<code>{}</code>".<p>     * <pre>     * drPepper.set(2);</pre>     * Now <code>drPepper.toString()</code> returns "<code>{2}</code>".<p>     * <pre>     * drPepper.set(4);     * drPepper.set(10);</pre>     * Now <code>drPepper.toString()</code> returns "<code>{2, 4, 10}</code>".     *     * @return  a string representation of this bit set.     */    public String toString() {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();    }}


 

原创粉丝点击