我喜欢HashSet<>()并在使用默认构造函数初始化它时急切地使用它:
Set<Users> users = new HashSet<>();
现在,我的自动 bean 创建器(JBoss 工具)将其初始化为:
Set<Users> users = new HashSet<>(0);
为什么是零?API 告诉我这是初始容量,但将其设为零有什么好处?这是建议吗?
我喜欢HashSet<>()并在使用默认构造函数初始化它时急切地使用它:
Set<Users> users = new HashSet<>();
现在,我的自动 bean 创建器(JBoss 工具)将其初始化为:
Set<Users> users = new HashSet<>(0);
为什么是零?API 告诉我这是初始容量,但将其设为零有什么好处?这是建议吗?
默认的初始容量是 16,所以如果你最终没有在集合中放入任何东西,通过传入 0 可以节省几个字节的内存。
除此之外没有真正的优势;当您传递 0 时,将创建容量为 1 的集合,并且一旦添加某些内容,就必须调整其大小。
HashSet 使用 HashMap 存储数据:
public HashSet(int initialCapacity) {
map = new HashMap<E,Object>(initialCapacity);
}
而初始容量 = 0,
public HashMap(int initialCapacity, float loadFactor) {
....
// Find a power of 2 >= initialCapacity
int capacity = 1;
while (capacity < initialCapacity)
capacity <<= 1;
}
HashMap 容量为1
.
但如果使用默认构造函数:
public HashMap() {
this.loadFactor = DEFAULT_LOAD_FACTOR;
threshold = (int)(DEFAULT_INITIAL_CAPACITY * DEFAULT_LOAD_FACTOR);
table = new Entry[DEFAULT_INITIAL_CAPACITY];
init();
}
HashMap 容量为16*0.75
.
所以,new HashSet<>(0)
在初始化时保存一些内存。
这会将其设置为最小值。
这很可能用于关闭代码分析器,如果您没有为集合设置初始容量,它们可能会抱怨。通过将其设置为 0,您只需将其设置为最小值。
这并不是什么优化,因为一旦添加条目,0.7 的负载因子将使容量为 2,Map.Entry[]
在此过程中重新创建。
有一些线索。
迭代这个集合需要的时间与 HashSet 实例的大小(元素的数量)加上支持 HashMap 实例的“容量”(桶的数量)的总和成正比。因此,如果迭代性能很重要,则不要将初始容量设置得太高(或负载因子太低),这一点非常重要。
HashMap的Initial Load factor是16。当HashMap保存12条Record的数据时,是其初始大小的75%。然后 HashMap 增加它的大小。
所以这里我们只是将初始容量设置为 0,方法是在 Constructor 中传递它。