Home | History | Annotate | Download | only in util
      1 /*
      2  *  Licensed to the Apache Software Foundation (ASF) under one or more
      3  *  contributor license agreements.  See the NOTICE file distributed with
      4  *  this work for additional information regarding copyright ownership.
      5  *  The ASF licenses this file to You under the Apache License, Version 2.0
      6  *  (the "License"); you may not use this file except in compliance with
      7  *  the License.  You may obtain a copy of the License at
      8  *
      9  *     http://www.apache.org/licenses/LICENSE-2.0
     10  *
     11  *  Unless required by applicable law or agreed to in writing, software
     12  *  distributed under the License is distributed on an "AS IS" BASIS,
     13  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     14  *  See the License for the specific language governing permissions and
     15  *  limitations under the License.
     16  */
     17 
     18 package java.util;
     19 
     20 import java.io.IOException;
     21 import java.io.ObjectInputStream;
     22 import java.io.Serializable;
     23 import java.nio.ByteBuffer;
     24 import java.nio.ByteOrder;
     25 import java.nio.LongBuffer;
     26 import libcore.io.SizeOf;
     27 
     28 /**
     29  * The {@code BitSet} class implements a
     30  * <a href="http://en.wikipedia.org/wiki/Bit_array">bit array</a>.
     31  * Each element is either true or false. A {@code BitSet} is created with a given size and grows
     32  * automatically if this size is exceeded.
     33  */
     34 public class BitSet implements Serializable, Cloneable {
     35     private static final long serialVersionUID = 7997698588986878753L;
     36 
     37     private static final long ALL_ONES = ~0L;
     38 
     39     /**
     40      * The bits. Access bit n thus:
     41      *
     42      *   boolean bit = (bits[n / 64] | (1 << n)) != 0;
     43      *
     44      * Note that Java's shift operators truncate their rhs to the log2 size of the lhs.
     45      * That is, there's no "% 64" needed because it's implicit in the shift.
     46      *
     47      * TODO: would int[] be significantly more efficient for Android at the moment?
     48      */
     49     private long[] bits;
     50 
     51     /**
     52      * The number of elements of 'bits' that are actually in use (non-zero). Amongst other
     53      * things, this guarantees that isEmpty is cheap, because we never have to examine the array.
     54      */
     55     private transient int longCount;
     56 
     57     /**
     58      * Updates 'longCount' by inspecting 'bits'. Assumes that the new longCount is <= the current
     59      * longCount, to avoid scanning large tracts of empty array. This means it's safe to call
     60      * directly after a clear operation that may have cleared the highest set bit, but
     61      * not safe after an xor operation that may have cleared the highest set bit or
     62      * made a new highest set bit. In that case, you'd need to set 'longCount' to a conservative
     63      * estimate before calling this method.
     64      */
     65     private void shrinkSize() {
     66         int i = longCount - 1;
     67         while (i >= 0 && bits[i] == 0) {
     68             --i;
     69         }
     70         this.longCount = i + 1;
     71     }
     72 
     73     /**
     74      * Creates a new {@code BitSet} with size equal to 64 bits.
     75      */
     76     public BitSet() {
     77         this(new long[1]);
     78     }
     79 
     80     /**
     81      * Creates a new {@code BitSet} with size equal to {@code bitCount}, rounded up to
     82      * a multiple of 64.
     83      *
     84      * @throws NegativeArraySizeException if {@code bitCount < 0}.
     85      */
     86     public BitSet(int bitCount) {
     87         if (bitCount < 0) {
     88             throw new NegativeArraySizeException(Integer.toString(bitCount));
     89         }
     90         this.bits = arrayForBits(bitCount);
     91         this.longCount = 0;
     92     }
     93 
     94     private BitSet(long[] bits) {
     95         this.bits = bits;
     96         this.longCount = bits.length;
     97         shrinkSize();
     98     }
     99 
    100     private static long[] arrayForBits(int bitCount) {
    101         return new long[(bitCount + 63)/ 64];
    102     }
    103 
    104     @Override public Object clone() {
    105         try {
    106             BitSet clone = (BitSet) super.clone();
    107             clone.bits = bits.clone();
    108             clone.shrinkSize();
    109             return clone;
    110         } catch (CloneNotSupportedException e) {
    111             throw new AssertionError(e);
    112         }
    113     }
    114 
    115     @Override public boolean equals(Object o) {
    116         if (this == o) {
    117             return true;
    118         }
    119         if (!(o instanceof BitSet)) {
    120             return false;
    121         }
    122         BitSet lhs = (BitSet) o;
    123         if (this.longCount != lhs.longCount) {
    124             return false;
    125         }
    126         for (int i = 0; i < longCount; ++i) {
    127             if (bits[i] != lhs.bits[i]) {
    128                 return false;
    129             }
    130         }
    131         return true;
    132     }
    133 
    134     /**
    135      * Ensures that our long[] can hold at least 64 * desiredLongCount bits.
    136      */
    137     private void ensureCapacity(int desiredLongCount) {
    138         if (desiredLongCount <= bits.length) {
    139             return;
    140         }
    141         int newLength = Math.max(desiredLongCount, bits.length * 2);
    142         long[] newBits = new long[newLength];
    143         System.arraycopy(bits, 0, newBits, 0, longCount);
    144         this.bits = newBits;
    145         // 'longCount' is unchanged by this operation: the long[] is larger,
    146         // but you're not yet using any more of it.
    147     }
    148 
    149     @Override public int hashCode() {
    150         // The RI doesn't use Arrays.hashCode, and explicitly specifies this algorithm.
    151         long x = 1234;
    152         for (int i = 0; i < longCount; ++i) {
    153             x ^= bits[i] * (i + 1);
    154         }
    155         return (int) ((x >> 32) ^ x);
    156     }
    157 
    158     /**
    159      * Returns the bit at index {@code index}. Indexes greater than the current length return false.
    160      *
    161      * @throws IndexOutOfBoundsException if {@code index < 0}.
    162      */
    163     public boolean get(int index) {
    164         if (index < 0) { // TODO: until we have an inlining JIT.
    165             checkIndex(index);
    166         }
    167         int arrayIndex = index / 64;
    168         if (arrayIndex >= longCount) {
    169             return false;
    170         }
    171         return (bits[arrayIndex] & (1L << index)) != 0;
    172     }
    173 
    174     /**
    175      * Sets the bit at index {@code index} to true.
    176      *
    177      * @throws IndexOutOfBoundsException if {@code index < 0}.
    178      */
    179     public void set(int index) {
    180         if (index < 0) { // TODO: until we have an inlining JIT.
    181             checkIndex(index);
    182         }
    183         int arrayIndex = index / 64;
    184         if (arrayIndex >= bits.length) {
    185             ensureCapacity(arrayIndex + 1);
    186         }
    187         bits[arrayIndex] |= (1L << index);
    188         longCount = Math.max(longCount, arrayIndex + 1);
    189     }
    190 
    191     /**
    192      * Clears the bit at index {@code index}.
    193      *
    194      * @throws IndexOutOfBoundsException if {@code index < 0}.
    195      */
    196     public void clear(int index) {
    197         if (index < 0) { // TODO: until we have an inlining JIT.
    198             checkIndex(index);
    199         }
    200         int arrayIndex = index / 64;
    201         if (arrayIndex >= longCount) {
    202             return;
    203         }
    204         bits[arrayIndex] &= ~(1L << index);
    205         shrinkSize();
    206     }
    207 
    208     /**
    209      * Flips the bit at index {@code index}.
    210      *
    211      * @throws IndexOutOfBoundsException if {@code index < 0}.
    212      */
    213     public void flip(int index) {
    214         if (index < 0) { // TODO: until we have an inlining JIT.
    215             checkIndex(index);
    216         }
    217         int arrayIndex = index / 64;
    218         if (arrayIndex >= bits.length) {
    219             ensureCapacity(arrayIndex + 1);
    220         }
    221         bits[arrayIndex] ^= (1L << index);
    222         longCount = Math.max(longCount, arrayIndex + 1);
    223         shrinkSize();
    224     }
    225 
    226     private void checkIndex(int index) {
    227         if (index < 0) {
    228             throw new IndexOutOfBoundsException("index < 0: " + index);
    229         }
    230     }
    231 
    232     private void checkRange(int fromIndex, int toIndex) {
    233         if ((fromIndex | toIndex) < 0 || toIndex < fromIndex) {
    234             throw new IndexOutOfBoundsException("fromIndex=" + fromIndex + " toIndex=" + toIndex);
    235         }
    236     }
    237 
    238     /**
    239      * Returns a new {@code BitSet} containing the
    240      * range of bits {@code [fromIndex, toIndex)}, shifted down so that the bit
    241      * at {@code fromIndex} is at bit 0 in the new {@code BitSet}.
    242      *
    243      * @throws IndexOutOfBoundsException
    244      *             if {@code fromIndex} or {@code toIndex} is negative, or if
    245      *             {@code toIndex} is smaller than {@code fromIndex}.
    246      */
    247     public BitSet get(int fromIndex, int toIndex) {
    248         checkRange(fromIndex, toIndex);
    249 
    250         int last = 64 * longCount;
    251         if (fromIndex >= last || fromIndex == toIndex) {
    252             return new BitSet(0);
    253         }
    254         if (toIndex > last) {
    255             toIndex = last;
    256         }
    257 
    258         int firstArrayIndex = fromIndex / 64;
    259         int lastArrayIndex = (toIndex - 1) / 64;
    260         long lowMask = ALL_ONES << fromIndex;
    261         long highMask = ALL_ONES >>> -toIndex;
    262 
    263         if (firstArrayIndex == lastArrayIndex) {
    264             long result = (bits[firstArrayIndex] & (lowMask & highMask)) >>> fromIndex;
    265             if (result == 0) {
    266                 return new BitSet(0);
    267             }
    268             return new BitSet(new long[] { result });
    269         }
    270 
    271         long[] newBits = new long[lastArrayIndex - firstArrayIndex + 1];
    272 
    273         // first fill in the first and last indexes in the new BitSet
    274         newBits[0] = bits[firstArrayIndex] & lowMask;
    275         newBits[newBits.length - 1] = bits[lastArrayIndex] & highMask;
    276 
    277         // fill in the in between elements of the new BitSet
    278         for (int i = 1; i < lastArrayIndex - firstArrayIndex; i++) {
    279             newBits[i] = bits[firstArrayIndex + i];
    280         }
    281 
    282         // shift all the elements in the new BitSet to the right
    283         int numBitsToShift = fromIndex % 64;
    284         int actualLen = newBits.length;
    285         if (numBitsToShift != 0) {
    286             for (int i = 0; i < newBits.length; i++) {
    287                 // shift the current element to the right regardless of
    288                 // sign
    289                 newBits[i] = newBits[i] >>> (numBitsToShift);
    290 
    291                 // apply the last x bits of newBits[i+1] to the current
    292                 // element
    293                 if (i != newBits.length - 1) {
    294                     newBits[i] |= newBits[i + 1] << -numBitsToShift;
    295                 }
    296                 if (newBits[i] != 0) {
    297                     actualLen = i + 1;
    298                 }
    299             }
    300         }
    301         return new BitSet(newBits);
    302     }
    303 
    304     /**
    305      * Sets the bit at index {@code index} to {@code state}.
    306      *
    307      * @throws IndexOutOfBoundsException if {@code index < 0}.
    308      */
    309     public void set(int index, boolean state) {
    310         if (state) {
    311             set(index);
    312         } else {
    313             clear(index);
    314         }
    315     }
    316 
    317     /**
    318      * Sets the range of bits {@code [fromIndex, toIndex)} to {@code state}.
    319      *
    320      * @throws IndexOutOfBoundsException
    321      *             if {@code fromIndex} or {@code toIndex} is negative, or if
    322      *             {@code toIndex} is smaller than {@code fromIndex}.
    323      */
    324     public void set(int fromIndex, int toIndex, boolean state) {
    325         if (state) {
    326             set(fromIndex, toIndex);
    327         } else {
    328             clear(fromIndex, toIndex);
    329         }
    330     }
    331 
    332     /**
    333      * Clears all the bits in this {@code BitSet}. This method does not change the capacity.
    334      * Use {@code clear} if you want to reuse this {@code BitSet} with the same capacity, but
    335      * create a new {@code BitSet} if you're trying to potentially reclaim memory.
    336      */
    337     public void clear() {
    338         Arrays.fill(bits, 0, longCount, 0L);
    339         longCount = 0;
    340     }
    341 
    342     /**
    343      * Sets the range of bits {@code [fromIndex, toIndex)}.
    344      *
    345      * @throws IndexOutOfBoundsException
    346      *             if {@code fromIndex} or {@code toIndex} is negative, or if
    347      *             {@code toIndex} is smaller than {@code fromIndex}.
    348      */
    349     public void set(int fromIndex, int toIndex) {
    350         checkRange(fromIndex, toIndex);
    351         if (fromIndex == toIndex) {
    352             return;
    353         }
    354         int firstArrayIndex = fromIndex / 64;
    355         int lastArrayIndex = (toIndex - 1) / 64;
    356         if (lastArrayIndex >= bits.length) {
    357             ensureCapacity(lastArrayIndex + 1);
    358         }
    359 
    360         long lowMask = ALL_ONES << fromIndex;
    361         long highMask = ALL_ONES >>> -toIndex;
    362         if (firstArrayIndex == lastArrayIndex) {
    363             bits[firstArrayIndex] |= (lowMask & highMask);
    364         } else {
    365             int i = firstArrayIndex;
    366             bits[i++] |= lowMask;
    367             while (i < lastArrayIndex) {
    368                 bits[i++] |= ALL_ONES;
    369             }
    370             bits[i++] |= highMask;
    371         }
    372         longCount = Math.max(longCount, lastArrayIndex + 1);
    373     }
    374 
    375     /**
    376      * Clears the range of bits {@code [fromIndex, toIndex)}.
    377      *
    378      * @throws IndexOutOfBoundsException
    379      *             if {@code fromIndex} or {@code toIndex} is negative, or if
    380      *             {@code toIndex} is smaller than {@code fromIndex}.
    381      */
    382     public void clear(int fromIndex, int toIndex) {
    383         checkRange(fromIndex, toIndex);
    384         if (fromIndex == toIndex || longCount == 0) {
    385             return;
    386         }
    387         int last = 64 * longCount;
    388         if (fromIndex >= last) {
    389             return;
    390         }
    391         if (toIndex > last) {
    392             toIndex = last;
    393         }
    394         int firstArrayIndex = fromIndex / 64;
    395         int lastArrayIndex = (toIndex - 1) / 64;
    396 
    397         long lowMask = ALL_ONES << fromIndex;
    398         long highMask = ALL_ONES >>> -toIndex;
    399         if (firstArrayIndex == lastArrayIndex) {
    400             bits[firstArrayIndex] &= ~(lowMask & highMask);
    401         } else {
    402             int i = firstArrayIndex;
    403             bits[i++] &= ~lowMask;
    404             while (i < lastArrayIndex) {
    405                 bits[i++] = 0L;
    406             }
    407             bits[i++] &= ~highMask;
    408         }
    409         shrinkSize();
    410     }
    411 
    412     /**
    413      * Flips the range of bits {@code [fromIndex, toIndex)}.
    414      *
    415      * @throws IndexOutOfBoundsException
    416      *             if {@code fromIndex} or {@code toIndex} is negative, or if
    417      *             {@code toIndex} is smaller than {@code fromIndex}.
    418      */
    419     public void flip(int fromIndex, int toIndex) {
    420         checkRange(fromIndex, toIndex);
    421         if (fromIndex == toIndex) {
    422             return;
    423         }
    424         int firstArrayIndex = fromIndex / 64;
    425         int lastArrayIndex = (toIndex - 1) / 64;
    426         if (lastArrayIndex >= bits.length) {
    427             ensureCapacity(lastArrayIndex + 1);
    428         }
    429 
    430         long lowMask = ALL_ONES << fromIndex;
    431         long highMask = ALL_ONES >>> -toIndex;
    432         if (firstArrayIndex == lastArrayIndex) {
    433             bits[firstArrayIndex] ^= (lowMask & highMask);
    434         } else {
    435             int i = firstArrayIndex;
    436             bits[i++] ^= lowMask;
    437             while (i < lastArrayIndex) {
    438                 bits[i++] ^= ALL_ONES;
    439             }
    440             bits[i++] ^= highMask;
    441         }
    442         longCount = Math.max(longCount, lastArrayIndex + 1);
    443         shrinkSize();
    444     }
    445 
    446     /**
    447      * Returns true if {@code this.and(bs)} is non-empty, but may be faster than computing that.
    448      */
    449     public boolean intersects(BitSet bs) {
    450         long[] bsBits = bs.bits;
    451         int length = Math.min(this.longCount, bs.longCount);
    452         for (int i = 0; i < length; ++i) {
    453             if ((bits[i] & bsBits[i]) != 0L) {
    454                 return true;
    455             }
    456         }
    457         return false;
    458     }
    459 
    460     /**
    461      * Logically ands the bits of this {@code BitSet} with {@code bs}.
    462      */
    463     public void and(BitSet bs) {
    464         int minSize = Math.min(this.longCount, bs.longCount);
    465         for (int i = 0; i < minSize; ++i) {
    466             bits[i] &= bs.bits[i];
    467         }
    468         Arrays.fill(bits, minSize, longCount, 0L);
    469         shrinkSize();
    470     }
    471 
    472     /**
    473      * Clears all bits in this {@code BitSet} which are also set in {@code bs}.
    474      */
    475     public void andNot(BitSet bs) {
    476         int minSize = Math.min(this.longCount, bs.longCount);
    477         for (int i = 0; i < minSize; ++i) {
    478             bits[i] &= ~bs.bits[i];
    479         }
    480         shrinkSize();
    481     }
    482 
    483     /**
    484      * Logically ors the bits of this {@code BitSet} with {@code bs}.
    485      */
    486     public void or(BitSet bs) {
    487         int minSize = Math.min(this.longCount, bs.longCount);
    488         int maxSize = Math.max(this.longCount, bs.longCount);
    489         ensureCapacity(maxSize);
    490         for (int i = 0; i < minSize; ++i) {
    491             bits[i] |= bs.bits[i];
    492         }
    493         if (bs.longCount > minSize) {
    494             System.arraycopy(bs.bits, minSize, bits, minSize, maxSize - minSize);
    495         }
    496         longCount = maxSize;
    497     }
    498 
    499     /**
    500      * Logically xors the bits of this {@code BitSet} with {@code bs}.
    501      */
    502     public void xor(BitSet bs) {
    503         int minSize = Math.min(this.longCount, bs.longCount);
    504         int maxSize = Math.max(this.longCount, bs.longCount);
    505         ensureCapacity(maxSize);
    506         for (int i = 0; i < minSize; ++i) {
    507             bits[i] ^= bs.bits[i];
    508         }
    509         if (bs.longCount > minSize) {
    510             System.arraycopy(bs.bits, minSize, bits, minSize, maxSize - minSize);
    511         }
    512         longCount = maxSize;
    513         shrinkSize();
    514     }
    515 
    516     /**
    517      * Returns the capacity in bits of the array implementing this {@code BitSet}. This is
    518      * unrelated to the length of the {@code BitSet}, and not generally useful.
    519      * Use {@link #nextSetBit} to iterate, or {@link #length} to find the highest set bit.
    520      */
    521     public int size() {
    522         return bits.length * 64;
    523     }
    524 
    525     /**
    526      * Returns the number of bits up to and including the highest bit set. This is unrelated to
    527      * the {@link #size} of the {@code BitSet}.
    528      */
    529     public int length() {
    530         if (longCount == 0) {
    531             return 0;
    532         }
    533         return 64 * (longCount - 1) + (64 - Long.numberOfLeadingZeros(bits[longCount - 1]));
    534     }
    535 
    536     /**
    537      * Returns a string containing a concise, human-readable description of the
    538      * receiver: a comma-delimited list of the indexes of all set bits.
    539      * For example: {@code "{0,1,8}"}.
    540      */
    541     @Override public String toString() {
    542         //System.err.println("BitSet[longCount=" + longCount + ",bits=" + Arrays.toString(bits) + "]");
    543         StringBuilder sb = new StringBuilder(longCount / 2);
    544         sb.append('{');
    545         boolean comma = false;
    546         for (int i = 0; i < longCount; ++i) {
    547             if (bits[i] != 0) {
    548                 for (int j = 0; j < 64; ++j) {
    549                     if ((bits[i] & 1L << j) != 0) {
    550                         if (comma) {
    551                             sb.append(", ");
    552                         } else {
    553                             comma = true;
    554                         }
    555                         sb.append(64 * i + j);
    556                     }
    557                 }
    558             }
    559         }
    560         sb.append('}');
    561         return sb.toString();
    562     }
    563 
    564     /**
    565      * Returns the index of the first bit that is set on or after {@code index}, or -1
    566      * if no higher bits are set.
    567      * @throws IndexOutOfBoundsException if {@code index < 0}.
    568      */
    569     public int nextSetBit(int index) {
    570         checkIndex(index);
    571         int arrayIndex = index / 64;
    572         if (arrayIndex >= longCount) {
    573             return -1;
    574         }
    575         long mask = ALL_ONES << index;
    576         if ((bits[arrayIndex] & mask) != 0) {
    577             return 64 * arrayIndex + Long.numberOfTrailingZeros(bits[arrayIndex] & mask);
    578         }
    579         while (++arrayIndex < longCount && bits[arrayIndex] == 0) {
    580         }
    581         if (arrayIndex == longCount) {
    582             return -1;
    583         }
    584         return 64 * arrayIndex + Long.numberOfTrailingZeros(bits[arrayIndex]);
    585     }
    586 
    587     /**
    588      * Returns the index of the first bit that is clear on or after {@code index}.
    589      * Since all bits past the end are implicitly clear, this never returns -1.
    590      * @throws IndexOutOfBoundsException if {@code index < 0}.
    591      */
    592     public int nextClearBit(int index) {
    593         checkIndex(index);
    594         int arrayIndex = index / 64;
    595         if (arrayIndex >= longCount) {
    596             return index;
    597         }
    598         long mask = ALL_ONES << index;
    599         if ((~bits[arrayIndex] & mask) != 0) {
    600             return 64 * arrayIndex + Long.numberOfTrailingZeros(~bits[arrayIndex] & mask);
    601         }
    602         while (++arrayIndex < longCount && bits[arrayIndex] == ALL_ONES) {
    603         }
    604         if (arrayIndex == longCount) {
    605             return 64 * longCount;
    606         }
    607         return 64 * arrayIndex + Long.numberOfTrailingZeros(~bits[arrayIndex]);
    608     }
    609 
    610     /**
    611      * Returns the index of the first bit that is set on or before {@code index}, or -1 if
    612      * no lower bits are set or {@code index == -1}.
    613      * @throws IndexOutOfBoundsException if {@code index < -1}.
    614      * @since 1.7
    615      */
    616     public int previousSetBit(int index) {
    617         if (index == -1) {
    618             return -1;
    619         }
    620         checkIndex(index);
    621         // TODO: optimize this.
    622         for (int i = index; i >= 0; --i) {
    623             if (get(i)) {
    624                 return i;
    625             }
    626         }
    627         return -1;
    628     }
    629 
    630     /**
    631      * Returns the index of the first bit that is clear on or before {@code index}, or -1 if
    632      * no lower bits are clear or {@code index == -1}.
    633      * @throws IndexOutOfBoundsException if {@code index < -1}.
    634      * @since 1.7
    635      */
    636     public int previousClearBit(int index) {
    637         if (index == -1) {
    638             return -1;
    639         }
    640         checkIndex(index);
    641         // TODO: optimize this.
    642         for (int i = index; i >= 0; --i) {
    643             if (!get(i)) {
    644                 return i;
    645             }
    646         }
    647         return -1;
    648     }
    649 
    650     /**
    651      * Returns true if all the bits in this {@code BitSet} are set to false, false otherwise.
    652      */
    653     public boolean isEmpty() {
    654         return (longCount == 0);
    655     }
    656 
    657     /**
    658      * Returns the number of bits that are {@code true} in this {@code BitSet}.
    659      */
    660     public int cardinality() {
    661         int result = 0;
    662         for (int i = 0; i < longCount; ++i) {
    663             result += Long.bitCount(bits[i]);
    664         }
    665         return result;
    666     }
    667 
    668     /**
    669      * Equivalent to {@code BitSet.valueOf(LongBuffer.wrap(longs))}, but likely to be faster.
    670      * This is likely to be the fastest way to create a {@code BitSet} because it's closest
    671      * to the internal representation.
    672      * @since 1.7
    673      */
    674     public static BitSet valueOf(long[] longs) {
    675         return new BitSet(longs.clone());
    676     }
    677 
    678     /**
    679      * Returns a {@code BitSet} corresponding to {@code longBuffer}, interpreted as a little-endian
    680      * sequence of bits. This method does not alter the {@code LongBuffer}.
    681      * @since 1.7
    682      */
    683     public static BitSet valueOf(LongBuffer longBuffer) {
    684         // The bulk get would mutate LongBuffer (even if we reset position later), and it's not
    685         // clear that's allowed. My assumption is that it's the long[] variant that's the common
    686         // case anyway, so copy the buffer into a long[].
    687         long[] longs = new long[longBuffer.remaining()];
    688         for (int i = 0; i < longs.length; ++i) {
    689             longs[i] = longBuffer.get(longBuffer.position() + i);
    690         }
    691         return BitSet.valueOf(longs);
    692     }
    693 
    694     /**
    695      * Equivalent to {@code BitSet.valueOf(ByteBuffer.wrap(bytes))}.
    696      * @since 1.7
    697      */
    698     public static BitSet valueOf(byte[] bytes) {
    699         return BitSet.valueOf(ByteBuffer.wrap(bytes));
    700     }
    701 
    702     /**
    703      * Returns a {@code BitSet} corresponding to {@code byteBuffer}, interpreted as a little-endian
    704      * sequence of bits. This method does not alter the {@code ByteBuffer}.
    705      * @since 1.7
    706      */
    707     public static BitSet valueOf(ByteBuffer byteBuffer) {
    708         byteBuffer = byteBuffer.slice().order(ByteOrder.LITTLE_ENDIAN);
    709         long[] longs = arrayForBits(byteBuffer.remaining() * 8);
    710         int i = 0;
    711         while (byteBuffer.remaining() >= SizeOf.LONG) {
    712             longs[i++] = byteBuffer.getLong();
    713         }
    714         for (int j = 0; byteBuffer.hasRemaining(); ++j) {
    715             longs[i] |= ((((long) byteBuffer.get()) & 0xff) << (8*j));
    716         }
    717         return BitSet.valueOf(longs);
    718     }
    719 
    720     /**
    721      * Returns a new {@code long[]} containing a little-endian representation of the bits of
    722      * this {@code BitSet}, suitable for passing to {@code valueOf} to reconstruct
    723      * this {@code BitSet}.
    724      * @since 1.7
    725      */
    726     public long[] toLongArray() {
    727         return Arrays.copyOf(bits, longCount);
    728     }
    729 
    730     /**
    731      * Returns a new {@code byte[]} containing a little-endian representation the bits of
    732      * this {@code BitSet}, suitable for passing to {@code valueOf} to reconstruct
    733      * this {@code BitSet}.
    734      * @since 1.7
    735      */
    736     public byte[] toByteArray() {
    737         int bitCount = length();
    738         byte[] result = new byte[(bitCount + 7)/ 8];
    739         for (int i = 0; i < result.length; ++i) {
    740             int lowBit = 8 * i;
    741             int arrayIndex = lowBit / 64;
    742             result[i] = (byte) (bits[arrayIndex] >>> lowBit);
    743         }
    744         return result;
    745     }
    746 
    747     private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException {
    748         ois.defaultReadObject();
    749         // The serialized form doesn't include a 'longCount' field, so we'll have to scan the array.
    750         this.longCount = this.bits.length;
    751         shrinkSize();
    752     }
    753 }
    754