Java 创建初始容量为0的ArrayList的优点?
我是一个有点经验的Java开发人员,我经常看到这样的事情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项:返回空数组或集合,而不是空值。最好给数组
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
}
}
}