在java中声明列表的初始容量是一种糟糕的技术?

在java中声明列表的初始容量是一种糟糕的技术?,java,arrays,list,arraylist,collections,Java,Arrays,List,Arraylist,Collections,我有多个具有相同容量的ArrayList。我通过读取文件来填写这些列表 我知道数组和ArrayList之间的一个区别是数组具有固定容量,而ArrayList具有可变容量。声明数组长度时,应该显式指定它,但当数组列表变满时,它会重新调整大小 ArrayList中的任何调整大小操作都会降低性能,因为它涉及到创建新数组以及将内容从旧数组复制到新数组。因此,我想: A-使用first的容量显式初始化其余的ArrayList,这样这些列表就不必调整自身大小,也不必将旧的数组元素复制到新的数组元素 B-我可

我有多个具有相同容量的ArrayList。我通过读取文件来填写这些列表

我知道数组和ArrayList之间的一个区别是数组具有固定容量,而ArrayList具有可变容量。声明数组长度时,应该显式指定它,但当数组列表变满时,它会重新调整大小

ArrayList中的任何调整大小操作都会降低性能,因为它涉及到创建新数组以及将内容从旧数组复制到新数组。因此,我想:

A-使用first的容量显式初始化其余的ArrayList,这样这些列表就不必调整自身大小,也不必将旧的数组元素复制到新的数组元素

B-我可以放弃列表的其余部分,我只声明第一个列表,其余部分将是具有ArrayList长度的数组

例如:

A:

static ArrayList list1=new ArrayList();
ArrayList list2=新的ArrayList(list1.size());
ArrayList list2=新的ArrayList(list1.size());
...
B:

static ArrayList list1=new ArrayList();
ObjectType[]array1=新的ObjectType[list1.size()];
ObjectType[]array2=新的ObjectType[list1.size()];
ObjectType[]array3=新的ObjectType[array1.length];
...
问题是:

这个例子是一种糟糕的编程技术吗?但是B的例子呢


使用哪个示例更好?

创建具有初始容量的ArrayList是一项不错的技术。事实上,它将给你一个更好的性能,因为它不必重新分配内存和复制现有的内容,每次大小是满的,而你继续添加元素到列表中

每个ArrayList实例都有一个容量。容量是指容量的大小 用于存储列表中元素的数组。它总是在 至少与列表大小一样大。当元素添加到 ArrayList,其容量会自动增长。增长的细节 策略的指定不超过添加元素 固定摊销时间成本

应用程序可以增加ArrayList实例的容量 在使用EnsureCapity添加大量元素之前 活动这可能会减少增量重新分配的数量


我唯一一次设置列表的初始大小是当我确定我知道列表将包含多少元素时。在下面的示例中,stuffNames中的元素数将与原始stuffList中的元素数完全相同。因此,我们不需要在添加列表时对列表进行自我扩展

好:

List stuffList=getStuff();
List stuffNames=新的ArrayList(stuffList.size());
用于(填充:填充列表){
添加(stuff.getName());
}
但在本例中,我们并不总是添加名称,这取决于hasNiceName()-因此在本例中,我们创建了一个容量大于可能需要的列表

坏的:

List stuffList=getStuff();
List stuffNames=新的ArrayList(stuffList.size());
用于(填充:填充列表){
if(stuff.hasNiceName()){
添加(stuff.getName());
}
}

但是,就我的例子来说,这取决于你是否认为这是代码的味道,而自我扩展列表与开发人员无关。< / P>我根本不明白你的目标是什么。
list1
中有什么内容?根据您要做的事情,您可以简单地使用
ArrayList(list1)将复制
列表1
。向
ArrayList
提供任何大小调整信息的原因是为了在接近容量时提高性能。两者都不是好的,也不是坏的,它们都完成了相同的事情,但是
ArrayList
是动态的,这意味着它可以增长……您如何知道需要多少额外的列表?如果你知道这个数字,为什么不用这个容量初始化你的原始列表呢?@Sotirios Delimanolis:我说我在从文件中读取元素。首先,我在列表1中添加元素。下一个列表的容量将与列表1的容量相等。因此,我随后添加到下一个列表中的元素不必在新的调整大小的ArrayList自身调整大小后进行压缩,因为它已完全填充。对于删除元素的人:ArrayList的第一个容量不是0,而是一个正数:@Sotirios Delimanolis:我知道我需要多少额外的列表,因为我知道我在读取的文件中查找哪种类型的元素。这不是问题……你认为哪个例子更好?我认为,如果我指定后续列表的初始容量,那么在内存分配方面将与B示例中的数组完全相同。
ArrayList
也是一种仅在幕后实现的数组。当考虑内存分配时,使用<代码> ARARYLIST/<代码>可以使用比数组高的非常小的常量内存。但您有很多好处,比如可以轻松添加和删除元素。因此,我将使用ArrayList实现。事实上,使用列表有很多好处,而且代码更清晰。我将初始化后续列表的容量。谢谢大家的帖子!
static ArrayList<ObjectType> list1 = new ArrayList<>();
ArrayList<ObjectType> list2 = new ArrayList<>(list1.size());
ArrayList<ObjectType> list2 = new ArrayList<>(list1.size());
...
static ArrayList<ObjectType> list1 = new ArrayList<>();
ObjectType[] array1 = new  ObjectType[list1.size()]; 
ObjectType[] array2 = new  ObjectType[list1.size()];
ObjectType[] array3 = new  ObjectType[array1.length];
...
    List<Stuff> stuffList = getStuff();
    List<String> stuffNames = new ArrayList<String>( stuffList.size() );
    for (Stuff stuff : stuffList) {
        stuffNames.add( stuff.getName() );
    }
    List<Stuff> stuffList = getStuff();
    List<String> stuffNames = new ArrayList<String>( stuffList.size() );
    for (Stuff stuff : stuffList) {
        if (stuff.hasNiceName()) {
            stuffNames.add( stuff.getName() );
        }
    }