0

此处的 Java 参考表明布尔类型虽然用“位”信息表示,但没有精确定义的大小。相比之下,其他类型似乎表明定义了大小。例如,一个int是 32 位,故事结束。

当我们查看BitSet的规范时,我们可以看到它由布尔值组成。通过上面的参考,这似乎表明BitSet的“大小”是未定义的——毕竟它是由布尔值组成的。果然,文档指定:

请注意,大小与位集的实现有关,因此它可能会随着实现而改变。

所以我的问题是,为什么不使用另一种精确定义的数据类型来实现BitSet ?例如,如果我们使用一个字节,我们可以保证 8 位的大小,并且我们不会有大小可能不是我们想象的那样的模糊感觉。确实,大小必须能被 8 整除,但至少这种方式似乎更具大小确定性。

如果我们有一个绝对不能超过某个内存容量的系统,那么拥有一个在大小方面精确的BitSet实现似乎很有用。

4

5 回答 5

5

我认为您在概念上被方法签名使用布尔值这一事实所困扰。

考虑单个位的最简单方法是关闭/打开,因此布尔值 true/false 是对其进行建模的便捷方法。另一件事完全是BitSet内部存储,如果您查看源代码,它使用long数组并使用位掩码来旋转各个位。

因此,它的大小与BitSet使用的位数密切相关。

于 2012-04-12T14:23:45.460 回答
1

部分BitSet原因在于它的长度在概念上是无限的——我们可以用它来操作任意多个位。我们关心的不是内存消耗,而是语义,size只是内存消耗的一个指标。

于 2012-04-12T14:15:26.173 回答
1

ABitSet不一定由布尔值组成,但会将位转换为布尔值以便于使用(而不是必须检查 0 或 1)。

除此之外,实现很可能会使用某种数据类型,但取决于架构,可能会使用一堆 8 位、16 位、32 位或 64 位整数(或其他东西)来存储位。在大多数系统中,内存限制并不那么难,因此逻辑大小为 5 且实际大小为 1 或 8 个字节的位集并不那么重要。

诚然,您可以仅使用字节来实现位集,但可能有理由遵守平台的内存对齐(可能超过一个字节)。

于 2012-04-12T14:23:34.223 回答
1

你让它听起来像 BitField需要是一个实际的数组boolean,事实并非如此;例如,您可以在 JDK 的源代码中查找当前实现。这是一个片段:

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

因此,在这种情况下,使用了一个 s 数组,long并通过位掩码和移位访问这些位。

于 2012-04-12T14:24:00.267 回答
1

与大多数原语不同,Java 对象的字节大小没有很好地定义,并且依赖于实现,甚至可能由于 JIT 编译和 JVM 内部使用的不同技巧而在应用程序运行时发生变化。即使在 Sun JVM 版本之间(4 对 1 字节), a 的大小boolean也发生了变化,如果我没记错的话,甚至有一段时间单个boolean需要 4 个字节,而 N 的数组booleans需要大约 N*1 个字节(或者也许是byte类型?)。无论如何,变量的逻辑大小或其信息容量可能与JVM分配的物理内存完全不同。

BitSet仅在概念上由布尔值组成,实现不需要遵循逻辑布局。实际上,大多数实现将使用字节数组,BitSet并且每个值大约只使用一位(但为了允许它增长和一些额外的内务数据存在一些松弛)。

于 2012-04-12T14:26:02.433 回答