创建初始容量为0的ArrayList的优点?

时间:2015-02-05 13:44:08

标签: java arraylist capacity

我是一位经验丰富的Java开发人员,我一直在看这样的事情

List<Integer> l = new ArrayList<Integer>(0);
我真的无法理解。当你知道它会超出容量时,创建一个初始容量为0的ArrayList有什么意义呢?

这样做有什么好处吗?

6 个答案:

答案 0 :(得分:6)

对于java 6 (或openjdk 7),未指定初始大小会为您提供初始大小设置为 10 的列表。因此,根据您使用列表的许多因素,初始化大小为0的列表可能会略微提高内存和/或性能。

对于java 7 ,指定初始大小0在功能上等同于未指定初始大小。

然而它实际上效率较低,因为使用参数0调用构造函数会调用new Object[0],而如果指定no-args构造函数,则初始elementData对于您的列表,将设置为静态定义的名为EMPTY_ELEMENTDATA的常量。

来自ArrayList来源的相关代码:

/**
 * Shared empty array instance used for empty instances.
 */
private static final Object[] EMPTY_ELEMENTDATA = {};

换句话说,使用new ArrayList<Integer>(0);似乎是多余的,这样做没有任何好处,我会改用new ArrayList<Integer>();

答案 1 :(得分:6)

它使ArrayList的大小(在内存中)保持非常小,并且是您希望变量非空并且可以使用时的策略,但不要期望立即填充List。如果您希望立即填充它,最好给它一个更大的初始值 - 任何&#34;成长&#34; ArrayList的内部创建一个新的基本数组,并复制项目。 ArrayList的增长是昂贵的,应该最小化。

或者,如果您正在创建批次类的实例,每个类都包含这些List属性中的一个。如果你没有立即计划填写它们,你可以通过不分配房间来节省一些内存。

然而:有更好的方法:Collections.emptyList()。通常,您希望直接保护对该列表的访问,并且(作为示例)您的类中提供对内部List进行操作的特定于域的方法调用。例如,假设您有School个班级,其中包含List个学生姓名。 (保持简单。)

public class School {
    private List<String> studentNames = Collections.emptyList();

    public void addStudentName(String name) {
        if (studentNames.isEmpty()) {
            studentNames = new ArrayList<String>();
        }
        studentNames.add(name);
    }

    public void removeStudentName(String name) {
        studentNames.remove(name);
        if (studentNames.isEmpty()) {
            studentNames = Collections.emptyList(); // GC will deallocate the old List
        }
    }
}

如果您愿意进行isEmpty()检查并执行初始化/分配,这是创建大量空ArrayList个实例的更好选择,因为Collections.emptyList()是一个静态实例(只存在一个)并且不可修改。

答案 2 :(得分:3)

  • 如果对ArrayList的添加真的不太可能,并且将ArrayList的大小保持在最低限度很重要,那么我可以看到它很有用。

    < / LI>
  • 或者,如果ArrayList的唯一目的是从方法返回值,则返回空列表是函数调用者的特殊消息,如“找不到结果”。< / p>

  • 否则,不是真的。

答案 3 :(得分:1)

向数组列表提供较大的值(如果列表将超出多少)总是更好的方法,因为它会减少列表的大小调整,从而优化执行时间。

使用值0初始化数组列表创建Empty数组列表,reducing memory如果您知道列表的内容不会超过10内容。

答案 4 :(得分:1)

默认情况下,ArrayList的容量为10,每次调整幅度为+ 50%。

通过使用较低的初始容量,您可以有时(理论上)节省内存。另一方面,每次调整大小都很耗时。在大多数情况下,这只是先发制人优化的标志。

答案 5 :(得分:-2)

根据合同,您可以通过不使用空值来避免NullPointerExceptions。在某些情况下这是一种很好的做法,请参阅Joshua Bloch的Effective Java 第43项:返回空数组或集合,而不是空值