简体   繁体   English

arraylist 调整大小的时间复杂度 java

[英]time complexity for arraylist resizing java

I know that the default size for arraylist is 10, and that the arraylist automatically expands for additional items added.我知道 arraylist 的默认大小是 10,并且 arraylist 会自动扩展以添加其他项目。

What is the time complexity for the resizing/expansion ?调整大小/扩展的时间复杂度是多少?

is it similar to a normal array, where the items have to be copied over into the new larger array for O(n) time?它是否类似于普通数组,其中的项目必须在 O(n) 时间内复制到新的更大的数组中?

Overview概述

The time complexity for resizing is O(n) .调整大小的时间复杂度为O(n)

It will create a new array with double the capacity and copy over each element from the original array into the new array.它将创建一个容量翻倍的新数组,并将每个元素从原始数组复制到新数组中。 This requires a full iteration .这需要一个完整的迭代 Note that this can be optimized internally by the JVM though.请注意,这可以通过 JVM 在内部进行优化。


Amortized摊销

Resizing is not needed often .不需要经常调整大小。 In particular not for every add call.特别是不是每个add调用。 Hence, why it doubles the internal capacity.因此,为什么它将内部容量加倍。 This gives room for a whole bunch of subsequent add -calls.这为一大堆后续的add调用提供了空间。

More formally, this yields the amortized complexity of O(1) for add , even though its regular complexity would be O(n) bound by the resize .更正式地说,这会为add产生O(1)分摊复杂度,尽管其常规复杂度将是O(n)resize约束。


Details细节

You can see the source of this here (OpenJDK 17):您可以在此处查看其来源(OpenJDK 17):

private Object[] grow(int minCapacity) {
    int oldCapacity = elementData.length;
    if (/* ... */) {
        int newCapacity = ArraysSupport.newLength(oldCapacity,
                minCapacity - oldCapacity, /* minimum growth */
                oldCapacity >> 1           /* preferred growth */);
        return elementData = Arrays.copyOf(elementData, newCapacity);
    } else {
        // ...
    }
}

The preferred growth is oldCapacity >> 1 , ie double the capacity.首选增长oldCapacity >> 1 ,即容量加倍。 The actual part that costs you performance and gives you the O(n) is Arrays.copyOf(...) .使您付出性能代价并为您提供O(n)的实际部分是Arrays.copyOf(...)

This method is called primarily from this helper :这个方法主要是从这个助手调用的:

private void add(E e, Object[] elementData, int s) {
    if (s == elementData.length)
        elementData = grow();
    elementData[s] = e;
    size = s + 1;
}

That is used by the main entry point add(E) :由主入口点add(E)使用:

public boolean add(E e) {
    modCount++;
    add(e, elementData, size);
    return true;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM