001/* 002 * Copyright (c) 1995, 2014, Oracle and/or its affiliates. All rights reserved. 003 * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. 004 * 005 * 006 * 007 * 008 * 009 * 010 * 011 * 012 * 013 * 014 * 015 * 016 * 017 * 018 * 019 * 020 * 021 * 022 * 023 * 024 */ 025 026package conexp.fx.core.collections; 027 028/*- 029 * #%L 030 * Concept Explorer FX 031 * %% 032 * Copyright (C) 2010 - 2023 Francesco Kriegel 033 * %% 034 * This program is free software: you can redistribute it and/or modify 035 * it under the terms of the GNU General Public License as 036 * published by the Free Software Foundation, either version 3 of the 037 * License, or (at your option) any later version. 038 * 039 * This program is distributed in the hope that it will be useful, 040 * but WITHOUT ANY WARRANTY; without even the implied warranty of 041 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 042 * GNU General Public License for more details. 043 * 044 * You should have received a copy of the GNU General Public 045 * License along with this program. If not, see 046 * <http://www.gnu.org/licenses/gpl-3.0.html>. 047 * #L% 048 */ 049 050import java.io.IOException; 051import java.io.ObjectInputStream; 052import java.io.ObjectOutputStream; 053import java.io.ObjectStreamField; 054import java.nio.ByteBuffer; 055import java.nio.ByteOrder; 056import java.nio.LongBuffer; 057import java.util.AbstractSet; 058import java.util.Arrays; 059import java.util.Collection; 060import java.util.Comparator; 061import java.util.Iterator; 062import java.util.NoSuchElementException; 063import java.util.PrimitiveIterator; 064import java.util.SortedSet; 065import java.util.Spliterator; 066import java.util.Spliterators; 067import java.util.stream.Stream; 068import java.util.stream.StreamSupport; 069 070/** 071 * This class implements a vector of bits that grows as needed. Each component of the bit set has a {@code boolean} 072 * value. The bits of a {@code BitSet} are indexed by nonnegative integers. Individual indexed bits can be examined, 073 * set, or cleared. One {@code BitSet} may be used to modify the contents of another {@code BitSet} through logical AND, 074 * logical inclusive OR, and logical exclusive OR operations. 075 * 076 * <p> 077 * By default, all bits in the set initially have the value {@code false}. 078 * 079 * <p> 080 * Every bit set has a current size, which is the number of bits of space currently in use by the bit set. Note that the 081 * size is related to the implementation of a bit set, so it may change with implementation. The length of a bit set 082 * relates to logical length of a bit set and is defined independently of implementation. 083 * 084 * <p> 085 * Unless otherwise noted, passing a null parameter to any of the methods in a {@code BitSet} will result in a 086 * {@code NullPointerException}. 087 * 088 * <p> 089 * A {@code BitSet} is not safe for multithreaded use without external synchronization. 090 * 091 * @author Arthur van Hoff 092 * @author Michael McCloskey 093 * @author Martin Buchholz 094 * @since JDK1.0 095 */ 096public class BitSetFX extends AbstractSet<Integer> implements SortedSet<Integer>, Cloneable, java.io.Serializable { 097 098 /* 099 * BitSets are packed into arrays of "words." Currently a word is a long, which consists of 64 bits, requiring 6 100 * address bits. The choice of word size is determined purely by performance concerns. 101 */ 102 private final static int ADDRESS_BITS_PER_WORD = 6; 103 private final static int BITS_PER_WORD = 1 << ADDRESS_BITS_PER_WORD; 104 private final static int BIT_INDEX_MASK = BITS_PER_WORD - 1; 105 106 /* Used to shift left or right for a partial word mask */ 107 private static final long WORD_MASK = 0xffffffffffffffffL; 108 109 /** 110 * @serialField bits 111 * long[] 112 * 113 * The bits in this BitSet. The ith bit is stored in bits[i/64] at bit position i % 64 (where bit 114 * position 0 refers to the least significant bit and 63 refers to the most significant bit). 115 */ 116 private static final ObjectStreamField[] serialPersistentFields = { 117 new ObjectStreamField("bits", long[].class), 118 }; 119 120 /** 121 * The internal field corresponding to the serialField "bits". 122 */ 123 private long[] words; 124 125 /** 126 * The number of words in the logical size of this BitSet. 127 */ 128 private transient int wordsInUse = 0; 129 130 /** 131 * Whether the size of "words" is user-specified. If so, we assume the user knows what he's doing and try harder to 132 * preserve it. 133 */ 134 private transient boolean sizeIsSticky = false; 135 136 /* use serialVersionUID from JDK 1.0.2 for interoperability */ 137 private static final long serialVersionUID = 7997698588986878753L; 138 139 /** 140 * Given a bit index, return word index containing it. 141 */ 142 private static int wordIndex(int bitIndex) { 143 return bitIndex >> ADDRESS_BITS_PER_WORD; 144 } 145 146 /** 147 * Every public method must preserve these invariants. 148 */ 149 private void checkInvariants() { 150 assert (wordsInUse == 0 || words[wordsInUse - 1] != 0); 151 assert (wordsInUse >= 0 && wordsInUse <= words.length); 152 assert (wordsInUse == words.length || words[wordsInUse] == 0); 153 } 154 155 /** 156 * Sets the field wordsInUse to the logical size in words of the bit set. WARNING:This method assumes that the number 157 * of words actually in use is less than or equal to the current value of wordsInUse! 158 */ 159 private void recalculateWordsInUse() { 160 // Traverse the bitset until a used word is found 161 int i; 162 for (i = wordsInUse - 1; i >= 0; i--) 163 if (words[i] != 0) 164 break; 165 166 wordsInUse = i + 1; // The new logical size 167 } 168 169 /** 170 * Creates a new bit set. All bits are initially {@code false}. 171 */ 172 public BitSetFX() { 173 initWords(BITS_PER_WORD); 174 sizeIsSticky = false; 175 } 176 177 /** 178 * Creates a bit set whose initial size is large enough to explicitly represent bits with indices in the range 179 * {@code 0} through {@code nbits-1}. All bits are initially {@code false}. 180 * 181 * @param nbits 182 * the initial size of the bit set 183 * @throws NegativeArraySizeException 184 * if the specified initial size is negative 185 */ 186 public BitSetFX(int nbits) { 187 // nbits can't be negative; size 0 is OK 188 if (nbits < 0) 189 throw new NegativeArraySizeException("nbits < 0: " + nbits); 190 191 initWords(nbits); 192 sizeIsSticky = true; 193 } 194 195 private void initWords(int nbits) { 196 words = new long[wordIndex(nbits - 1) + 1]; 197 } 198 199 /** 200 * Creates a bit set using words as the internal representation. The last word (if there is one) must be non-zero. 201 */ 202 private BitSetFX(long[] words) { 203 this.words = words; 204 this.wordsInUse = words.length; 205 checkInvariants(); 206 } 207 208 /** 209 * Returns a new bit set containing all the bits in the given long array. 210 * 211 * <p> 212 * More precisely, <br> 213 * {@code BitSet.valueOf(longs).get(n) == ((longs[n/64] & (1L<<(n%64))) != 0)} <br> 214 * for all {@code n < 64 * longs.length}. 215 * 216 * <p> 217 * This method is equivalent to {@code BitSet.valueOf(LongBuffer.wrap(longs))}. 218 * 219 * @param longs 220 * a long array containing a little-endian representation of a sequence of bits to be used as the initial 221 * bits of the new bit set 222 * @return a {@code BitSet} containing all the bits in the long array 223 * @since 1.7 224 */ 225 public static BitSetFX valueOf(long[] longs) { 226 int n; 227 for (n = longs.length; n > 0 && longs[n - 1] == 0; n--); 228 return new BitSetFX(Arrays.copyOf(longs, n)); 229 } 230 231 /** 232 * Returns a new bit set containing all the bits in the given long buffer between its position and limit. 233 * 234 * <p> 235 * More precisely, <br> 236 * {@code BitSet.valueOf(lb).get(n) == ((lb.get(lb.position()+n/64) & (1L<<(n%64))) != 0)} <br> 237 * for all {@code n < 64 * lb.remaining()}. 238 * 239 * <p> 240 * The long buffer is not modified by this method, and no reference to the buffer is retained by the bit set. 241 * 242 * @param lb 243 * a long buffer containing a little-endian representation of a sequence of bits between its position and 244 * limit, to be used as the initial bits of the new bit set 245 * @return a {@code BitSet} containing all the bits in the buffer in the specified range 246 * @since 1.7 247 */ 248 public static BitSetFX valueOf(LongBuffer lb) { 249 lb = lb.slice(); 250 int n; 251 for (n = lb.remaining(); n > 0 && lb.get(n - 1) == 0; n--); 252 long[] words = new long[n]; 253 lb.get(words); 254 return new BitSetFX(words); 255 } 256 257 /** 258 * Returns a new bit set containing all the bits in the given byte array. 259 * 260 * <p> 261 * More precisely, <br> 262 * {@code BitSet.valueOf(bytes).get(n) == ((bytes[n/8] & (1<<(n%8))) != 0)} <br> 263 * for all {@code n < 8 * bytes.length}. 264 * 265 * <p> 266 * This method is equivalent to {@code BitSet.valueOf(ByteBuffer.wrap(bytes))}. 267 * 268 * @param bytes 269 * a byte array containing a little-endian representation of a sequence of bits to be used as the initial 270 * bits of the new bit set 271 * @return a {@code BitSet} containing all the bits in the byte array 272 * @since 1.7 273 */ 274 public static BitSetFX valueOf(byte[] bytes) { 275 return BitSetFX.valueOf(ByteBuffer.wrap(bytes)); 276 } 277 278 /** 279 * Returns a new bit set containing all the bits in the given byte buffer between its position and limit. 280 * 281 * <p> 282 * More precisely, <br> 283 * {@code BitSet.valueOf(bb).get(n) == ((bb.get(bb.position()+n/8) & (1<<(n%8))) != 0)} <br> 284 * for all {@code n < 8 * bb.remaining()}. 285 * 286 * <p> 287 * The byte buffer is not modified by this method, and no reference to the buffer is retained by the bit set. 288 * 289 * @param bb 290 * a byte buffer containing a little-endian representation of a sequence of bits between its position and 291 * limit, to be used as the initial bits of the new bit set 292 * @return a {@code BitSet} containing all the bits in the buffer in the specified range 293 * @since 1.7 294 */ 295 public static BitSetFX valueOf(ByteBuffer bb) { 296 bb = bb.slice().order(ByteOrder.LITTLE_ENDIAN); 297 int n; 298 for (n = bb.remaining(); n > 0 && bb.get(n - 1) == 0; n--); 299 long[] words = new long[(n + 7) / 8]; 300 bb.limit(n); 301 int i = 0; 302 while (bb.remaining() >= 8) 303 words[i++] = bb.getLong(); 304 for (int remaining = bb.remaining(), j = 0; j < remaining; j++) 305 words[i] |= (bb.get() & 0xffL) << (8 * j); 306 return new BitSetFX(words); 307 } 308 309 /** 310 * Returns a new byte array containing all the bits in this bit set. 311 * 312 * <p> 313 * More precisely, if <br> 314 * {@code byte[] bytes = s.toByteArray();} <br> 315 * then {@code bytes.length == (s.length()+7)/8} and <br> 316 * {@code s.get(n) == ((bytes[n/8] & (1<<(n%8))) != 0)} <br> 317 * for all {@code n < 8 * bytes.length}. 318 * 319 * @return a byte array containing a little-endian representation of all the bits in this bit set 320 * @since 1.7 321 */ 322 public byte[] toByteArray() { 323 int n = wordsInUse; 324 if (n == 0) 325 return new byte[0]; 326 int len = 8 * (n - 1); 327 for (long x = words[n - 1]; x != 0; x >>>= 8) 328 len++; 329 byte[] bytes = new byte[len]; 330 ByteBuffer bb = ByteBuffer.wrap(bytes).order(ByteOrder.LITTLE_ENDIAN); 331 for (int i = 0; i < n - 1; i++) 332 bb.putLong(words[i]); 333 for (long x = words[n - 1]; x != 0; x >>>= 8) 334 bb.put((byte) (x & 0xff)); 335 return bytes; 336 } 337 338 /** 339 * Returns a new long array containing all the bits in this bit set. 340 * 341 * <p> 342 * More precisely, if <br> 343 * {@code long[] longs = s.toLongArray();} <br> 344 * then {@code longs.length == (s.length()+63)/64} and <br> 345 * {@code s.get(n) == ((longs[n/64] & (1L<<(n%64))) != 0)} <br> 346 * for all {@code n < 64 * longs.length}. 347 * 348 * @return a long array containing a little-endian representation of all the bits in this bit set 349 * @since 1.7 350 */ 351 public long[] toLongArray() { 352 return Arrays.copyOf(words, wordsInUse); 353 } 354 355 /** 356 * Ensures that the BitSet can hold enough words. 357 * 358 * @param wordsRequired 359 * the minimum acceptable number of words. 360 */ 361 private void ensureCapacity(int wordsRequired) { 362 if (words.length < wordsRequired) { 363 // Allocate larger of doubled size or required size 364 int request = Math.max(2 * words.length, wordsRequired); 365 words = Arrays.copyOf(words, request); 366 sizeIsSticky = false; 367 } 368 } 369 370 /** 371 * Ensures that the BitSet can accommodate a given wordIndex, temporarily violating the invariants. The caller must 372 * restore the invariants before returning to the user, possibly using recalculateWordsInUse(). 373 * 374 * @param wordIndex 375 * the index to be accommodated. 376 */ 377 private void expandTo(int wordIndex) { 378 int wordsRequired = wordIndex + 1; 379 if (wordsInUse < wordsRequired) { 380 ensureCapacity(wordsRequired); 381 wordsInUse = wordsRequired; 382 } 383 } 384 385 /** 386 * Checks that fromIndex ... toIndex is a valid range of bit indices. 387 */ 388 private static void checkRange(int fromIndex, int toIndex) { 389 if (fromIndex < 0) 390 throw new IndexOutOfBoundsException("fromIndex < 0: " + fromIndex); 391 if (toIndex < 0) 392 throw new IndexOutOfBoundsException("toIndex < 0: " + toIndex); 393 if (fromIndex > toIndex) 394 throw new IndexOutOfBoundsException("fromIndex: " + fromIndex + " > toIndex: " + toIndex); 395 } 396 397 /** 398 * Sets the bit at the specified index to the complement of its current value. 399 * 400 * @param bitIndex 401 * the index of the bit to flip 402 * @throws IndexOutOfBoundsException 403 * if the specified index is negative 404 * @since 1.4 405 */ 406 public void flip(int bitIndex) { 407 if (bitIndex < 0) 408 throw new IndexOutOfBoundsException("bitIndex < 0: " + bitIndex); 409 410 int wordIndex = wordIndex(bitIndex); 411 expandTo(wordIndex); 412 413 words[wordIndex] ^= (1L << bitIndex); 414 415 recalculateWordsInUse(); 416 checkInvariants(); 417 } 418 419 /** 420 * Sets each bit from the specified {@code fromIndex} (inclusive) to the specified {@code toIndex} (exclusive) to the 421 * complement of its current value. 422 * 423 * @param fromIndex 424 * index of the first bit to flip 425 * @param toIndex 426 * index after the last bit to flip 427 * @throws IndexOutOfBoundsException 428 * if {@code fromIndex} is negative, or {@code toIndex} is negative, or {@code fromIndex} is larger than 429 * {@code toIndex} 430 * @since 1.4 431 */ 432 public void flip(int fromIndex, int toIndex) { 433 checkRange(fromIndex, toIndex); 434 435 if (fromIndex == toIndex) 436 return; 437 438 int startWordIndex = wordIndex(fromIndex); 439 int endWordIndex = wordIndex(toIndex - 1); 440 expandTo(endWordIndex); 441 442 long firstWordMask = WORD_MASK << fromIndex; 443 long lastWordMask = WORD_MASK >>> -toIndex; 444 if (startWordIndex == endWordIndex) { 445 // Case 1: One word 446 words[startWordIndex] ^= (firstWordMask & lastWordMask); 447 } else { 448 // Case 2: Multiple words 449 // Handle first word 450 words[startWordIndex] ^= firstWordMask; 451 452 // Handle intermediate words, if any 453 for (int i = startWordIndex + 1; i < endWordIndex; i++) 454 words[i] ^= WORD_MASK; 455 456 // Handle last word 457 words[endWordIndex] ^= lastWordMask; 458 } 459 460 recalculateWordsInUse(); 461 checkInvariants(); 462 } 463 464 /** 465 * Sets the bit at the specified index to {@code true}. 466 * 467 * @param bitIndex 468 * a bit index 469 * @throws IndexOutOfBoundsException 470 * if the specified index is negative 471 * @since JDK1.0 472 */ 473 public void set(int bitIndex) { 474 if (bitIndex < 0) 475 throw new IndexOutOfBoundsException("bitIndex < 0: " + bitIndex); 476 477 int wordIndex = wordIndex(bitIndex); 478 expandTo(wordIndex); 479 480 words[wordIndex] |= (1L << bitIndex); // Restores invariants 481 482 checkInvariants(); 483 } 484 485 /** 486 * Sets the bit at the specified index to the specified value. 487 * 488 * @param bitIndex 489 * a bit index 490 * @param value 491 * a boolean value to set 492 * @throws IndexOutOfBoundsException 493 * if the specified index is negative 494 * @since 1.4 495 */ 496 public void set(int bitIndex, boolean value) { 497 if (value) 498 set(bitIndex); 499 else 500 clear(bitIndex); 501 } 502 503 /** 504 * Sets the bits from the specified {@code fromIndex} (inclusive) to the specified {@code toIndex} (exclusive) to 505 * {@code true}. 506 * 507 * @param fromIndex 508 * index of the first bit to be set 509 * @param toIndex 510 * index after the last bit to be set 511 * @throws IndexOutOfBoundsException 512 * if {@code fromIndex} is negative, or {@code toIndex} is negative, or {@code fromIndex} is larger than 513 * {@code toIndex} 514 * @since 1.4 515 */ 516 public void set(int fromIndex, int toIndex) { 517 checkRange(fromIndex, toIndex); 518 519 if (fromIndex == toIndex) 520 return; 521 522 // Increase capacity if necessary 523 int startWordIndex = wordIndex(fromIndex); 524 int endWordIndex = wordIndex(toIndex - 1); 525 expandTo(endWordIndex); 526 527 long firstWordMask = WORD_MASK << fromIndex; 528 long lastWordMask = WORD_MASK >>> -toIndex; 529 if (startWordIndex == endWordIndex) { 530 // Case 1: One word 531 words[startWordIndex] |= (firstWordMask & lastWordMask); 532 } else { 533 // Case 2: Multiple words 534 // Handle first word 535 words[startWordIndex] |= firstWordMask; 536 537 // Handle intermediate words, if any 538 for (int i = startWordIndex + 1; i < endWordIndex; i++) 539 words[i] = WORD_MASK; 540 541 // Handle last word (restores invariants) 542 words[endWordIndex] |= lastWordMask; 543 } 544 545 checkInvariants(); 546 } 547 548 /** 549 * Sets the bits from the specified {@code fromIndex} (inclusive) to the specified {@code toIndex} (exclusive) to the 550 * specified value. 551 * 552 * @param fromIndex 553 * index of the first bit to be set 554 * @param toIndex 555 * index after the last bit to be set 556 * @param value 557 * value to set the selected bits to 558 * @throws IndexOutOfBoundsException 559 * if {@code fromIndex} is negative, or {@code toIndex} is negative, or {@code fromIndex} is larger than 560 * {@code toIndex} 561 * @since 1.4 562 */ 563 public void set(int fromIndex, int toIndex, boolean value) { 564 if (value) 565 set(fromIndex, toIndex); 566 else 567 clear(fromIndex, toIndex); 568 } 569 570 /** 571 * Sets the bit specified by the index to {@code false}. 572 * 573 * @param bitIndex 574 * the index of the bit to be cleared 575 * @throws IndexOutOfBoundsException 576 * if the specified index is negative 577 * @since JDK1.0 578 */ 579 public void clear(int bitIndex) { 580 if (bitIndex < 0) 581 throw new IndexOutOfBoundsException("bitIndex < 0: " + bitIndex); 582 583 int wordIndex = wordIndex(bitIndex); 584 if (wordIndex >= wordsInUse) 585 return; 586 587 words[wordIndex] &= ~(1L << bitIndex); 588 589 recalculateWordsInUse(); 590 checkInvariants(); 591 } 592 593 /** 594 * Sets the bits from the specified {@code fromIndex} (inclusive) to the specified {@code toIndex} (exclusive) to 595 * {@code false}. 596 * 597 * @param fromIndex 598 * index of the first bit to be cleared 599 * @param toIndex 600 * index after the last bit to be cleared 601 * @throws IndexOutOfBoundsException 602 * if {@code fromIndex} is negative, or {@code toIndex} is negative, or {@code fromIndex} is larger than 603 * {@code toIndex} 604 * @since 1.4 605 */ 606 public void clear(int fromIndex, int toIndex) { 607 checkRange(fromIndex, toIndex); 608 609 if (fromIndex == toIndex) 610 return; 611 612 int startWordIndex = wordIndex(fromIndex); 613 if (startWordIndex >= wordsInUse) 614 return; 615 616 int endWordIndex = wordIndex(toIndex - 1); 617 if (endWordIndex >= wordsInUse) { 618 toIndex = length(); 619 endWordIndex = wordsInUse - 1; 620 } 621 622 long firstWordMask = WORD_MASK << fromIndex; 623 long lastWordMask = WORD_MASK >>> -toIndex; 624 if (startWordIndex == endWordIndex) { 625 // Case 1: One word 626 words[startWordIndex] &= ~(firstWordMask & lastWordMask); 627 } else { 628 // Case 2: Multiple words 629 // Handle first word 630 words[startWordIndex] &= ~firstWordMask; 631 632 // Handle intermediate words, if any 633 for (int i = startWordIndex + 1; i < endWordIndex; i++) 634 words[i] = 0; 635 636 // Handle last word 637 words[endWordIndex] &= ~lastWordMask; 638 } 639 640 recalculateWordsInUse(); 641 checkInvariants(); 642 } 643 644 /** 645 * Sets all of the bits in this BitSet to {@code false}. 646 * 647 * @since 1.4 648 */ 649 public void clear() { 650 while (wordsInUse > 0) 651 words[--wordsInUse] = 0; 652 } 653 654 /** 655 * Returns the value of the bit with the specified index. The value is {@code true} if the bit with the index 656 * {@code bitIndex} is currently set in this {@code BitSet}; otherwise, the result is {@code false}. 657 * 658 * @param bitIndex 659 * the bit index 660 * @return the value of the bit with the specified index 661 * @throws IndexOutOfBoundsException 662 * if the specified index is negative 663 */ 664 public boolean get(int bitIndex) { 665 if (bitIndex < 0) 666 throw new IndexOutOfBoundsException("bitIndex < 0: " + bitIndex); 667 668 checkInvariants(); 669 670 int wordIndex = wordIndex(bitIndex); 671 return (wordIndex < wordsInUse) && ((words[wordIndex] & (1L << bitIndex)) != 0); 672 } 673 674 /** 675 * Returns a new {@code BitSet} composed of bits from this {@code BitSet} from {@code fromIndex} (inclusive) to 676 * {@code toIndex} (exclusive). 677 * 678 * @param fromIndex 679 * index of the first bit to include 680 * @param toIndex 681 * index after the last bit to include 682 * @return a new {@code BitSet} from a range of this {@code BitSet} 683 * @throws IndexOutOfBoundsException 684 * if {@code fromIndex} is negative, or {@code toIndex} is negative, or {@code fromIndex} is larger than 685 * {@code toIndex} 686 * @since 1.4 687 */ 688 public BitSetFX get(int fromIndex, int toIndex) { 689 checkRange(fromIndex, toIndex); 690 691 checkInvariants(); 692 693 int len = length(); 694 695 // If no set bits in range return empty bitset 696 if (len <= fromIndex || fromIndex == toIndex) 697 return new BitSetFX(0); 698 699 // An optimization 700 if (toIndex > len) 701 toIndex = len; 702 703 BitSetFX result = new BitSetFX(toIndex - fromIndex); 704 int targetWords = wordIndex(toIndex - fromIndex - 1) + 1; 705 int sourceIndex = wordIndex(fromIndex); 706 boolean wordAligned = ((fromIndex & BIT_INDEX_MASK) == 0); 707 708 // Process all words but the last word 709 for (int i = 0; i < targetWords - 1; i++, sourceIndex++) 710 result.words[i] = wordAligned ? words[sourceIndex] 711 : (words[sourceIndex] >>> fromIndex) | (words[sourceIndex + 1] << -fromIndex); 712 713 // Process the last word 714 long lastWordMask = WORD_MASK >>> -toIndex; 715 result.words[targetWords - 1] = 716 ((toIndex - 1) & BIT_INDEX_MASK) < (fromIndex & BIT_INDEX_MASK) ? /* straddles source words */ 717 ((words[sourceIndex] >>> fromIndex) | (words[sourceIndex + 1] & lastWordMask) << -fromIndex) 718 : ((words[sourceIndex] & lastWordMask) >>> fromIndex); 719 720 // Set wordsInUse correctly 721 result.wordsInUse = targetWords; 722 result.recalculateWordsInUse(); 723 result.checkInvariants(); 724 725 return result; 726 } 727 728 /** 729 * Returns the index of the first bit that is set to {@code true} that occurs on or after the specified starting 730 * index. If no such bit exists then {@code -1} is returned. 731 * 732 * <p> 733 * To iterate over the {@code true} bits in a {@code BitSet}, use the following loop: 734 * 735 * <pre> 736 * {@code 737 * for (int i = bs.nextSetBit(0); i >= 0; i = bs.nextSetBit(i+1)) { 738 * // operate on index i here 739 * if (i == Integer.MAX_VALUE) { 740 * break; // or (i+1) would overflow 741 * } 742 * }} 743 * </pre> 744 * 745 * @param fromIndex 746 * the index to start checking from (inclusive) 747 * @return the index of the next set bit, or {@code -1} if there is no such bit 748 * @throws IndexOutOfBoundsException 749 * if the specified index is negative 750 * @since 1.4 751 */ 752 public int nextSetBit(int fromIndex) { 753 if (fromIndex < 0) 754 throw new IndexOutOfBoundsException("fromIndex < 0: " + fromIndex); 755 756 checkInvariants(); 757 758 int u = wordIndex(fromIndex); 759 if (u >= wordsInUse) 760 return -1; 761 762 long word = words[u] & (WORD_MASK << fromIndex); 763 764 while (true) { 765 if (word != 0) 766 return (u * BITS_PER_WORD) + Long.numberOfTrailingZeros(word); 767 if (++u == wordsInUse) 768 return -1; 769 word = words[u]; 770 } 771 } 772 773 /** 774 * Returns the index of the first bit that is set to {@code false} that occurs on or after the specified starting 775 * index. 776 * 777 * @param fromIndex 778 * the index to start checking from (inclusive) 779 * @return the index of the next clear bit 780 * @throws IndexOutOfBoundsException 781 * if the specified index is negative 782 * @since 1.4 783 */ 784 public int nextClearBit(int fromIndex) { 785 // Neither spec nor implementation handle bitsets of maximal length. 786 // See 4816253. 787 if (fromIndex < 0) 788 throw new IndexOutOfBoundsException("fromIndex < 0: " + fromIndex); 789 790 checkInvariants(); 791 792 int u = wordIndex(fromIndex); 793 if (u >= wordsInUse) 794 return fromIndex; 795 796 long word = ~words[u] & (WORD_MASK << fromIndex); 797 798 while (true) { 799 if (word != 0) 800 return (u * BITS_PER_WORD) + Long.numberOfTrailingZeros(word); 801 if (++u == wordsInUse) 802 return wordsInUse * BITS_PER_WORD; 803 word = ~words[u]; 804 } 805 } 806 807 /** 808 * Returns the index of the nearest bit that is set to {@code true} that occurs on or before the specified starting 809 * index. If no such bit exists, or if {@code -1} is given as the starting index, then {@code -1} is returned. 810 * 811 * <p> 812 * To iterate over the {@code true} bits in a {@code BitSet}, use the following loop: 813 * 814 * <pre> 815 * {@code 816 * for (int i = bs.length(); (i = bs.previousSetBit(i-1)) >= 0; ) { 817 * // operate on index i here 818 * }} 819 * </pre> 820 * 821 * @param fromIndex 822 * the index to start checking from (inclusive) 823 * @return the index of the previous set bit, or {@code -1} if there is no such bit 824 * @throws IndexOutOfBoundsException 825 * if the specified index is less than {@code -1} 826 * @since 1.7 827 */ 828 public int previousSetBit(int fromIndex) { 829 if (fromIndex < 0) { 830 if (fromIndex == -1) 831 return -1; 832 throw new IndexOutOfBoundsException("fromIndex < -1: " + fromIndex); 833 } 834 835 checkInvariants(); 836 837 int u = wordIndex(fromIndex); 838 if (u >= wordsInUse) 839 return length() - 1; 840 841 long word = words[u] & (WORD_MASK >>> -(fromIndex + 1)); 842 843 while (true) { 844 if (word != 0) 845 return (u + 1) * BITS_PER_WORD - 1 - Long.numberOfLeadingZeros(word); 846 if (u-- == 0) 847 return -1; 848 word = words[u]; 849 } 850 } 851 852 /** 853 * Returns the index of the nearest bit that is set to {@code false} that occurs on or before the specified starting 854 * index. If no such bit exists, or if {@code -1} is given as the starting index, then {@code -1} is returned. 855 * 856 * @param fromIndex 857 * the index to start checking from (inclusive) 858 * @return the index of the previous clear bit, or {@code -1} if there is no such bit 859 * @throws IndexOutOfBoundsException 860 * if the specified index is less than {@code -1} 861 * @since 1.7 862 */ 863 public int previousClearBit(int fromIndex) { 864 if (fromIndex < 0) { 865 if (fromIndex == -1) 866 return -1; 867 throw new IndexOutOfBoundsException("fromIndex < -1: " + fromIndex); 868 } 869 870 checkInvariants(); 871 872 int u = wordIndex(fromIndex); 873 if (u >= wordsInUse) 874 return fromIndex; 875 876 long word = ~words[u] & (WORD_MASK >>> -(fromIndex + 1)); 877 878 while (true) { 879 if (word != 0) 880 return (u + 1) * BITS_PER_WORD - 1 - Long.numberOfLeadingZeros(word); 881 if (u-- == 0) 882 return -1; 883 word = ~words[u]; 884 } 885 } 886 887 /** 888 * Returns the "logical size" of this {@code BitSet}: the index of the highest set bit in the {@code BitSet} plus one. 889 * Returns zero if the {@code BitSet} contains no set bits. 890 * 891 * @return the logical size of this {@code BitSet} 892 * @since 1.2 893 */ 894 public int length() { 895 if (wordsInUse == 0) 896 return 0; 897 898 return BITS_PER_WORD * (wordsInUse - 1) + (BITS_PER_WORD - Long.numberOfLeadingZeros(words[wordsInUse - 1])); 899 } 900 901 /** 902 * Returns true if this {@code BitSet} contains no bits that are set to {@code true}. 903 * 904 * @return boolean indicating whether this {@code BitSet} is empty 905 * @since 1.4 906 */ 907 public boolean isEmpty() { 908 return wordsInUse == 0; 909 } 910 911 /** 912 * Returns true if the specified {@code BitSet} has any bits set to {@code true} that are also set to {@code true} in 913 * this {@code BitSet}. 914 * 915 * @param set 916 * {@code BitSet} to intersect with 917 * @return boolean indicating whether this {@code BitSet} intersects the specified {@code BitSet} 918 * @since 1.4 919 */ 920 public boolean intersects(BitSetFX set) { 921 for (int i = Math.min(wordsInUse, set.wordsInUse) - 1; i >= 0; i--) 922 if ((words[i] & set.words[i]) != 0) 923 return true; 924 return false; 925 } 926 927 /** 928 * Returns the number of bits set to {@code true} in this {@code BitSet}. 929 * 930 * @return the number of bits set to {@code true} in this {@code BitSet} 931 * @since 1.4 932 */ 933 public int cardinality() { 934 int sum = 0; 935 for (int i = 0; i < wordsInUse; i++) 936 sum += Long.bitCount(words[i]); 937 return sum; 938 } 939 940 /** 941 * Performs a logical <b>AND</b> of this target bit set with the argument bit set. This bit set is modified so that 942 * each bit in it has the value {@code true} if and only if it both initially had the value {@code true} and the 943 * corresponding bit in the bit set argument also had the value {@code true}. 944 * 945 * @param set 946 * a bit set 947 */ 948 public void and(BitSetFX set) { 949 if (this == set) 950 return; 951 952 while (wordsInUse > set.wordsInUse) 953 words[--wordsInUse] = 0; 954 955 // Perform logical AND on words in common 956 for (int i = 0; i < wordsInUse; i++) 957 words[i] &= set.words[i]; 958 959 recalculateWordsInUse(); 960 checkInvariants(); 961 } 962 963 /** 964 * Performs a logical <b>OR</b> of this bit set with the bit set argument. This bit set is modified so that a bit in 965 * it has the value {@code true} if and only if it either already had the value {@code true} or the corresponding bit 966 * in the bit set argument has the value {@code true}. 967 * 968 * @param set 969 * a bit set 970 */ 971 public void or(BitSetFX set) { 972 if (this == set) 973 return; 974 975 int wordsInCommon = Math.min(wordsInUse, set.wordsInUse); 976 977 if (wordsInUse < set.wordsInUse) { 978 ensureCapacity(set.wordsInUse); 979 wordsInUse = set.wordsInUse; 980 } 981 982 // Perform logical OR on words in common 983 for (int i = 0; i < wordsInCommon; i++) 984 words[i] |= set.words[i]; 985 986 // Copy any remaining words 987 if (wordsInCommon < set.wordsInUse) 988 System.arraycopy(set.words, wordsInCommon, words, wordsInCommon, wordsInUse - wordsInCommon); 989 990 // recalculateWordsInUse() is unnecessary 991 checkInvariants(); 992 } 993 994 /** 995 * Performs a logical <b>XOR</b> of this bit set with the bit set argument. This bit set is modified so that a bit in 996 * it has the value {@code true} if and only if one of the following statements holds: 997 * <ul> 998 * <li>The bit initially has the value {@code true}, and the corresponding bit in the argument has the value 999 * {@code false}. 1000 * <li>The bit initially has the value {@code false}, and the corresponding bit in the argument has the value 1001 * {@code true}. 1002 * </ul> 1003 * 1004 * @param set 1005 * a bit set 1006 */ 1007 public void xor(BitSetFX set) { 1008 int wordsInCommon = Math.min(wordsInUse, set.wordsInUse); 1009 1010 if (wordsInUse < set.wordsInUse) { 1011 ensureCapacity(set.wordsInUse); 1012 wordsInUse = set.wordsInUse; 1013 } 1014 1015 // Perform logical XOR on words in common 1016 for (int i = 0; i < wordsInCommon; i++) 1017 words[i] ^= set.words[i]; 1018 1019 // Copy any remaining words 1020 if (wordsInCommon < set.wordsInUse) 1021 System.arraycopy(set.words, wordsInCommon, words, wordsInCommon, set.wordsInUse - wordsInCommon); 1022 1023 recalculateWordsInUse(); 1024 checkInvariants(); 1025 } 1026 1027 /** 1028 * Clears all of the bits in this {@code BitSet} whose corresponding bit is set in the specified {@code BitSet}. 1029 * 1030 * @param set 1031 * the {@code BitSet} with which to mask this {@code BitSet} 1032 * @since 1.2 1033 */ 1034 public void andNot(BitSetFX set) { 1035 // Perform logical (a & !b) on words in common 1036 for (int i = Math.min(wordsInUse, set.wordsInUse) - 1; i >= 0; i--) 1037 words[i] &= ~set.words[i]; 1038 1039 recalculateWordsInUse(); 1040 checkInvariants(); 1041 } 1042 1043 /** 1044 * Returns the hash code value for this bit set. The hash code depends only on which bits are set within this 1045 * {@code BitSet}. 1046 * 1047 * <p> 1048 * The hash code is defined to be the result of the following calculation: 1049 * 1050 * <pre> 1051 * {@code 1052 * public int hashCode() { 1053 * long h = 1234; 1054 * long[] words = toLongArray(); 1055 * for (int i = words.length; --i >= 0; ) 1056 * h ^= words[i] * (i + 1); 1057 * return (int)((h >> 32) ^ h); 1058 * }} 1059 * </pre> 1060 * 1061 * Note that the hash code changes if the set of bits is altered. 1062 * 1063 * @return the hash code value for this bit set 1064 */ 1065 public int hashCode() { 1066 long h = 1234; 1067 for (int i = wordsInUse; --i >= 0;) 1068 h ^= words[i] * (i + 1); 1069 1070 return (int) ((h >> 32) ^ h); 1071 } 1072 1073 /** 1074 * Returns the number of bits of space actually in use by this {@code BitSet} to represent bit values. The maximum 1075 * element in the set is the size - 1st element. 1076 * 1077 * @return the number of bits currently in this bit set 1078 */ 1079 public int space() { 1080 return words.length * BITS_PER_WORD; 1081 } 1082 1083 public int size() { 1084 return cardinality(); 1085 } 1086 1087 /** 1088 * Compares this object against the specified object. The result is {@code true} if and only if the argument is not 1089 * {@code null} and is a {@code Bitset} object that has exactly the same set of bits set to {@code true} as this bit 1090 * set. That is, for every nonnegative {@code int} index {@code k}, 1091 * 1092 * <pre> 1093 * ((BitSet) obj).get(k) == this.get(k) 1094 * </pre> 1095 * 1096 * must be true. The current sizes of the two bit sets are not compared. 1097 * 1098 * @param obj 1099 * the object to compare with 1100 * @return {@code true} if the objects are the same; {@code false} otherwise 1101 * @see #space() 1102 */ 1103 public boolean equals(Object obj) { 1104 if (!(obj instanceof BitSetFX)) 1105 return false; 1106 if (this == obj) 1107 return true; 1108 1109 BitSetFX set = (BitSetFX) obj; 1110 1111 trimToSize(); 1112 set.trimToSize(); 1113 1114 checkInvariants(); 1115 set.checkInvariants(); 1116 1117 if (wordsInUse != set.wordsInUse) 1118 return false; 1119 1120 // Check words in use by both BitSets 1121 for (int i = 0; i < wordsInUse; i++) 1122 if (words[i] != set.words[i]) 1123 return false; 1124 1125 return true; 1126 } 1127 1128 /** 1129 * Cloning this {@code BitSet} produces a new {@code BitSet} that is equal to it. The clone of the bit set is another 1130 * bit set that has exactly the same bits set to {@code true} as this bit set. 1131 * 1132 * @return a clone of this bit set 1133 * @see #space() 1134 */ 1135 public Object clone() { 1136 if (!sizeIsSticky) 1137 trimToSize(); 1138 1139 try { 1140 BitSetFX result = (BitSetFX) super.clone(); 1141 result.words = words.clone(); 1142 result.checkInvariants(); 1143 return result; 1144 } catch (CloneNotSupportedException e) { 1145 throw new InternalError(e); 1146 } 1147 } 1148 1149 /** 1150 * Attempts to reduce internal storage used for the bits in this bit set. Calling this method may, but is not required 1151 * to, affect the value returned by a subsequent call to the {@link #space()} method. 1152 */ 1153 private void trimToSize() { 1154 if (wordsInUse != words.length) { 1155 words = Arrays.copyOf(words, wordsInUse); 1156 checkInvariants(); 1157 } 1158 } 1159 1160 /** 1161 * Save the state of the {@code BitSet} instance to a stream (i.e., serialize it). 1162 */ 1163 private void writeObject(ObjectOutputStream s) throws IOException { 1164 1165 checkInvariants(); 1166 1167 if (!sizeIsSticky) 1168 trimToSize(); 1169 1170 ObjectOutputStream.PutField fields = s.putFields(); 1171 fields.put("bits", words); 1172 s.writeFields(); 1173 } 1174 1175 /** 1176 * Reconstitute the {@code BitSet} instance from a stream (i.e., deserialize it). 1177 */ 1178 private void readObject(ObjectInputStream s) throws IOException, ClassNotFoundException { 1179 1180 ObjectInputStream.GetField fields = s.readFields(); 1181 words = (long[]) fields.get("bits", null); 1182 1183 // Assume maximum length then find real length 1184 // because recalculateWordsInUse assumes maintenance 1185 // or reduction in logical size 1186 wordsInUse = words.length; 1187 recalculateWordsInUse(); 1188 sizeIsSticky = (words.length > 0 && words[words.length - 1] == 0L); // heuristic 1189 checkInvariants(); 1190 } 1191 1192 /** 1193 * Returns a string representation of this bit set. For every index for which this {@code BitSet} contains a bit in 1194 * the set state, the decimal representation of that index is included in the result. Such indices are listed in order 1195 * from lowest to highest, separated by ", " (a comma and a space) and surrounded by braces, resulting in the 1196 * usual mathematical notation for a set of integers. 1197 * 1198 * <p> 1199 * Example: 1200 * 1201 * <pre> 1202 * 1203 * BitSet drPepper = new BitSet(); 1204 * </pre> 1205 * 1206 * Now {@code drPepper.toString()} returns "{@code {}}". 1207 * 1208 * <pre> 1209 * drPepper.set(2); 1210 * </pre> 1211 * 1212 * Now {@code drPepper.toString()} returns "{@code {2}}". 1213 * 1214 * <pre> 1215 * drPepper.set(4); 1216 * drPepper.set(10); 1217 * </pre> 1218 * 1219 * Now {@code drPepper.toString()} returns "{@code {2, 4, 10}}". 1220 * 1221 * @return a string representation of this bit set 1222 */ 1223 public String toString() { 1224 checkInvariants(); 1225 1226 int numBits = (wordsInUse > 128) ? cardinality() : wordsInUse * BITS_PER_WORD; 1227 StringBuilder b = new StringBuilder(6 * numBits + 2); 1228 b.append('{'); 1229 1230 int i = nextSetBit(0); 1231 if (i != -1) { 1232 b.append(i); 1233 while (true) { 1234 if (++i < 0) 1235 break; 1236 if ((i = nextSetBit(i)) < 0) 1237 break; 1238 int endOfRun = nextClearBit(i); 1239 do { 1240 b.append(", ").append(i); 1241 } while (++i != endOfRun); 1242 } 1243 } 1244 1245 b.append('}'); 1246 return b.toString(); 1247 } 1248 1249 /** 1250 * Returns a stream of indices for which this {@code BitSet} contains a bit in the set state. The indices are returned 1251 * in order, from lowest to highest. The size of the stream is the number of bits in the set state, equal to the value 1252 * returned by the {@link #cardinality()} method. 1253 * 1254 * <p> 1255 * The bit set must remain constant during the execution of the terminal stream operation. Otherwise, the result of 1256 * the terminal stream operation is undefined. 1257 * 1258 * @return a stream of integers representing set indices 1259 * @since 1.8 1260 */ 1261 public Stream<Integer> stream() { 1262 return StreamSupport.stream( 1263 () -> Spliterators 1264 .spliterator(iterator(), cardinality(), Spliterator.ORDERED | Spliterator.DISTINCT | Spliterator.SORTED), 1265 Spliterator.SIZED | Spliterator.SUBSIZED | Spliterator.ORDERED | Spliterator.DISTINCT | Spliterator.SORTED, 1266 false); 1267 } 1268 1269 public Iterator<Integer> iterator() { 1270 class BitSetIterator implements PrimitiveIterator.OfInt { 1271 1272 int next = nextSetBit(0); 1273 1274 @Override 1275 public boolean hasNext() { 1276 return next != -1; 1277 } 1278 1279 @Override 1280 public int nextInt() { 1281 if (next != -1) { 1282 int ret = next; 1283 next = nextSetBit(next + 1); 1284 return ret; 1285 } else { 1286 throw new NoSuchElementException(); 1287 } 1288 } 1289 } 1290 return new BitSetIterator(); 1291 } 1292 1293 public void and(final BitSetFX... sets) { 1294 and(Arrays.asList(sets)); 1295 } 1296 1297 public void and(final Collection<BitSetFX> sets) { 1298 if (sets.isEmpty()) 1299 return; 1300 1301 final Integer minWordsInUse = sets.stream().map(set -> set.wordsInUse).min(Integer::compare).get(); 1302 while (wordsInUse > minWordsInUse) 1303 words[--wordsInUse] = 0; 1304 1305 // Perform logical AND on words in common 1306 for (int i = 0; i < wordsInUse; i++) 1307 for (BitSetFX set : sets) 1308 words[i] &= set.words[i]; 1309 1310 recalculateWordsInUse(); 1311 checkInvariants(); 1312 } 1313 1314 public BitSetFX(final BitSetFX b) { 1315 this(); 1316 or(b); 1317 } 1318 1319 public BitSetFX(final Collection<? extends Integer> c) { 1320 this(); 1321 addAll(c); 1322 } 1323 1324 public boolean geq(final BitSetFX set) { 1325 trimToSize(); 1326 set.trimToSize(); 1327 1328 checkInvariants(); 1329 set.checkInvariants(); 1330 1331 if (set.wordsInUse == 0) 1332 return true; 1333 if (set.wordsInUse > wordsInUse) 1334 return false; 1335 for (int i = set.wordsInUse - 1; i >= 0; i--) 1336 if ((set.words[i] & words[i]) != set.words[i]) 1337 return false; 1338 return true; 1339 } 1340 1341 public boolean contains(Object o) { 1342 return get((Integer) o); 1343 } 1344 1345 public boolean containsAll(Collection<?> c) { 1346 if (c instanceof BitSetFX) { 1347 final BitSetFX other = (BitSetFX) c; 1348 return this.geq(other); 1349 } else { 1350 for (Object o : c) 1351 if (!get((Integer) o)) 1352 return false; 1353 return true; 1354 } 1355 } 1356 1357 public boolean add(final Integer e) { 1358 if (get(e)) 1359 return false; 1360 set(e); 1361 return true; 1362 } 1363 1364 public boolean addAll(final Collection<? extends Integer> c) { 1365 if (c instanceof BitSetFX) { 1366 final int cardinality = cardinality(); 1367 or((BitSetFX) c); 1368 return cardinality != cardinality(); 1369 } else { 1370 boolean changed = false; 1371 for (int e : c) 1372 changed |= add(e); 1373 return changed; 1374 } 1375 } 1376 1377 public void addRange(int start, int end) { 1378 set(start, end); 1379 } 1380 1381 public boolean remove(Object o) { 1382 if (o instanceof Integer) { 1383 final int e = (Integer) o; 1384 if (get(e)) { 1385 clear(e); 1386 return true; 1387 } 1388 } 1389 return false; 1390 } 1391 1392 public boolean removeAll(Collection<?> c) { 1393 if (c instanceof BitSetFX) { 1394 final int cardinality = cardinality(); 1395 andNot((BitSetFX) c); 1396 return cardinality != cardinality(); 1397 } else { 1398 boolean changed = false; 1399 for (Object e : c) 1400 changed |= remove(e); 1401 return changed; 1402 } 1403 } 1404 1405 @Override 1406 public boolean retainAll(Collection<?> c) { 1407 if (c instanceof BitSetFX) { 1408 final int cardinality = cardinality(); 1409 and((BitSetFX) c); 1410 return cardinality != cardinality(); 1411 } else { 1412 boolean changed = false; 1413 for (int i = nextSetBit(0); i != -1; i = nextSetBit(i)) 1414 if (!c.contains(i)) { 1415 clear(i); 1416 changed = true; 1417 } 1418 return changed; 1419 } 1420 } 1421 1422 public Comparator<? super Integer> comparator() { 1423 return Integer::compare; 1424 } 1425 1426 public SortedSet<Integer> subSet(Integer fromElement, Integer toElement) { 1427 return get(fromElement, toElement); 1428 } 1429 1430 public SortedSet<Integer> headSet(Integer toElement) { 1431 return get(0, toElement); 1432 } 1433 1434 public SortedSet<Integer> tailSet(Integer fromElement) { 1435 return get(fromElement, length()); 1436 } 1437 1438 public Integer first() { 1439 return nextSetBit(0); 1440 } 1441 1442 public Integer last() { 1443 return length() - 1; 1444 } 1445 1446}