Java 位集';s size()方法?

Java 位集';s size()方法?,java,bitset,Java,Bitset,类上的方法是否有用例 我的意思是-JavaDoc明确表示它依赖于实现,它返回内部long[]存储的大小(以位为单位)。从上面所说的,我们可以得出结论,您将无法设置比size()更高索引的位,但事实并非如此,位集可以自动增长: BitSet myBitSet = new BitSet(); System.out.println(myBitSet.size()); // prints "64" myBitSet.set(768); System.out.println(myBitSet.siz

类上的方法是否有用例

我的意思是-JavaDoc明确表示它依赖于实现,它返回内部
long[]
存储的大小(以位为单位)。从上面所说的,我们可以得出结论,您将无法设置比
size()
更高索引的位,但事实并非如此,
位集可以自动增长:

BitSet myBitSet = new BitSet();
System.out.println(myBitSet.size());    // prints "64"
myBitSet.set(768);
System.out.println(myBitSet.size());    // prints "832"
在我一生中遇到的每一次
位集
中,我总是想使用它,因为它返回
位集
的逻辑大小:

BitSet myBitSet = new BitSet();
System.out.println(myBitSet.length());    // prints "0"
myBitSet.set(768);
System.out.println(myBitSet.length());    // prints "769"
尽管我在过去6年中一直在编写Java,但这两种方法对我来说总是非常混乱。我经常把它们混在一起,顺便用错了一个,因为在我的头脑中,我认为
位集
是一个聪明的
,我会使用
size()

这就像
ArrayList
具有
length()
返回元素数和
size()
返回基础数组的大小一样

现在,我缺少的
size()
方法是否有任何用例?它在任何方面有用吗?有人用过吗?这对一些手工的小游戏或者类似的东西来说可能很重要吗


编辑(经过进一步研究)


我意识到
BitSet
是在Java1.0中引入的,而包含我们使用的大多数类的集合框架是在Java1.2中引入的。所以在我看来,
size()
基本上是因为遗留的原因而保留下来的,它没有实际的用途。新集合类没有这样的方法,而一些旧集合类(例如)有这样的方法。

0和1的数量必须是64的倍数。可以使用基数()表示1的数目

我意识到位集是在Java1.0中引入的,而包含我们使用的大多数类的集合框架是在Java1.2中引入的

所以在我看来,size()基本上是因为遗留的原因而保留的,它没有真正的用途

是的,差不多

另一种“size”方法是
length()
,它提供了设置位的最大索引。从逻辑角度来看,
length()
size()
更有用。。。但是
length()
仅在Java1.2中引入

我能想到的唯一一个(假设的)用例是当以下情况时,
size()
可能比
length()
更好:

  • 您正试图为集合中的位的迭代建立一个“围栏”,并且
  • 很可能在结束之前就停止迭代,并且
  • 不要紧的是你比设定的最后一位稍微多了一点
在这种情况下,
size()。(看看源代码…)但这是相当边缘化的

(我猜,类似的另一个用例是当您创建一个新的
位集
并基于现有
位集
大小()预先分配它时。同样,差异是微不足道的。)


但关于兼容性,你是对的。很明显,他们既不能摆脱
size()
,也不能在不造成兼容性问题的情况下更改其语义。所以他们大概决定不去管它了。(事实上,他们甚至不认为有必要反对它。在API中有一个不是特别有用的方法的“危害”是最小的。)

如果
size
方法不是由Java创建者设计为公共的,它无疑仍然会作为私有方法/字段存在。因此,我们正在讨论它的可访问性和命名

Java1.0从C/C++中获得了很多灵感,不仅仅是过程语法。在C++标准库中,也存在代码< >代码集> /COD> <代码>长度<代码>和<代码>大小< /代码>。它们分别称为
大小
容量
。在C++中很少有任何使用“代码>容量”/代码的理由,在垃圾收集语言(如java)中使用更少,但是使用该方法仍然是有用的。我将用Java术语解释

告诉我,执行
位集
操作(如
)所需的最大机器指令数是多少?有人想回答“只有一小部分”,但这只有在特定操作不会导致整个底层阵列的重新分配时才是正确的。从理论上讲,重新分配将常数时间算法转变为线性时间算法

这种理论上的差异有多大的实际影响?很少地阵列通常不会经常增长。但是,当您的算法在逐渐增长的具有近似已知最终大小的
位集
上运行时,如果您已将最终大小传递给
位集
的构造函数,则可以节省重新分配的时间。在一些非常特殊的情况下,这甚至可能有明显的效果,在大多数情况下,它不会造成伤害

  • set
    则具有恒定的时间复杂度-调用它永远不会阻塞应用程序太长时间
  • 如果只有一个非常大的
    位集
    实例(按设计)耗尽了您所有的可用内存,那么稍后可能会开始明显的交换,这取决于JVM实现增长操作的方式(有无额外副本)

现在,假设您对许多位集进行操作,所有这些位集都已分配了目标大小。您正在从另一个位集实例构建一个位集实例,并且希望新的位集与旧的位集实例共享目标大小,因为您知道您将同时使用它们。将
size
方法公开使其更容易干净地实现

我认为它可能有用的一个主要原因是当我们需要扩展时
protected Set bitset;
public int length() {
  int returnValue = 0;
  // Make sure set not empty
  // Get maximum value +1
  if (bitset.size() > 0) {
     Integer max = (Integer)Collections.max(bitset);
     returnValue = max.intValue()+1;
  }
  return returnValue;
 }