从集合构建HashSet
和LinkedHashSet
时,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);
}
我确信这有一个完全正确的理由,但我没有看到它。
答案 0 :(得分:4)
根据您向我们展示的代码,以下是HashSet
和LinkedHashSet
的规范:
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
更大的初始容量,我们可以避免在较长时间内进行昂贵的容量扩展。