21

我喜欢HashSet<>()并在使用默认构造函数初始化它时急切地使用它:

Set<Users> users = new HashSet<>();

现在,我的自动 bean 创建器(JBoss 工具)将其初始化为:

Set<Users> users = new HashSet<>(0);

为什么是?API 告诉我这是初始容量,但将其设为零有什么好处?这是建议吗?

4

5 回答 5

22

默认的初始容量是 16,所以如果你最终没有在集合中放入任何东西,通过传入 0 可以节省几个字节的内存。

除此之外没有真正的优势;当您传递 0 时,将创建容量为 1 的集合,并且一旦添加某些内容,就必须调整其大小。

于 2013-08-06T09:37:22.553 回答
6

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)在初始化时保存一些内存。

于 2013-08-06T09:40:13.067 回答
5

这会将其设置为最小值。

这很可能用于关闭代码分析器,如果您没有为集合设置初始容量,它们可能会抱怨。通过将其设置为 0,您只需将其设置为最小值。

这并不是什么优化,因为一旦添加条目,0.7 的负载因子将使容量为 2,Map.Entry[]在此过程中重新创建。

于 2013-08-06T09:44:36.857 回答
3

如果您看到文档

有一些线索。

迭代这个集合需要的时间与 HashSet 实例的大小(元素的数量)加上支持 HashMap 实例的“容量”(桶的数量)的总和成正比。因此,如果迭代性能很重要,则不要将初始容量设置得太高(或负载因子太低),这一点非常重要。

于 2013-08-06T09:37:05.287 回答
0

HashMap的Initial Load factor是16。当HashMap保存12条Record的数据时,是其初始大小的75%。然后 HashMap 增加它的大小。

所以这里我们只是将初始容量设置为 0,方法是在 Constructor 中传递它。

于 2017-03-11T01:19:59.467 回答