我喜欢使用 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);
}
当 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的初始负载因子为16。当HashMap保存12条记录的数据时,这相当于其初始大小的75%。此时HashMap会增加其大小。
因此,在构造函数中将初始容量设置为0即可。