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

Java 创建初始容量为0的ArrayList的优点?,java,arraylist,capacity,Java,Arraylist,Capacity,我是一个有点经验的Java开发人员,我经常看到这样的事情 List<Integer> l = new ArrayList<Integer>(0); List l=新的数组列表(0); 我真的不明白。当您知道将超出容量时,创建初始容量为0的ArrayList有什么意义 这样做有什么好处吗?根据合同的不同,您可以通过不使用空值来避免空值异常。在某些情况下,这是一种很好的做法,请参见Joshua Bloch的《高效Java》第43项:返回空数组或集合,而不是空值。最好给数组

我是一个有点经验的Java开发人员,我经常看到这样的事情

List<Integer> l = new ArrayList<Integer>(0);
List l=新的数组列表(0);
我真的不明白。当您知道将超出容量时,创建初始容量为0的
ArrayList
有什么意义


这样做有什么好处吗?

根据合同的不同,您可以通过不使用空值来避免空值异常。在某些情况下,这是一种很好的做法,请参见Joshua Bloch的《高效Java》第43项:返回空数组或集合,而不是空值。最好给数组列表指定一个较大的值(如果列表超过了多少),因为这将减少列表的大小,从而优化执行时间


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

对于java6(或openjdk 7),如果不指定初始大小,将为您提供一个初始大小设置为10的列表。因此,根据列表使用的许多因素,使用大小
0
初始化列表可能会略微增加内存和/或性能效率

对于java7,指定初始大小
0
在功能上等同于不指定初始大小

但是,它实际上效率较低,因为使用参数
0
调用构造函数会导致调用
新对象[0]
,而如果指定无参数构造函数,则列表的初始
elementData
设置为名为
EMPTY\u elementData
的静态定义常量

来自
ArrayList
的相关代码来源:

/**
 * Shared empty array instance used for empty instances.
 */
private static final Object[] EMPTY_ELEMENTDATA = {};
换句话说,使用
新的ArrayList(0)似乎是多余的,这样做没有好处,我会使用
newarraylist()代替。

  • 如果对
    ArrayList
    的添加不太可能,并且如果将
    ArrayList
    的大小保持在最小值很重要,那么我可以看出这很有用

  • 或者,如果该
    ArrayList
    的唯一用途是从方法返回值,其中返回空列表是向函数调用方发送的特殊消息,如“找不到结果”

  • 否则,就不会了

它将
数组列表的大小(在内存中)保持得非常小,并且是一种策略,用于您希望变量为非空且可以使用,但不要期望立即填充
列表。如果您希望立即填充它,最好给它一个较大的初始值-
ArrayList
的任何“增长”都是在内部创建一个新的基元数组,并复制项目。
ArrayList
的增长非常昂贵,应该最小化

或者,如果您正在创建一个类的许多实例,每个实例都包含一个
列表
属性。如果您没有立即计划填充它们,您可以通过不分配房间来节省一点内存

但是:有一个更好的方法:
Collections.emptyList()
。通常,您希望直接保护对该列表的访问,并且(作为示例)在类中提供对内部
列表
进行操作的特定于域的方法调用。例如,假设您有一个
学校
类,该类包含学生姓名的
列表。(保持简单,注意这个类不是线程安全的。)

公立学校{
private List studentNames=Collections.emptyList();
public void addStudentName(字符串名称){
if(studentNames.isEmpty()){
studentNames=newarraylist();
}
学生姓名。添加(姓名);
}
public void removeStudentName(字符串名称){
学生姓名。删除(姓名);
if(studentNames.isEmpty()){
studentNames=Collections.emptyList();//GC将取消分配旧列表
}
}
}

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

默认情况下,
ArrayList
的容量为,并且每次调整的大小为+50%


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

可能的重复也:@Ascalonian我确实知道区别,我想知道的是这样做的好处,而不是做
new ArrayList()
。不是dup。请参阅第二个链接Iprovided@Ascalonianbarq的回答似乎更合适。我无意中发现了第二个链接,但它仍然不是我想知道的。openjdk 7也是如此。不适用于OpenJDK 6请参见->甚至不适用于所有版本的OpenJDK 7,似乎:但我也不知道grepcode的准确程度…这也是我的想法,但刚刚检查了OpenJDK 7的源代码,它现在通过使用@vikingsteve所描述的共享空元素进行优化。显然,问题不是对比ArrayList()和ArrayList(),而是询问使用ArrayList(0)的一般原因。当然,还有其他选择。是的,它是正确的,而不是在数组列表中保留
null
值,将其初始化为零。@vikingsteve谢谢你的回复,我编辑了我的答案。好的,我删除了我的否决票。您的答案现在好多了,谢谢您抽出时间再次编辑。@vikingsteve我喜欢您帮助我改进了我的答案。
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
        }
    }
}