为什么要将HashSet<>(0)初始化为零?

时间:2013-08-06 09:32:45

标签: java constructor initialization hashset zero

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

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

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

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

为什么 ? API告诉我这是初始容量,但将其置于零的优势是什么?这是建议吗?

5 个答案:

答案 0 :(得分:21)

default initial capacity is 16,所以通过传入0可以节省几个字节的内存,如果你最终没有在集合中放任何东西。

除此之外没有真正的优势;当你传递0时,创建的集合的容量为1,一旦你添加了东西,就必须调整它的大小。

答案 1 :(得分:6)

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

答案 2 :(得分:5)

这会将其设置为最小值。

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

这不是一个优化,因为只要添加一个条目,加载因子为0.7就会使容量为2,在过程中重新创建Map.Entry[]

答案 3 :(得分:3)

If you see docs

有一些线索。

  

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

答案 4 :(得分:0)

HashMap的初始加载因子是16.当HashMap保存12个记录的数据时,它是其初始大小的75%。然后HashMap增加它的大小。

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