【问题标题】:Why is the default capacity of ArrayList 10?为什么ArrayList的默认容量是10?
【发布时间】:2012-06-03 10:12:27
【问题描述】:

看了ArrayList的java doc,发现ArrayList的初始容量是10。

 /**
 * Constructs an empty list with an initial capacity of ten.
 */
public ArrayList() {
this(10);
}

我认为如果它是 2 的任何幂都有意义,但为什么是 10?

我还检查了 HashMap 的初始容量,它是 16,这是有道理的。

/**
 * The default initial capacity - MUST be a power of two.
 */
static final int DEFAULT_INITIAL_CAPACITY = 16;

/**
 * Constructs an empty <tt>HashMap</tt> with the default initial capacity
 * (16) and the default load factor (0.75).
 */
public HashMap() {
    this.loadFactor = DEFAULT_LOAD_FACTOR;
    threshold = (int)(DEFAULT_INITIAL_CAPACITY * DEFAULT_LOAD_FACTOR);
    table = new Entry[DEFAULT_INITIAL_CAPACITY];
    init();
}

数字 10 背后有什么具体原因吗?

【问题讨论】:

  • >>> 如果它是 2 的任意数量的幂可能有意义 为什么?
  • 我认为这可以追溯到 cs 中的主要生命形式,它似乎有两个机械手,每个机械手都有 5 个数字。在计算的早期用于计数的那些。因此,他们更喜欢 10 的幂。
  • 10是Array List的初始容量而不是大小。初始大小始终为0。
  • @AbhisekBose :是的,你写的。我的错误。它的容量不是大小。我修改了问题。 :)
  • Java 1.7.0_40更新后,ArrayList初始容量为0(指向空数组)

标签: java collections arraylist


【解决方案1】:

ArrayList 是简单的增长数组。当尝试添加元素时,缓冲区大小超出了,它只是在增长。所以初始大小可以是任何正值。

1 太少了。即使有一些元素,我们也会有一些调整大小的操作。

100 将失去空间。

所以,10 是妥协。为什么是 10 而不是 12 或 8?第一个提示是,分析了典型用例,这是性能损失和空间损失之间的最佳匹配。然而,我认为,看到 Sun 的原始代码,它没有被分析得那么深入,它是一个任意的“不太小,也不太大”的数字。

【讨论】:

    【解决方案2】:

    对于列表,容量为 2 的幂没有任何优势。事实上,任何特定的启动能力都没有真正的优势。它必须足够大,以避免在小列表的常见情况下进行多次调整大小步骤,并且必须足够小,以免在相同情况下将内存浪费在未使用的容量上。选择 10 可能只是因为它在满足这些要求的正确范围内,并且因为它是“圆形的”。

    【讨论】:

    • 对于任何特定容量,即使它的幂为2,也可能没有真正的优势。但是,如果sun开发人员已经对大量场景进行了足够的分析以找出任何数字,他们应该至少分享一下,可能不在java doc中,而是在任何官方博客中。让开源社区的每个人都有一个想法,其他程序员可以发表意见,使这个初始容量数字更贴近实际的开发用例。
    • @Priyank Doshi:理想的初始容量在应用程序之间会有所不同,因此大量场景的平均值实际上并不是很有用 - 对于大多数应用程序来说,确切的值不太重要,但对于那些确实重要的人,您将希望为特定应用程序使用最佳价值,而不是一些平均值。
    • @PriyankDoshi:答案几乎可以肯定,值得大惊小怪并不重要。 10 或多或少足够小,如果高估也没关系,但足够大,更大的ArrayLists 会相对较快地调整大小;担心诸如确切容量之类的细节太过分了。
    • 通常,当您处理内存分配和所有这些事情时,2 的幂数是计算机编程算法中的首选。所以我想。
    • Java 内存分配的工作方式与许多其他语言中的分配不同——在垃圾收集、对象头和所有这些东西之间。最好不要太在意“二次幂”和“对齐问题”之类的东西。
    【解决方案3】:

    Vector,从 JDK 1.0 开始,默认初始容量为 10,因此当他们在 1.2 中引入 ArrayList 时,保持一致可能是有意义的。

    【讨论】:

    • 没有。那将是一个不相容的变化。 Javadoc 是规范,说默认容量是 10,所以他们不能随便更改它。
    • @PriyankDoshi 我的意思是他们可能希望 ArrayList 与 Vector 保持一致,因为它们密切相关。不参考其他集合实现。
    【解决方案4】:

    完全任意的选择。

    2 的幂在这里没有任何意义。由于散列的工作方式,它在 HashMap 中是有意义的。事实上,它必须是二的幂(根据源代码中的评论)。

    注意java.util.Vector(ArrayList的老大哥)也有10个。

    【讨论】:

    • 是的,它也有。 ArrayList 的容量也可能是有原因的。但是问题来了,为什么vector的初始容量是10?
    【解决方案5】:

    对于默认的元素数量,10 可能是一个或多或少的任意数字。

    【讨论】:

    • 我不认为sun 开发人员会不加思索地使用任何随机数作为默认数。他们一定想到了一些有用且高效的方案。
    【解决方案6】:

    除非代码中有注释,否则我们永远无法确定。然而,我想在某个时候,一位 Sun 工程师已经收集了大量实际应用程序中 ArrayList 使用情况的统计数据,并确定……凭经验……平均而言,这 10 个结果大致上是最好的。 (这就是他们调整诸如优化器、字节码设计等等之类的东西的方式。)

    而且,还有其他人指出,对于 ArrayList 的大小,使用 2 的幂的大小没有计算优势(或劣势)。

    【讨论】:

      【解决方案7】:

      ArrayList 只是一个可以自动增长的数组..

      是的..默认大小是 10

      而且我认为这个初始/默认值背后没有太多考虑。默认值 10 似乎不太大,也不太小。(这可能是原因)。 如果超出数组的默认初始容量怎么办..? 数组的下一个容量是通过-

      New capacity=(current capacity*3)/2+1
      So next size would be (10*3)/2+1= 16
      And next (16*3)/2+1= 25
      And So on...
      

      【讨论】:

        猜你喜欢
        • 2016-03-18
        • 2010-12-12
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-10-11
        • 1970-01-01
        相关资源
        最近更新 更多