不同的默认'initialCapacity'HashSet和LinkedHashSet

时间:2017-01-17 08:27:51

标签: java

从集合构建HashSetLinkedHashSet时,initialCapacity在默认实现中设置为不同的值。

HashSet的:

public HashSet(Collection<? extends E> c) {
    map = new HashMap<>(Math.max((int) (c.size()/.75f) + 1, 16));
    addAll(c);
}

LinkedHashSet:

public LinkedHashSet(Collection<? extends E> c) {
    super(Math.max(2*c.size(), 11), .75f, true);
    addAll(c);
}

我确信这有一个完全正确的理由,但我没有看到它。

1 个答案:

答案 0 :(得分:4)

根据您向我们展示的代码,以下是HashSetLinkedHashSet的规范:

data structure | initial capacity      | load factor
HashSet        | max(1.333 * size, 16) | 0.75
LinkedHashSet  | max(2 * size, 11)     | 0.75

在我的脑海中,重新传输LinkedHashSet可能比普通的HashSet成本更高,因为前者有一个贯穿它的链表,也可能需要重构/重新计算。通过提高初始容量,我们可以避免超过一些典型用例的初始容量。

当Java中超出哈希表数据结构的初始容量时,需要进行扩展。除其他事项外,这需要将表中的每个条目重新分配到新存储桶。在LinkedHashSet和普通HashSet中,执行此操作的成本应大致相同。 但是LinkedHashSet在扩展容量时还有一个额外的要求,因为它维护了一个贯穿条目的链表。此列表可能还需要在此过程中进行重构。因此,我认为在LinkedHashSet中扩展容量的成本要高于普通HashSet。通过赋予LinkedHashSet更大的初始容量,我们可以避免在较长时间内进行昂贵的容量扩展。

LinkedHashSet Javadoc

相关问题