size()
类上的java.util.BitSet
方法是否有用例?
我的意思是 - JavaDoc明确表示它依赖于实现,它以位为单位返回内部long[]
存储的大小。根据它的说法,可以得出结论,你将无法设置比size()
更高的索引,但事实并非如此,BitSet
可以自动增长:
BitSet myBitSet = new BitSet();
System.out.println(myBitSet.size()); // prints "64"
myBitSet.set(768);
System.out.println(myBitSet.size()); // prints "832"
在我生命中遇到的BitSet
的每一次遭遇中,我总是想使用length()
,因为那会返回BitSet
的逻辑大小:
BitSet myBitSet = new BitSet();
System.out.println(myBitSet.length()); // prints "0"
myBitSet.set(768);
System.out.println(myBitSet.length()); // prints "769"
尽管我在过去的6年里一直在编写Java,但这两种方法对我来说总是很困惑。我经常将它们混合在一起并偶然使用错误的一个,因为在我的脑海中,我认为BitSet
是一个聪明的Set<boolean>
,我会使用size()
。
就好像ArrayList
让length()
返回元素数量,size()
返回基础数组的大小。
现在,我缺少size()
方法的用例吗?它有用吗?有没有人用它做任何事情?对于某些手动钻头或类似物品来说,它是否很重要?
编辑(经过更多研究后)
我意识到在Java 1.0中引入了BitSet
,而我们使用的大多数类的Collections框架都是在Java 1.2中引入的。所以基本上在我看来size()
由于遗留原因而被保留,并且没有真正的用途。新的Collection类没有这样的方法,而有些旧的(例如Vector
)也没有。
答案 0 :(得分:4)
我意识到BitSet是在Java 1.0中引入的,而我们使用的大多数类的Collections框架是在Java 1.2中引入的。
正确。
所以基本上在我看来,由于遗留原因而保留size()并且没有真正的用途。
是的,差不多。
另一个“size”方法是length()
,它为您提供设置位的最大索引。从逻辑角度来看,length()
比size()
更有用......但length()
仅在Java 1.2中引入。
唯一(假设的)用例,我可以想到size()
可能比length()
更好的地方是:
在这种情况下,size()
可能比length()
好,因为这是一个更便宜的电话。 (看一下源代码......)但这很微不足道。
(我想,沿着类似行的另一个用例是当您创建新的BitSet
并根据现有size()
的{{1}}预先分配它时。是边缘的。)
但你对兼容性是正确的。很明显,他们不能摆脱BitSet
或改变其语义而不会产生兼容性问题。所以他们可能决定不管它。 (实际上,他们甚至没有看到需要弃用它。在API中使用非特别有用的方法的“危害”很小。)
答案 1 :(得分:1)
如果size
方法不是由Java创建者设计为公共的,那么它无疑仍然作为私有方法/字段存在。所以我们正在讨论它的可访问性和命名。
Java 1.0从C / C ++中获取了很多灵感,而不仅仅是程序语法。在C ++标准库中,BitSet
的{{1}}和length
的对应项也存在。它们分别称为size
和size
。很少有任何硬性理由在C ++中使用capacity
,在Java等垃圾收集语言中使用{1}}更少,但是可访问方法仍然有用。我将用Java术语解释。
告诉我,执行capacity
操作(例如BitSet
)所需的最大机器指令数是多少?人们想回答“只是少数”,但只有当特定操作不会导致整个底层数组的重新分配时才会这样。从理论上讲,重新分配将恒定时间算法转换为线性时间算法。
这种理论差异是否具有很大的实际影响?很少。阵列通常不会经常增长。但是,只要您的算法在逐渐增长的set
上运行且具有近似已知的最终大小,如果您已将最终大小传递给BitSet
的构造函数,则将节省重新分配。在一些非常特殊的情况下,这甚至可能会产生明显的影响,在大多数情况下它并没有受到伤害。
BitSet
然后具有恒定的时间复杂度 - 称它不能长时间阻止应用程序。set
实例耗尽了所有可用内存(按设计),则交换可能会在以后明显地取决于JVM如何实现增长操作(使用或不使用额外的副本)。 / LI>
现在假设您在许多BitSets上运行,所有BitSet都已分配了目标大小。您正在构建另一个BitSet实例,并且您希望新的实例共享旧的目标大小,因为您知道将并排使用它们。公共BitSet
方法使得更容易实现干净。
答案 2 :(得分:0)
0和1的数量必须是64的倍数。你可以使用基数()作为1的数量。
答案 3 :(得分:0)
我认为它可能有用的一个主要原因是我们需要扩展BitSet类并覆盖length方法。在这种情况下,大小是有用的。下面是长度如何通过依赖大小方法返回值。
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;
}