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
18package java.util;
19
20import java.io.IOException;
21import java.io.ObjectInputStream;
22import java.io.Serializable;
23import java.nio.ByteBuffer;
24import java.nio.ByteOrder;
25import java.nio.LongBuffer;
26import 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 */
34public 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