2017-07-06 62 views
1

这是我的代码。我想要做的是使用BitSet处理来自我的ByteBuffer的字节。字节缓冲区从DynamoDB加载(随着DynamoDBMapper)为什么我的BitSet的大小为0?

ByteBuffer buffer = ....... 
    System.out.println("Array length is " + buffer.array().length); 
    BitSet bitSet = BitSet.valueOf(buffer.array()); 
    System.out.println("Bit set size is " + bitSet.size()); 

当我执行我的代码,我看到我的ByteBuffer的阵列长度为6100,这意味着它是由6100个字节支持。这些字节全部为0。但是我也看到位集大小是0.这对我来说没有意义(大小应该是6100 * 8)。

我查看了valueOf的文档以及“返回包含给定字节数组中所有位的新位集”的说明。对于我想要做的事情是有意义的。

我犯的第一个错误是使用位集的长度。长度为0,这是合理的,因为所有的位都是0。大小函数“返回此BitSet实际使用的空间位数,以表示位值。”尺寸函数不应该在这里返回6100 * 8吗?

更新:我只是试图把全1到字节缓冲区,现在我得到的7000数组长度和7232

回答

2

BitSet位集合的大小没有实现直接保持同等大小的缓冲区的数组传入以初始化它。相反,它在内部维护足够的缓冲区空间来跟踪打开的最高位。对于任何比这更高的位,BitSet#get等方法假定如果传递比当前缓冲区空间中维持的位索引更高的位,则该位必须关闭。

JavaDocs中有几个关于“大小”或“长度”的相关语句。来自类级别的JavaDocs BitSet

每个位集都有一个当前大小,它是该位集当前正在使用的空间位数。请注意,大小与位集的实现有关,所以它可能随实现而改变。位集的长度与位集的逻辑长度有关,并且与实现无关地定义。

BitSet#length

返回此BitSet的“逻辑大小”:在BitSet中加一的最高设置位的索引。如果BitSet不包含设定位,则返回零。

(另请注意,在关闭所有位的极端情况下,它返回零。)

BitSet#size

通过此BitSet返回实际使用空间的位数代表比特值。该集合中的最大元素是大小 - 第一个元素。

如果你有兴趣在更深的下潜,我也建议看OpenJDK的代码BitSet

http://hg.openjdk.java.net/jdk8u/jdk8u/jdk/file/3462d04401ba/src/share/classes/java/util/BitSet.java

有趣的部分是set,可动态扩展的需要设置缓冲空间如果所请求的位索引超出当前缓冲区容量(words成员变量),则返回,该代码返回false

+0

那么你会推荐处理bytebuffer并使用位操作呢? – committedandroider

+1

@committedandroider,我认为这取决于你的具体需求。您当然可以编写自己的逻辑来直接在“ByteBuffer”内计算正确的偏移量,并测试某个位是关闭还是打开。但是,如果您需要将这些数据长时间保存在内存中,并且数据集很大,那么'BitSet'的更紧凑表示可能有助于减少应用程序的内存占用量。 –

+0

“相反,它在内部维护着足够的缓冲空间来跟踪最高位”。我读过这个,但有6100字节(全0),它怎么可能有0的大小? – committedandroider

相关问题