【问题标题】:BitSet to and from integer/longBitSet 与整数/长整数
【发布时间】:2011-01-29 05:42:33
【问题描述】:

如果我想对一个整数执行位操作,如何将它加载到java.util.BitSet 中?如何将其转换回 int 或 long?我不太关心BitSet 的大小——它总是32 或64 位长。我只想使用set()clear()nextSetBit()nextClearBit() 方法而不是按位运算符,但我找不到一种简单的方法来初始化具有数字类型的位集。

【问题讨论】:

  • 就个人而言,我会说原始位操作是这里的方法。它真的没有那么复杂,正如你所说,我没有看到将 int 或 long 放入 BitSet 的简单方法。

标签: java bit-manipulation bitset


【解决方案1】:

以下代码从 long 值创建位集,反之亦然:

public class Bits {

  public static BitSet convert(long value) {
    BitSet bits = new BitSet();
    int index = 0;
    while (value != 0L) {
      if (value % 2L != 0) {
        bits.set(index);
      }
      ++index;
      value = value >>> 1;
    }
    return bits;
  }

  public static long convert(BitSet bits) {
    long value = 0L;
    for (int i = 0; i < bits.length(); ++i) {
      value += bits.get(i) ? (1L << i) : 0L;
    }
    return value;
  }
}

已编辑:现在两个方向,@leftbrain:当然,你是对的

【讨论】:

  • 仅供参考,这是按照 little-endian 顺序创建 bitset
  • 你真的应该使用BitSet.nextSetBit() 代替BitSet -&gt; long
【解决方案2】:

添加到 finnw 答案:还有 BitSet.valueOf(long[])BitSet.toLongArray()。所以:

int n = 12345;
BitSet bs = BitSet.valueOf(new long[]{n});
long l = bs.toLongArray()[0];

【讨论】:

  • 如果bitset没有“1”,bs.toLongArray()[0]会抛出ArrayIndexOutOfBoundsException异常!
【解决方案3】:

Java 7 有 @987654321@@987654322@

如果您坚持使用 Java 6 或更早版本,如果它不太可能成为性能瓶颈,则可以使用 BigInteger - 它具有 getLowestSetBitsetBitclearBit 方法(最后两个将创建一个新的BigInteger,而不是就地修改。)

【讨论】:

    【解决方案4】:

    要以 'streamy' 的方式从 small BitSet 获取 long

    long l = bitSet.stream()
            .takeWhile(i -> i < Long.SIZE)
            .mapToLong(i -> 1L << i)
            .reduce(0, (a, b) -> a | b);
    

    反之亦然:

    BitSet bitSet = IntStream.range(0, Long.SIZE - 1)
            .filter(i -> 0 != (l & 1L << i))
            .collect(BitSet::new, BitSet::set, BitSet::or);
    

    注意:使用BitSet::valueOfBitSet::toLongArray 当然更容易。

    【讨论】:

      【解决方案5】:

      几乎直接来自 nextSetBit 的文档

      value=0;
      for (int i = bs.nextSetBit(0); i >= 0; i = bs.nextSetBit(i+1)) {
       value += (1 << i)
       }
      

      【讨论】:

      • 这对于大于 32 或 64 位的 BitSet 将失败,在这种情况下,您需要在输出处处理 int[]long[]。但是 OP 明确地不在乎,所以很公平。只是一些小故障:如果是 long 你应该1L &lt;&lt; i,以防止溢出,像value |= 1L &lt;&lt; i 这样的 OR 就足够了。
      【解决方案6】:

      public void set(int bit) 方法不是您要找的吗?

      【讨论】:

      • 用您提供的索引设置一个位。我想设置整数中设置的每一位。
      猜你喜欢
      • 1970-01-01
      • 2014-12-30
      • 1970-01-01
      • 1970-01-01
      • 2012-08-26
      • 2015-04-21
      • 2011-10-05
      • 1970-01-01
      相关资源
      最近更新 更多