让bs1
成为Java中的BitSet
第一位设置为bs1.set(0)
,其size
和length
分别为64和1。
第65位设置为bs1.set(64)
,其size
和length
分别为128和65.
现在,如果我清除它的第65位bs1.clear(64)
,它的length
会回到1,但它的大小会发生什么变化?
如果我克隆bitset会发生什么?是新的尺寸默认值?
答案 0 :(得分:0)
更少的单词和更多的代码,这里是我认为回答问题的实验:
import java.util.BitSet;
public class BitSetExperiment {
public static void main(String[] args) {
BitSet bs0=new BitSet();
BitSet bs1;
System.out.println("created:\tLength,Size bs0: "+bs0.length()+" , "+bs0.size());
bs0.set(15);
System.out.println("set(15):\tLength,Size bs0: "+bs0.length()+" , "+bs0.size());
bs0.set(63);
System.out.println("set(63):\tLength,Size bs0: "+bs0.length()+" , "+bs0.size());
bs0.set(86);
System.out.println("set(86):\tLength,Size bs0: "+bs0.length()+" , "+bs0.size());
bs0.clear(86);
System.out.println("clear(86):\tLength,Size bs0: "+bs0.length()+" , "+bs0.size());
bs0.clear(63);
System.out.println("clear(63):\tLength,Size bs0: "+bs0.length()+" , "+bs0.size());
System.out.println("Cloning to bs1...\n");
bs1=(BitSet)bs0.clone();
System.out.println("Length,Size bs0: "+bs0.length()+" , "+bs0.size());
System.out.println("Length,Size bs1: "+bs1.length()+" , "+bs1.size());
}
}
输出:
created: Length,Size bs0: 0 , 64
set(15): Length,Size bs0: 16 , 64
set(63): Length,Size bs0: 64 , 64
set(86): Length,Size bs0: 87 , 128
clear(86): Length,Size bs0: 64 , 128
clear(63): Length,Size bs0: 16 , 128
Cloning to bs1...
Length,Size bs0: 16 , 64
Length,Size bs1: 16 , 64
看看输出,我发现了两件事:
答案 1 :(得分:0)
答案可能取决于实现方式。通过阅读Java 11源代码可以收集以下信息。
指定用于收缩BitSet
的唯一API方法是trimToSize()
。
大多数(变异)API方法 可能会增加其大小,但永远不会减小它。
例外情况是clone()
以及用于Java对象序列化的{private} readObject
和writeObject
方法。这些方法的行为取决于一个称为sizeIsSticky
的私有字段,而该私有字段又取决于该对象的先前历史记录。
如果创建的BitSet
具有容量,则它的大小为粘性。除非BitSet
超出其容量,否则大小将保持不变。
克隆具有粘性大小的BitSet
时,克隆对象具有相同的大小,并且大小也具有粘性。
克隆具有非粘性大小的BitSet
时,将首先修剪对象,然后创建克隆。克隆的大小不会发粘。
序列化具有粘性大小的BitSet
时,序列化的表格会保留大小。
以非粘性大小序列化BitSet
时,BitSet
会在序列化之前被修剪。
从序列号中反序列化BitSet
时,其大小与序列号相同,并且粘滞性是通过启发式设置的。
当大小为非粘性时,在clone()
和writeObject
中进行的修剪有点令人惊讶,但这就是(Java 11)代码所做的。通过sizeIsSticky
字段上的注释来部分解释此行为。
/**
* Whether the size of "words" is user-specified. If so, we assume
* the user knows what he's doing and try harder to preserve it.
*/
private transient boolean sizeIsSticky = false;