• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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      */
shrinkSize()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      */
BitSet()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      */
BitSet(int bitCount)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 
BitSet(long[] bits)94     private BitSet(long[] bits) {
95         this.bits = bits;
96         this.longCount = bits.length;
97         shrinkSize();
98     }
99 
arrayForBits(int bitCount)100     private static long[] arrayForBits(int bitCount) {
101         return new long[(bitCount + 63)/ 64];
102     }
103 
clone()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 
equals(Object o)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      */
ensureCapacity(int desiredLongCount)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 
hashCode()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      */
get(int index)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      */
set(int index)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      */
clear(int index)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      */
flip(int index)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 
checkIndex(int index)226     private void checkIndex(int index) {
227         if (index < 0) {
228             throw new IndexOutOfBoundsException("index < 0: " + index);
229         }
230     }
231 
checkRange(int fromIndex, int toIndex)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      */
get(int fromIndex, int toIndex)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      */
set(int index, boolean state)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      */
set(int fromIndex, int toIndex, boolean state)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      */
clear()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      */
set(int fromIndex, int toIndex)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      */
clear(int fromIndex, int toIndex)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      */
flip(int fromIndex, int toIndex)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      */
intersects(BitSet bs)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      */
and(BitSet bs)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      */
andNot(BitSet bs)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      */
or(BitSet bs)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      */
xor(BitSet bs)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      */
size()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      */
length()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      */
toString()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      */
nextSetBit(int index)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      */
nextClearBit(int index)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      */
previousSetBit(int index)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      */
previousClearBit(int index)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      */
isEmpty()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      */
cardinality()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      */
valueOf(long[] longs)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      */
valueOf(LongBuffer longBuffer)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      */
valueOf(byte[] bytes)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      */
valueOf(ByteBuffer byteBuffer)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      */
toLongArray()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      */
toByteArray()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 
readObject(ObjectInputStream ois)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