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

Declaring initial capaity for a list in java is a bad technique?

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

我知道 Array 和 ArrayList 之间的一个区别是 Array 的容量是固定的,而 ArrayList 的容量是可变的。您应该在声明时显式指定数组长度,但 ArrayList 在变满时会自行调整大小。

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

A - 用第一个容量显式初始化 ArrayList 的其余部分,因此这些列表将不必调整自身大小并将旧数组元素复制到新数组元素或,

B - 我可以放弃其余的列表,我只声明第一个列表,其余的将是具有 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];
...

问题是:

A 示例是一种糟糕的编程技术吗?但是B例呢?

用哪个例子比较好?

创建具有初始容量的 ArrayList 一点也不差。事实上,它将为您提供更好的性能,因为它不必在每次大小已满时重新分配内存并复制现有内容,同时您不断向列表中添加元素。

来自Java docs,

Each ArrayList instance has a capacity. The capacity is the size of the array used to store the elements in the list. It is always at least as large as the list size. As elements are added to an ArrayList, its capacity grows automatically. The details of the growth policy are not specified beyond the fact that adding an element has constant amortized time cost.

An application can increase the capacity of an ArrayList instance before adding a large number of elements using the ensureCapacity operation. This may reduce the amount of incremental reallocation.

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

好:

    List<Stuff> stuffList = getStuff();
    List<String> stuffNames = new ArrayList<String>( stuffList.size() );
    for (Stuff stuff : stuffList) {
        stuffNames.add( stuff.getName() );
    }

但是在这个例子中,我们并不总是添加名字,这取决于 hasNiceName() - 所以在这个例子中我们创建了一个容量大于可能需要的列表。

差:

    List<Stuff> stuffList = getStuff();
    List<String> stuffNames = new ArrayList<String>( stuffList.size() );
    for (Stuff stuff : stuffList) {
        if (stuff.hasNiceName()) {
            stuffNames.add( stuff.getName() );
        }
    }

但是,对于我的好例子,这取决于您是否认为这是一种代码味道以及自扩展列表与开发人员无关。