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