BitSet 与整数/长整数
Posted
技术标签:
【中文标题】BitSet 与整数/长整数【英文标题】:BitSet to and from integer/long 【发布时间】:2011-01-29 05:42:33 【问题描述】:如果我想对一个整数执行位操作,如何将它加载到java.util.BitSet
中?如何将其转换回 int 或 long?我不太关心BitSet
的大小——它总是32 或64 位长。我只想使用set()
、clear()
、nextSetBit()
和nextClearBit()
方法而不是按位运算符,但我找不到一种简单的方法来初始化具有数字类型的位集。
【问题讨论】:
就个人而言,我会说原始位操作是这里的方法。它真的没有那么复杂,正如你所说,我没有看到将 int 或 long 放入 BitSet 的简单方法。 【参考方案1】:要以 '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::valueOf
和BitSet::toLongArray
当然更容易。
【讨论】:
【参考方案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】:几乎直接来自 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 << i
,以防止溢出,像value |= 1L << i
这样的 OR 就足够了。【参考方案4】:
Java 7 有 @987654321@
和 @987654322@
如果您坚持使用 Java 6 或更早版本,如果它不太可能成为性能瓶颈,则可以使用 BigInteger
- 它具有 getLowestSetBit
、setBit
和 clearBit
方法(最后两个将创建一个新的BigInteger
,而不是就地修改。)
【讨论】:
【参考方案5】:以下代码从 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 -> long
。【参考方案6】:
public void set(int bit)
方法不是您要找的吗?
【讨论】:
用您提供的索引设置一个位。我想设置整数中设置的每一位。以上是关于BitSet 与整数/长整数的主要内容,如果未能解决你的问题,请参考以下文章