| /* |
| * Licensed to the Apache Software Foundation (ASF) under one or more |
| * contributor license agreements. See the NOTICE file distributed with |
| * this work for additional information regarding copyright ownership. |
| * The ASF licenses this file to You under the Apache License, Version 2.0 |
| * (the "License"); you may not use this file except in compliance with |
| * the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| package java.util; |
| |
| import java.io.Serializable; |
| |
| import org.apache.harmony.luni.util.Msg; |
| |
| /** |
| * The {@code BitSet} class implements a bit field. Each element in a |
| * {@code BitSet} can be on(1) or off(0). A {@code BitSet} is created with a |
| * given size and grows if this size is exceeded. Growth is always rounded to a |
| * 64 bit boundary. |
| * |
| * @since Android 1.0 |
| */ |
| public class BitSet implements Serializable, Cloneable { |
| private static final long serialVersionUID = 7997698588986878753L; |
| |
| // Size in bits of the data type being used in the bits array |
| private static final int ELM_SIZE = 64; |
| |
| private long[] bits; |
| |
| /** |
| * Create a new {@code BitSet} with size equal to 64 bits. |
| * |
| * @see #clear(int) |
| * @see #set(int) |
| * @see #clear() |
| * @see #clear(int, int) |
| * @see #set(int, boolean) |
| * @see #set(int, int) |
| * @see #set(int, int, boolean) |
| * @since Android 1.0 |
| */ |
| public BitSet() { |
| this(64); |
| } |
| |
| /** |
| * Create a new {@code BitSet} with size equal to nbits. If nbits is not a |
| * multiple of 64, then create a {@code BitSet} with size nbits rounded to |
| * the next closest multiple of 64. |
| * |
| * @param nbits |
| * the size of the bit set. |
| * @throws NegativeArraySizeException |
| * if {@code nbits} is negative. |
| * @see #clear(int) |
| * @see #set(int) |
| * @see #clear() |
| * @see #clear(int, int) |
| * @see #set(int, boolean) |
| * @see #set(int, int) |
| * @see #set(int, int, boolean) |
| * @since Android 1.0 |
| */ |
| public BitSet(int nbits) { |
| if (nbits >= 0) { |
| bits = new long[(nbits / ELM_SIZE) + (nbits % ELM_SIZE > 0 ? 1 : 0)]; |
| } else { |
| throw new NegativeArraySizeException(); |
| } |
| } |
| |
| /** |
| * Private constructor called from get(int, int) method |
| * |
| * @param bits |
| * the size of the bit set |
| */ |
| private BitSet(long[] bits) { |
| this.bits = bits; |
| } |
| |
| /** |
| * Creates a copy of this {@code BitSet}. |
| * |
| * @return a copy of this {@code BitSet}. |
| * @since Android 1.0 |
| */ |
| @Override |
| public Object clone() { |
| try { |
| BitSet clone = (BitSet) super.clone(); |
| clone.bits = bits.clone(); |
| return clone; |
| } catch (CloneNotSupportedException e) { |
| return null; |
| } |
| } |
| |
| /** |
| * Compares the argument to this {@code BitSet} and returns whether they are |
| * equal. The object must be an instance of {@code BitSet} with the same |
| * bits set. |
| * |
| * @param obj |
| * the {@code BitSet} object to compare. |
| * @return a {@code boolean} indicating whether or not this {@code BitSet} and |
| * {@code obj} are equal. |
| * @see #hashCode |
| * @since Android 1.0 |
| */ |
| @Override |
| public boolean equals(Object obj) { |
| if (this == obj) { |
| return true; |
| } |
| if (obj instanceof BitSet) { |
| long[] bsBits = ((BitSet) obj).bits; |
| int length1 = bits.length, length2 = bsBits.length; |
| // If one of the BitSets is larger than the other, check to see if |
| // any of |
| // its extra bits are set. If so return false. |
| if (length1 <= length2) { |
| for (int i = 0; i < length1; i++) { |
| if (bits[i] != bsBits[i]) { |
| return false; |
| } |
| } |
| for (int i = length1; i < length2; i++) { |
| if (bsBits[i] != 0) { |
| return false; |
| } |
| } |
| } else { |
| for (int i = 0; i < length2; i++) { |
| if (bits[i] != bsBits[i]) { |
| return false; |
| } |
| } |
| for (int i = length2; i < length1; i++) { |
| if (bits[i] != 0) { |
| return false; |
| } |
| } |
| } |
| return true; |
| } |
| return false; |
| } |
| |
| /** |
| * Increase the size of the internal array to accommodate {@code pos} bits. |
| * The new array max index will be a multiple of 64. |
| * |
| * @param pos |
| * the index the new array needs to be able to access. |
| * @since Android 1.0 |
| */ |
| private void growBits(int pos) { |
| pos++; // Inc to get correct bit count |
| long[] tempBits = new long[(pos / ELM_SIZE) |
| + (pos % ELM_SIZE > 0 ? 1 : 0)]; |
| System.arraycopy(bits, 0, tempBits, 0, bits.length); |
| bits = tempBits; |
| } |
| |
| /** |
| * Computes the hash code for this {@code BitSet}. If two {@code BitSet}s are equal |
| * the have to return the same result for {@code hashCode()}. |
| * |
| * @return the {@code int} representing the hash code for this bit |
| * set. |
| * @see #equals |
| * @see java.util.Hashtable |
| * @since Android 1.0 |
| */ |
| @Override |
| public int hashCode() { |
| long x = 1234; |
| // for (int i = 0, length = bits.length; i < length; i+=2) |
| // x ^= (bits[i] + ((long)bits[i+1] << 32)) * (i/2 + 1); |
| for (int i = 0, length = bits.length; i < length; i++) { |
| x ^= bits[i] * (i + 1); |
| } |
| return (int) ((x >> 32) ^ x); |
| } |
| |
| /** |
| * Retrieves the bit at index {@code pos}. Grows the {@code BitSet} if |
| * {@code pos > size}. |
| * |
| * @param pos |
| * the index of the bit to be retrieved. |
| * @return {@code true} if the bit at {@code pos} is set, |
| * {@code false} otherwise. |
| * @throws IndexOutOfBoundsException |
| * if {@code pos} is negative. |
| * @see #clear(int) |
| * @see #set(int) |
| * @see #clear() |
| * @see #clear(int, int) |
| * @see #set(int, boolean) |
| * @see #set(int, int) |
| * @see #set(int, int, boolean) |
| * @since Android 1.0 |
| */ |
| public boolean get(int pos) { |
| if (pos >= 0) { |
| if (pos < bits.length * ELM_SIZE) { |
| return (bits[pos / ELM_SIZE] & (1L << (pos % ELM_SIZE))) != 0; |
| } |
| return false; |
| } |
| // Negative index specified |
| throw new IndexOutOfBoundsException(Msg.getString("K0006")); //$NON-NLS-1$ |
| } |
| |
| /** |
| * Retrieves the bits starting from {@code pos1} to {@code pos2} and returns |
| * back a new bitset made of these bits. Grows the {@code BitSet} if |
| * {@code pos2 > size}. |
| * |
| * @param pos1 |
| * beginning position. |
| * @param pos2 |
| * ending position. |
| * @return new bitset of the range specified. |
| * @throws IndexOutOfBoundsException |
| * if {@code pos1} or {@code pos2} is negative, or if |
| * {@code pos2} is smaller than {@code pos1}. |
| * @see #get(int) |
| * @since Android 1.0 |
| */ |
| public BitSet get(int pos1, int pos2) { |
| if (pos1 >= 0 && pos2 >= 0 && pos2 >= pos1) { |
| int last = (bits.length * ELM_SIZE); |
| if (pos1 >= last || pos1 == pos2) { |
| return new BitSet(0); |
| } |
| if (pos2 > last) { |
| pos2 = last; |
| } |
| |
| int idx1 = pos1 / ELM_SIZE; |
| int idx2 = (pos2 - 1) / ELM_SIZE; |
| long factor1 = (~0L) << (pos1 % ELM_SIZE); |
| long factor2 = (~0L) >>> (ELM_SIZE - (pos2 % ELM_SIZE)); |
| |
| if (idx1 == idx2) { |
| long result = (bits[idx1] & (factor1 & factor2)) >>> (pos1 % ELM_SIZE); |
| return new BitSet(new long[] { result }); |
| } |
| long[] newbits = new long[idx2 - idx1 + 1]; |
| // first fill in the first and last indexes in the new bitset |
| newbits[0] = bits[idx1] & factor1; |
| newbits[newbits.length - 1] = bits[idx2] & factor2; |
| |
| // fill in the in between elements of the new bitset |
| for (int i = 1; i < idx2 - idx1; i++) { |
| newbits[i] = bits[idx1 + i]; |
| } |
| |
| // shift all the elements in the new bitset to the right by pos1 |
| // % ELM_SIZE |
| int numBitsToShift = pos1 % ELM_SIZE; |
| if (numBitsToShift != 0) { |
| for (int i = 0; i < newbits.length; i++) { |
| // shift the current element to the right regardless of |
| // sign |
| newbits[i] = newbits[i] >>> (numBitsToShift); |
| |
| // apply the last x bits of newbits[i+1] to the current |
| // element |
| if (i != newbits.length - 1) { |
| newbits[i] |= newbits[i + 1] << (ELM_SIZE - (numBitsToShift)); |
| } |
| } |
| } |
| return new BitSet(newbits); |
| } |
| throw new IndexOutOfBoundsException(Msg.getString("K0006")); //$NON-NLS-1$ |
| } |
| |
| /** |
| * Sets the bit at index {@code pos} to 1. Grows the {@code BitSet} if |
| * {@code pos > size}. |
| * |
| * @param pos |
| * the index of the bit to set. |
| * @throws IndexOutOfBoundsException |
| * if {@code pos} is negative. |
| * @see #clear(int) |
| * @see #clear() |
| * @see #clear(int, int) |
| * @since Android 1.0 |
| */ |
| public void set(int pos) { |
| if (pos >= 0) { |
| if (pos >= bits.length * ELM_SIZE) { |
| growBits(pos); |
| } |
| bits[pos / ELM_SIZE] |= 1L << (pos % ELM_SIZE); |
| } else { |
| throw new IndexOutOfBoundsException(Msg.getString("K0006")); //$NON-NLS-1$ |
| } |
| } |
| |
| /** |
| * Sets the bit at index {@code pos} to {@code val}. Grows the |
| * {@code BitSet} if {@code pos > size}. |
| * |
| * @param pos |
| * the index of the bit to set. |
| * @param val |
| * value to set the bit. |
| * @throws IndexOutOfBoundsException |
| * if {@code pos} is negative. |
| * @see #set(int) |
| * @since Android 1.0 |
| */ |
| public void set(int pos, boolean val) { |
| if (val) { |
| set(pos); |
| } else { |
| clear(pos); |
| } |
| } |
| |
| /** |
| * Sets the bits starting from {@code pos1} to {@code pos2}. Grows the |
| * {@code BitSet} if {@code pos2 > size}. |
| * |
| * @param pos1 |
| * beginning position. |
| * @param pos2 |
| * ending position. |
| * @throws IndexOutOfBoundsException |
| * if {@code pos1} or {@code pos2} is negative, or if |
| * {@code pos2} is smaller than {@code pos1}. |
| * @see #set(int) |
| * @since Android 1.0 |
| */ |
| public void set(int pos1, int pos2) { |
| if (pos1 >= 0 && pos2 >= 0 && pos2 >= pos1) { |
| if (pos1 == pos2) { |
| return; |
| } |
| if (pos2 >= bits.length * ELM_SIZE) { |
| growBits(pos2); |
| } |
| |
| int idx1 = pos1 / ELM_SIZE; |
| int idx2 = (pos2 - 1) / ELM_SIZE; |
| long factor1 = (~0L) << (pos1 % ELM_SIZE); |
| long factor2 = (~0L) >>> (ELM_SIZE - (pos2 % ELM_SIZE)); |
| |
| if (idx1 == idx2) { |
| bits[idx1] |= (factor1 & factor2); |
| } else { |
| bits[idx1] |= factor1; |
| bits[idx2] |= factor2; |
| for (int i = idx1 + 1; i < idx2; i++) { |
| bits[i] |= (~0L); |
| } |
| } |
| } else { |
| throw new IndexOutOfBoundsException(Msg.getString("K0006")); //$NON-NLS-1$ |
| } |
| } |
| |
| /** |
| * Sets the bits starting from {@code pos1} to {@code pos2} to the given |
| * {@code val}. Grows the {@code BitSet} if {@code pos2 > size}. |
| * |
| * @param pos1 |
| * beginning position. |
| * @param pos2 |
| * ending position. |
| * @param val |
| * value to set these bits. |
| * @throws IndexOutOfBoundsException |
| * if {@code pos1} or {@code pos2} is negative, or if |
| * {@code pos2} is smaller than {@code pos1}. |
| * @see #set(int,int) |
| * @since Android 1.0 |
| */ |
| public void set(int pos1, int pos2, boolean val) { |
| if (val) { |
| set(pos1, pos2); |
| } else { |
| clear(pos1, pos2); |
| } |
| } |
| |
| /** |
| * Clears all the bits in this {@code BitSet}. |
| * |
| * @see #clear(int) |
| * @see #clear(int, int) |
| * @since Android 1.0 |
| */ |
| public void clear() { |
| for (int i = 0; i < bits.length; i++) { |
| bits[i] = 0L; |
| } |
| } |
| |
| /** |
| * Clears the bit at index {@code pos}. Grows the {@code BitSet} if |
| * {@code pos > size}. |
| * |
| * @param pos |
| * the index of the bit to clear. |
| * @throws IndexOutOfBoundsException |
| * if {@code pos} is negative. |
| * @see #clear(int, int) |
| * @since Android 1.0 |
| */ |
| public void clear(int pos) { |
| if (pos >= 0) { |
| if (pos < bits.length * ELM_SIZE) { |
| bits[pos / ELM_SIZE] &= ~(1L << (pos % ELM_SIZE)); |
| } |
| } else { |
| // Negative index specified |
| throw new IndexOutOfBoundsException(Msg.getString("K0006")); //$NON-NLS-1$ |
| } |
| } |
| |
| /** |
| * Clears the bits starting from {@code pos1} to {@code pos2}. Grows the |
| * {@code BitSet} if {@code pos2 > size}. |
| * |
| * @param pos1 |
| * beginning position. |
| * @param pos2 |
| * ending position. |
| * @throws IndexOutOfBoundsException |
| * if {@code pos1} or {@code pos2} is negative, or if |
| * {@code pos2} is smaller than {@code pos1}. |
| * @see #clear(int) |
| * @since Android 1.0 |
| */ |
| public void clear(int pos1, int pos2) { |
| if (pos1 >= 0 && pos2 >= 0 && pos2 >= pos1) { |
| int last = (bits.length * ELM_SIZE); |
| if (pos1 >= last || pos1 == pos2) { |
| return; |
| } |
| if (pos2 > last) { |
| pos2 = last; |
| } |
| |
| int idx1 = pos1 / ELM_SIZE; |
| int idx2 = (pos2 - 1) / ELM_SIZE; |
| long factor1 = (~0L) << (pos1 % ELM_SIZE); |
| long factor2 = (~0L) >>> (ELM_SIZE - (pos2 % ELM_SIZE)); |
| |
| if (idx1 == idx2) { |
| bits[idx1] &= ~(factor1 & factor2); |
| } else { |
| bits[idx1] &= ~factor1; |
| bits[idx2] &= ~factor2; |
| for (int i = idx1 + 1; i < idx2; i++) { |
| bits[i] = 0L; |
| } |
| } |
| } else { |
| throw new IndexOutOfBoundsException(Msg.getString("K0006")); //$NON-NLS-1$ |
| } |
| } |
| |
| /** |
| * Flips the bit at index {@code pos}. Grows the {@code BitSet} if |
| * {@code pos > size}. |
| * |
| * @param pos |
| * the index of the bit to flip. |
| * @throws IndexOutOfBoundsException |
| * if {@code pos} is negative. |
| * @see #flip(int, int) |
| * @since Android 1.0 |
| */ |
| public void flip(int pos) { |
| if (pos >= 0) { |
| if (pos >= bits.length * ELM_SIZE) { |
| growBits(pos); |
| } |
| bits[pos / ELM_SIZE] ^= 1L << (pos % ELM_SIZE); |
| } else { |
| throw new IndexOutOfBoundsException(Msg.getString("K0006")); //$NON-NLS-1$ |
| } |
| } |
| |
| /** |
| * Flips the bits starting from {@code pos1} to {@code pos2}. Grows the |
| * {@code BitSet} if {@code pos2 > size}. |
| * |
| * @param pos1 |
| * beginning position. |
| * @param pos2 |
| * ending position. |
| * @throws IndexOutOfBoundsException |
| * if {@code pos1} or {@code pos2} is negative, or if |
| * {@code pos2} is smaller than {@code pos1}. |
| * @see #flip(int) |
| * @since Android 1.0 |
| */ |
| public void flip(int pos1, int pos2) { |
| if (pos1 >= 0 && pos2 >= 0 && pos2 >= pos1) { |
| if (pos1 == pos2) { |
| return; |
| } |
| if (pos2 >= bits.length * ELM_SIZE) { |
| growBits(pos2); |
| } |
| |
| int idx1 = pos1 / ELM_SIZE; |
| int idx2 = (pos2 - 1) / ELM_SIZE; |
| long factor1 = (~0L) << (pos1 % ELM_SIZE); |
| long factor2 = (~0L) >>> (ELM_SIZE - (pos2 % ELM_SIZE)); |
| |
| if (idx1 == idx2) { |
| bits[idx1] ^= (factor1 & factor2); |
| } else { |
| bits[idx1] ^= factor1; |
| bits[idx2] ^= factor2; |
| for (int i = idx1 + 1; i < idx2; i++) { |
| bits[i] ^= (~0L); |
| } |
| } |
| } else { |
| throw new IndexOutOfBoundsException(Msg.getString("K0006")); //$NON-NLS-1$ |
| } |
| } |
| |
| /** |
| * Checks if these two {@code BitSet}s have at least one bit set to true in the same |
| * position. |
| * |
| * @param bs |
| * {@code BitSet} used to calculate the intersection. |
| * @return {@code true} if bs intersects with this {@code BitSet}, |
| * {@code false} otherwise. |
| * @since Android 1.0 |
| */ |
| public boolean intersects(BitSet bs) { |
| long[] bsBits = bs.bits; |
| int length1 = bits.length, length2 = bsBits.length; |
| |
| if (length1 <= length2) { |
| for (int i = 0; i < length1; i++) { |
| if ((bits[i] & bsBits[i]) != 0L) { |
| return true; |
| } |
| } |
| } else { |
| for (int i = 0; i < length2; i++) { |
| if ((bits[i] & bsBits[i]) != 0L) { |
| return true; |
| } |
| } |
| } |
| |
| return false; |
| } |
| |
| /** |
| * Performs the logical AND of this {@code BitSet} with another |
| * {@code BitSet}. The values of this {@code BitSet} are changed accordingly. |
| * |
| * @param bs |
| * {@code BitSet} to AND with. |
| * @see #or |
| * @see #xor |
| * @since Android 1.0 |
| */ |
| |
| public void and(BitSet bs) { |
| long[] bsBits = bs.bits; |
| int length1 = bits.length, length2 = bsBits.length; |
| if (length1 <= length2) { |
| for (int i = 0; i < length1; i++) { |
| bits[i] &= bsBits[i]; |
| } |
| } else { |
| for (int i = 0; i < length2; i++) { |
| bits[i] &= bsBits[i]; |
| } |
| for (int i = length2; i < length1; i++) { |
| bits[i] = 0; |
| } |
| } |
| } |
| |
| /** |
| * Clears all bits in the receiver which are also set in the parameter |
| * {@code BitSet}. The values of this {@code BitSet} are changed accordingly. |
| * |
| * @param bs |
| * {@code BitSet} to ANDNOT with. |
| * @since Android 1.0 |
| */ |
| public void andNot(BitSet bs) { |
| long[] bsBits = bs.bits; |
| int range = bits.length < bsBits.length ? bits.length : bsBits.length; |
| for (int i = 0; i < range; i++) { |
| bits[i] &= ~bsBits[i]; |
| } |
| } |
| |
| /** |
| * Performs the logical OR of this {@code BitSet} with another {@code BitSet}. |
| * The values of this {@code BitSet} are changed accordingly. |
| * |
| * @param bs |
| * {@code BitSet} to OR with. |
| * @see #xor |
| * @see #and |
| * @since Android 1.0 |
| */ |
| public void or(BitSet bs) { |
| int nbits = bs.length(); |
| int length = nbits / ELM_SIZE + (nbits % ELM_SIZE > 0 ? 1 : 0); |
| if (length > bits.length) { |
| growBits(nbits - 1); |
| } |
| long[] bsBits = bs.bits; |
| for (int i = 0; i < length; i++) { |
| bits[i] |= bsBits[i]; |
| } |
| } |
| |
| /** |
| * Performs the logical XOR of this {@code BitSet} with another {@code BitSet}. |
| * The values of this {@code BitSet} are changed accordingly. |
| * |
| * @param bs |
| * {@code BitSet} to XOR with. |
| * @see #or |
| * @see #and |
| * @since Android 1.0 |
| */ |
| public void xor(BitSet bs) { |
| int nbits = bs.length(); |
| int length = nbits / ELM_SIZE + (nbits % ELM_SIZE > 0 ? 1 : 0); |
| if (length > bits.length) { |
| growBits(nbits - 1); |
| } |
| long[] bsBits = bs.bits; |
| for (int i = 0; i < length; i++) { |
| bits[i] ^= bsBits[i]; |
| } |
| |
| } |
| |
| /** |
| * Returns the number of bits this {@code BitSet} has. |
| * |
| * @return the number of bits contained in this {@code BitSet}. |
| * @see #length |
| * @since Android 1.0 |
| */ |
| public int size() { |
| return bits.length * ELM_SIZE; |
| } |
| |
| /** |
| * Returns the number of bits up to and including the highest bit set. |
| * |
| * @return the length of the {@code BitSet}. |
| * @since Android 1.0 |
| */ |
| public int length() { |
| int idx = bits.length - 1; |
| while (idx >= 0 && bits[idx] == 0) { |
| --idx; |
| } |
| if (idx == -1) { |
| return 0; |
| } |
| int i = ELM_SIZE - 1; |
| long val = bits[idx]; |
| while ((val & (1L << i)) == 0 && i > 0) { |
| i--; |
| } |
| return idx * ELM_SIZE + i + 1; |
| } |
| |
| /** |
| * Returns a string containing a concise, human-readable description of the |
| * receiver. |
| * |
| * @return a comma delimited list of the indices of all bits that are set. |
| * @since Android 1.0 |
| */ |
| @Override |
| public String toString() { |
| StringBuffer sb = new StringBuffer(bits.length / 2); |
| int bitCount = 0; |
| sb.append('{'); |
| boolean comma = false; |
| for (int i = 0; i < bits.length; i++) { |
| if (bits[i] == 0) { |
| bitCount += ELM_SIZE; |
| continue; |
| } |
| for (int j = 0; j < ELM_SIZE; j++) { |
| if (((bits[i] & (1L << j)) != 0)) { |
| if (comma) { |
| sb.append(", "); //$NON-NLS-1$ |
| } |
| sb.append(bitCount); |
| comma = true; |
| } |
| bitCount++; |
| } |
| } |
| sb.append('}'); |
| return sb.toString(); |
| } |
| |
| /** |
| * Returns the position of the first bit that is {@code true} on or after {@code pos}. |
| * |
| * @param pos |
| * the starting position (inclusive). |
| * @return -1 if there is no bits that are set to {@code true} on or after {@code pos}. |
| * @since Android 1.0 |
| */ |
| public int nextSetBit(int pos) { |
| if (pos >= 0) { |
| if (pos >= bits.length * ELM_SIZE) { |
| return -1; |
| } |
| |
| int idx = pos / ELM_SIZE; |
| // first check in the same bit set element |
| if (bits[idx] != 0L) { |
| for (int j = pos % ELM_SIZE; j < ELM_SIZE; j++) { |
| if (((bits[idx] & (1L << j)) != 0)) { |
| return idx * ELM_SIZE + j; |
| } |
| } |
| |
| } |
| idx++; |
| while (idx < bits.length && bits[idx] == 0L) { |
| idx++; |
| } |
| if (idx == bits.length) { |
| return -1; |
| } |
| |
| // we know for sure there is a bit set to true in this element |
| // since the bitset value is not 0L |
| for (int j = 0; j < ELM_SIZE; j++) { |
| if (((bits[idx] & (1L << j)) != 0)) { |
| return idx * ELM_SIZE + j; |
| } |
| } |
| |
| return -1; |
| } |
| throw new IndexOutOfBoundsException(Msg.getString("K0006")); //$NON-NLS-1$ |
| } |
| |
| /** |
| * Returns the position of the first bit that is {@code false} on or after {@code pos}. |
| * |
| * @param pos |
| * the starting position (inclusive). |
| * @return the position of the next bit set to {@code false}, even if it is further |
| * than this {@code BitSet}'s size. |
| * @since Android 1.0 |
| */ |
| public int nextClearBit(int pos) { |
| if (pos >= 0) { |
| int bssize = bits.length * ELM_SIZE; |
| if (pos >= bssize) { |
| return pos; |
| } |
| |
| int idx = pos / ELM_SIZE; |
| // first check in the same bit set element |
| if (bits[idx] != (~0L)) { |
| for (int j = pos % ELM_SIZE; j < ELM_SIZE; j++) { |
| if (((bits[idx] & (1L << j)) == 0)) { |
| return idx * ELM_SIZE + j; |
| } |
| } |
| |
| } |
| idx++; |
| while (idx < bits.length && bits[idx] == (~0L)) { |
| idx++; |
| } |
| if (idx == bits.length) { |
| return bssize; |
| } |
| |
| // we know for sure there is a bit set to true in this element |
| // since the bitset value is not 0L |
| for (int j = 0; j < ELM_SIZE; j++) { |
| if (((bits[idx] & (1L << j)) == 0)) { |
| return idx * ELM_SIZE + j; |
| } |
| } |
| |
| return bssize; |
| } |
| throw new IndexOutOfBoundsException(Msg.getString("K0006")); //$NON-NLS-1$ |
| } |
| |
| /** |
| * Returns true if all the bits in this {@code BitSet} are set to false. |
| * |
| * @return {@code true} if the {@code BitSet} is empty, |
| * {@code false} otherwise. |
| * @since Android 1.0 |
| */ |
| public boolean isEmpty() { |
| for (int idx = 0; idx < bits.length; idx++) { |
| if (bits[idx] != 0L) { |
| return false; |
| } |
| } |
| |
| return true; |
| } |
| |
| /** |
| * Returns the number of bits that are {@code true} in this {@code BitSet}. |
| * |
| * @return the number of {@code true} bits in the set. |
| * @since Android 1.0 |
| */ |
| public int cardinality() { |
| int count = 0; |
| for (int idx = 0; idx < bits.length; idx++) { |
| long temp = bits[idx]; |
| if (temp != 0L) { |
| for (int i = 0; i < ELM_SIZE; i++) { |
| if ((temp & (1L << i)) != 0L) { |
| count++; |
| } |
| } |
| } |
| } |
| return count; |
| } |
| } |