一尘不染

在Java 8中,为什么ArrayList的默认容量现在为零?

java

我记得在Java 8之前,默认容量ArrayList是10。

令人惊讶的是,对默认(void)构造函数的评论仍然是: Constructs an empty list with an initial capacity of ten.

来自ArrayList.java

/**
 * Shared empty array instance used for default sized empty instances. We
 * distinguish this from EMPTY_ELEMENTDATA to know how much to inflate when
 * first element is added.
 */
private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};

...

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

阅读 288

收藏
2020-09-08

共1个答案

一尘不染

从技术上讲,10如果您允许对备用数组进行延迟初始化,则它为,而不是零。看到:

public boolean add(E e) {
    ensureCapacityInternal(size + 1);
    elementData[size++] = e;
    return true;
}

private void ensureCapacityInternal(int minCapacity) {
    if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
        minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
    }

    ensureExplicitCapacity(minCapacity);
}

哪里

/**
 * Default initial capacity.
 */
private static final int DEFAULT_CAPACITY = 10;

您所指的只是在所有最初为空的ArrayList对象之间共享的大小为零的初始数组对象。即 懒惰地10保证的容量,Java 7中也存在这种优化。
__

诚然,建设者合同并不完全准确。也许这是造成混乱的根源。

背景

这是Mike Duigou的电子邮件

我已经发布了空ArrayList和HashMap补丁的更新版本。

http://cr.openjdk.java.net/~mduigou/JDK-7143928/1/webrev/

修订后的实现 没有 为这两个类引入 任何新字段
。对于ArrayList,仅当列表以默认大小创建时才进行后备阵列的延迟分配。根据我们的性能分析团队的说法,大约有85%的ArrayList实例是在默认大小下创建的,因此此优化将在绝大多数情况下有效。

对于HashMap,创意使用阈值字段来跟踪请求的初始大小,直到需要存储桶数组为止。在读取方面,使用isEmpty()测试空映射案例。在写入大小上,比较(table
== EMPTY_TABLE)用于检测是否需要对存储桶数组进行充气。在readObject中,还有更多工作来尝试选择有效的初始容量。

来自: http : //mail.openjdk.java.net/pipermail/core-libs-
dev/2013-April/015585.html

2020-09-08