Java Array列表的trimToSize()方法是多余的吗?

时间:2014-06-03 02:18:38

标签: java arraylist

我认为Java的ArrayList中的trimToSize()方法是不必要的。我的理解是:

让我们取一个整数数组:

int[] a = new int[10]; //This allocates ten free slots proactively.

ArrayList的主要优点是它可以在运行时动态创建数组,从而节省内存。现在的代码 ArrayList<Integer> arl = new ArrayList<Integer>(10);不会主动分配十个免费插槽;相反,只有在存储数据时才会添加插槽。

现在Java规范说trimToSize()将从ArrayList中删除未使用的空间,但根据我的理解,ArrayList中不会有任何未使用的空间,因为只有在数据可用且数据可用时才会创建空间未使用或可用空间将为零。

2 个答案:

答案 0 :(得分:8)

您的理解不正确。如果你创建一个new ArrayList<Integer>(10),它将创建一个大小为10的整数数组,在ArrayList中填充空值作为其数据模型的核心。它将根据项目数填充部分或全部插槽,如果项目数超过其可能大小的数量,它将增加基础数组的大小。 trimToSize()方法具有相关性。

答案 1 :(得分:5)

冗余:没有。有用?只有在非常特殊的情况下。

你应该知道的是,ArrayList在填充了一定比例的元素时会增加后备阵列。

[以前的内容用于Map,而不是ArrayList]

每次添加项目时,ArrayList都会在内部检查是否应该调整后备阵列的大小:

public boolean add(E e) {
    ensureCapacityInternal(size + 1);  // Increments modCount!!
}

private void ensureCapacityInternal(int minCapacity) {
    if (minCapacity - elementData.length > 0)
        grow(minCapacity);
}

private void grow(int minCapacity) {
    // overflow-conscious code
    int oldCapacity = elementData.length;
    int newCapacity = oldCapacity + (oldCapacity >> 1);
    elementData = Arrays.copyOf(elementData, newCapacity);
}

我遗漏了一些主要是边界检查的东西。因此,您可以看到:当空间用完而无法添加项目时,它将创建一个1.5倍于前一个数组的新数组,并将所有项目添加到其中。对于10个项目的初始值,它将立即到达15个。

将其推断为更高的值,您可以看到当您可能完成添加项目时,您突然开始分配数千个空数组条目。

同样,删除值可能会导致1000万个元素的后备数组缩小为10个元素。当你只需要十几个时,分配几百万个数组条目是相当浪费的。