📄 bitset.java
字号:
/* BitSet.java -- A vector of bits. Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc.This file is part of GNU Classpath.GNU Classpath is free software; you can redistribute it and/or modifyit under the terms of the GNU General Public License as published bythe Free Software Foundation; either version 2, or (at your option)any later version.GNU Classpath is distributed in the hope that it will be useful, butWITHOUT ANY WARRANTY; without even the implied warranty ofMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNUGeneral Public License for more details.You should have received a copy of the GNU General Public Licensealong with GNU Classpath; see the file COPYING. If not, write to theFree Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA02111-1307 USA.Linking this library statically or dynamically with other modules ismaking a combined work based on this library. Thus, the terms andconditions of the GNU General Public License cover the wholecombination.As a special exception, the copyright holders of this library give youpermission to link this library with independent modules to produce anexecutable, regardless of the license terms of these independentmodules, and to copy and distribute the resulting executable underterms of your choice, provided that you also meet, for each linkedindependent module, the terms and conditions of the license of thatmodule. An independent module is a module which is not derived fromor based on this library. If you modify this library, you may extendthis exception to your version of the library, but you are notobligated to do so. If you do not wish to do so, delete thisexception statement from your version. */package java.util;import java.io.Serializable;/* Written using "Java Class Libraries", 2nd edition, ISBN 0-201-31002-3 * hashCode algorithm taken from JDK 1.2 docs. *//** * This class can be thought of in two ways. You can see it as a * vector of bits or as a set of non-negative integers. The name * <code>BitSet</code> is a bit misleading. * * It is implemented by a bit vector, but its equally possible to see * it as set of non-negative integer; each integer in the set is * represented by a set bit at the corresponding index. The size of * this structure is determined by the highest integer in the set. * * You can union, intersect and build (symmetric) remainders, by * invoking the logical operations and, or, andNot, resp. xor. * * This implementation is NOT synchronized against concurrent access from * multiple threads. Specifically, if one thread is reading from a bitset * while another thread is simultaneously modifying it, the results are * undefined. * * @author Jochen Hoenicke * @author Tom Tromey <tromey@cygnus.com> * @author Eric Blake <ebb9@email.byu.edu> * @status updated to 1.4 */public class BitSet implements Cloneable, Serializable{ /** * Compatible with JDK 1.0. */ private static final long serialVersionUID = 7997698588986878753L; /** * A common mask. */ private static final int LONG_MASK = 0x3f; /** * The actual bits. * @serial the i'th bit is in bits[i/64] at position i%64 (where position * 0 is the least significant). */ private long[] bits; /** * Create a new empty bit set. All bits are initially false. */ public BitSet() { this(64); } /** * Create a new empty bit set, with a given size. This * constructor reserves enough space to represent the integers * from <code>0</code> to <code>nbits-1</code>. * * @param nbits the initial size of the bit set * @throws NegativeArraySizeException if nbits < 0 */ public BitSet(int nbits) { if (nbits < 0) throw new NegativeArraySizeException(); int length = nbits >>> 6; if ((nbits & LONG_MASK) != 0) ++length; bits = new long[length]; } /** * Performs the logical AND operation on this bit set and the * given <code>set</code>. This means it builds the intersection * of the two sets. The result is stored into this bit set. * * @param set the second bit set * @throws NullPointerException if set is null */ public void and(BitSet bs) { int max = Math.min(bits.length, bs.bits.length); int i; for (i = 0; i < max; ++i) bits[i] &= bs.bits[i]; while (i < bits.length) bits[i++] = 0; } /** * Performs the logical AND operation on this bit set and the * complement of the given <code>set</code>. This means it * selects every element in the first set, that isn't in the * second set. The result is stored into this bit set. * * @param set the second bit set * @throws NullPointerException if set is null * @since 1.2 */ public void andNot(BitSet bs) { int i = Math.min(bits.length, bs.bits.length); while (--i >= 0) bits[i] &= ~bs.bits[i]; } /** * Returns the number of bits set to true. * * @return the number of true bits * @since 1.4 */ public int cardinality() { int card = 0; for (int i = bits.length - 1; i >= 0; i--) { long a = bits[i]; // Take care of common cases. if (a == 0) continue; if (a == -1) { card += 64; continue; } // Successively collapse alternating bit groups into a sum. a = ((a >> 1) & 0x5555555555555555L) + (a & 0x5555555555555555L); a = ((a >> 2) & 0x3333333333333333L) + (a & 0x3333333333333333L); int b = (int) ((a >>> 32) + a); b = ((b >> 4) & 0x0f0f0f0f) + (b & 0x0f0f0f0f); b = ((b >> 8) & 0x00ff00ff) + (b & 0x00ff00ff); card += ((b >> 16) & 0x0000ffff) + (b & 0x0000ffff); } return card; } /** * Sets all bits in the set to false. * * @since 1.4 */ public void clear() { Arrays.fill(bits, 0); } /** * Removes the integer <code>bitIndex</code> from this set. That is * the corresponding bit is cleared. If the index is not in the set, * this method does nothing. * * @param bitIndex a non-negative integer * @throws IndexOutOfBoundsException if bitIndex < 0 */ public void clear(int pos) { int offset = pos >> 6; ensure(offset); // ArrayIndexOutOfBoundsException subclasses IndexOutOfBoundsException, // so we'll just let that be our exception. bits[offset] &= ~(1L << pos); } /** * Sets the bits between from (inclusive) and to (exclusive) to false. * * @param from the start range (inclusive) * @param to the end range (exclusive) * @throws IndexOutOfBoundsException if from < 0 || from > to * @since 1.4 */ public void clear(int from, int to) { if (from < 0 || from > to) throw new IndexOutOfBoundsException(); if (from == to) return; int lo_offset = from >>> 6; int hi_offset = to >>> 6; ensure(hi_offset); if (lo_offset == hi_offset) { bits[hi_offset] &= ((1L << from) - 1) | (-1L << to); return; } bits[lo_offset] &= (1L << from) - 1; bits[hi_offset] &= -1L << to; for (int i = lo_offset + 1; i < hi_offset; i++) bits[i] = 0; } /** * Create a clone of this bit set, that is an instance of the same * class and contains the same elements. But it doesn't change when * this bit set changes. * * @return the clone of this object. */ public Object clone() { try { BitSet bs = (BitSet) super.clone(); bs.bits = (long[]) bits.clone(); return bs; } catch (CloneNotSupportedException e) { // Impossible to get here. return null; } } /** * Returns true if the <code>obj</code> is a bit set that contains * exactly the same elements as this bit set, otherwise false. * * @param obj the object to compare to * @return true if obj equals this bit set */ public boolean equals(Object obj) { if (!(obj instanceof BitSet)) return false; BitSet bs = (BitSet) obj; int max = Math.min(bits.length, bs.bits.length); int i; for (i = 0; i < max; ++i) if (bits[i] != bs.bits[i]) return false; // If one is larger, check to make sure all extra bits are 0. for (int j = i; j < bits.length; ++j) if (bits[j] != 0) return false; for (int j = i; j < bs.bits.length; ++j) if (bs.bits[j] != 0) return false; return true; } /** * Sets the bit at the index to the opposite value. * * @param index the index of the bit * @throws IndexOutOfBoundsException if index is negative * @since 1.4 */ public void flip(int index) { int offset = index >> 6; ensure(offset); // ArrayIndexOutOfBoundsException subclasses IndexOutOfBoundsException, // so we'll just let that be our exception. bits[offset] ^= 1L << index; } /** * Sets a range of bits to the opposite value. * * @param from the low index (inclusive) * @param to the high index (exclusive) * @throws IndexOutOfBoundsException if from > to || from < 0 * @since 1.4 */ public void flip(int from, int to) { if (from < 0 || from > to) throw new IndexOutOfBoundsException(); if (from == to) return; int lo_offset = from >>> 6; int hi_offset = to >>> 6; ensure(hi_offset); if (lo_offset == hi_offset) { bits[hi_offset] ^= (-1L << from) & ((1L << to) - 1); return; } bits[lo_offset] ^= -1L << from; bits[hi_offset] ^= (1L << to) - 1; for (int i = lo_offset + 1; i < hi_offset; i++) bits[i] ^= -1; } /** * Returns true if the integer <code>bitIndex</code> is in this bit * set, otherwise false. * * @param pos a non-negative integer * @return the value of the bit at the specified index * @throws IndexOutOfBoundsException if the index is negative */ public boolean get(int pos) { int offset = pos >> 6; if (offset >= bits.length) return false; // ArrayIndexOutOfBoundsException subclasses IndexOutOfBoundsException, // so we'll just let that be our exception. return (bits[offset] & (1L << pos)) != 0; } /** * Returns a new <code>BitSet</code> composed of a range of bits from * this one. * * @param from the low index (inclusive) * @param to the high index (exclusive) * @throws IndexOutOfBoundsException if from > to || from < 0 * @since 1.4 */ public BitSet get(int from, int to) { if (from < 0 || from > to) throw new IndexOutOfBoundsException(); BitSet bs = new BitSet(to - from); int lo_offset = from >>> 6; if (lo_offset >= bits.length) return bs; int lo_bit = from & LONG_MASK; int hi_offset = to >>> 6; if (lo_bit == 0) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -