在 Java 8 中,为什么 ArrayList 的默认容量现在为零? [英] In Java 8, why is the default capacity of ArrayList now zero?

查看:40
本文介绍了在 Java 8 中,为什么 ArrayList 的默认容量现在为零?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

As I recall, before Java 8, the default capacity of ArrayList was 10.

令人惊讶的是,对默认(void)构造函数的注释仍然说:Constructs a empty list,初始容量为十.

Surprisingly, the comment on the default (void) constructor still says: 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;
}

推荐答案

从技术上讲,它是 10,而不是零,如果您承认支持数组的延迟初始化.见:

Technically, it's 10, not zero, if you admit for a lazy initialisation of the backing array. See:

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 对象之间共享的大小为零的初始数组对象.IE.10 的容量被保证延迟,Java 7 中也有这种优化.

What you're referring to is just the zero-sized initial array object that is shared among all initially empty ArrayList objects. I.e. the capacity of 10 is guaranteed lazily, an optimisation that is present also in Java 7.

诚然,建设者合同并不完全准确.也许这就是这里混乱的根源.

Admittedly, the constructor contract is not entirely accurate. Perhaps this is the source of confusion here.

这是 Mike Duigou 的电子邮件

Here's an E-Mail by Mike Duigou

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

I have posted an updated version of the empty ArrayList and HashMap patch.

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

这个修订后的实现没有向任一类引入新字段.对于 ArrayList,仅当以默认大小创建列表时,才会发生后备数组的延迟分配.根据我们的性能分析团队,大约 85% 的 ArrayList 实例是在默认大小下创建的,因此这种优化对于绝大多数情况都是有效的.

This revised implementation introduces no new fields to either class. For ArrayList the lazy allocation of the backing array occurs only if the list is created at default size. According to our performance analysis team, approximately 85% of ArrayList instances are created at default size so this optimization will be valid for an overwhelming majority of cases.

对于 HashMap,创造性地使用了阈值字段来跟踪请求的初始大小,直到需要存储桶数组.在读取端,空地图案例使用 isEmpty() 进行测试.在写入大小上,(table == EMPTY_TABLE) 的比较用于检测是否需要扩充存储桶数组.在 readObject 中有更多的工作来尝试选择一个有效的初始容量.

For HashMap, creative use is made of the threshold field to track the requested initial size until the bucket array is needed. On the read side the empty map case is tested with isEmpty(). On the write size a comparison of (table == EMPTY_TABLE) is used to detect the need to inflate the bucket array. In readObject there's a little more work to try to choose an efficient initial capacity.

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

这篇关于在 Java 8 中,为什么 ArrayList 的默认容量现在为零?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆