java.util.BitSet

我们已经了解了BitMap,在Java中已经提供了BitMap的实现,即java.util.BitSet类。

BitSet内部维护了一个long型的数组,long的大小是8  Byte,即 64 位,所以每个元素可以存储64个数字:

    /**
     * The internal field corresponding to the serialField "bits".
     */
    private long[] words;

存储元素:

    /**
     * Sets the bit at the specified index to {@code true}.
     *
     * @param  bitIndex a bit index
     * @throws IndexOutOfBoundsException if the specified index is negative
     * @since  JDK1.0
     */
    public void set(int bitIndex) {
        if (bitIndex < 0)
            throw new IndexOutOfBoundsException("bitIndex < 0: " + bitIndex);

        int wordIndex = wordIndex(bitIndex);
        expandTo(wordIndex);

        words[wordIndex] |= (1L << bitIndex); // Restores invariants

        checkInvariants();
    }

    /**
     * Given a bit index, return word index containing it.
     */
    private static int wordIndex(int bitIndex) {
        return bitIndex >> ADDRESS_BITS_PER_WORD;
    }

    /**
     * Ensures that the BitSet can accommodate a given wordIndex,
     * temporarily violating the invariants.  The caller must
     * restore the invariants before returning to the user,
     * possibly using recalculateWordsInUse().
     * @param wordIndex the index to be accommodated.
     */
    private void expandTo(int wordIndex) {
        int wordsRequired = wordIndex+1;
        if (wordsInUse < wordsRequired) {
            ensureCapacity(wordsRequired);
            wordsInUse = wordsRequired;
        }
    }

    /**
     * Every public method must preserve these invariants.
     */
    private void checkInvariants() {
        assert(wordsInUse == 0 || words[wordsInUse - 1] != 0);
        assert(wordsInUse >= 0 && wordsInUse <= words.length);
        assert(wordsInUse == words.length || words[wordsInUse] == 0);
    }

假设要存储数据3,首先通过wordIndex(bitIndex);计算出3对应的数组的位置,这里是右移6位实现(相当于3 / 64),结果是0,即3对应的位置在数组的第0个元素。接下来expandTo(wordIndex);方法确保 BitSet 可以容纳给定的 wordIndex,即如果超过容量,会对数组进行扩容。然后 words[wordIndex] |= (1L << bitIndex);将数字3对应bit位置为1(将1左移3位,然后与原值进行 | 运算)。最后checkInvariants();进行一些校验。假设BitSet以前没有存储任何数据,经过以上操作后,数组第0位的数据应该是8(1000)。

接下,假设要存储数据1,还是按照以上步骤,最后的结果是数组的第0位对应的数据是10(1010)。

什么意思呢?因为是按位存储数据,从右往左,1010的第0位代表数字0,此时是0,表示0不存在;第1位表示数字1,此时是1,表示1存在。

获取元素:

    /**
     * Returns the value of the bit with the specified index. The value
     * is {@code true} if the bit with the index {@code bitIndex}
     * is currently set in this {@code BitSet}; otherwise, the result
     * is {@code false}.
     *
     * @param  bitIndex   the bit index
     * @return the value of the bit with the specified index
     * @throws IndexOutOfBoundsException if the specified index is negative
     */
    public boolean get(int bitIndex) {
        if (bitIndex < 0)
            throw new IndexOutOfBoundsException("bitIndex < 0: " + bitIndex);

        checkInvariants();

        int wordIndex = wordIndex(bitIndex);
        return (wordIndex < wordsInUse)
            && ((words[wordIndex] & (1L << bitIndex)) != 0);
    }

首先wordIndex(bitIndex);获取bitIndex在数组中的下标,然后再判断bitIndex位对应位是否为1,是则返回true,表示元素存在,否则返回false,表示元素不存在。

总体来说,BitSet是BitMap的Java实现,其内部使用long[]存储元素,每个数组元素可以表示64个数字,数组元素的每一位对应一个数字,为0表示对应的数字不存在,为1表示对应的数字存在。

可以使用BitSet来进行排序、去重等。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值