Java 为什么AbstractList.removeRange需要二次时间?

Java 为什么AbstractList.removeRange需要二次时间?,java,collections,big-o,time-complexity,Java,Collections,Big O,Time Complexity,我可以在文档中看到: java.util.AbstractList#removeRange 它需要二次时间: 此实现在fromIndex之前获得一个列表迭代器, 并反复调用ListIterator.next,后跟ListIterator.remove 直到整个范围被移除。注意:如果ListIterator.remove 需要线性时间,此实现需要二次时间 但是为什么呢??守则: protected void removeRange(int fromIndex, int toIndex) {

我可以在文档中看到:

java.util.AbstractList#removeRange

它需要二次时间:

此实现在fromIndex之前获得一个列表迭代器, 并反复调用ListIterator.next,后跟ListIterator.remove 直到整个范围被移除。注意:如果ListIterator.remove 需要线性时间,此实现需要二次时间

但是为什么呢??守则:

protected void removeRange(int fromIndex, int toIndex) {
        ListIterator<E> it = listIterator(fromIndex);
        for (int i=0, n=toIndex-fromIndex; i<n; i++) {
            it.next();
            it.remove();
        }
    }
protectedvoidremoverange(int-fromfindex,int-toIndex){
ListIterator it=ListIterator(fromIndex);
for(int i=0,n=toIndex fromIndex;i重要的部分是“注意:如果ListIterator.remove需要线性时间,则此实现需要二次时间”。for循环需要线性时间,您是对的。但是,如果您在每次迭代中执行线性时间步,您会得到
n*n=n^2
原因在于:

it.remove();
这可以是列表上的O(n)操作,在O(n)循环中调用

换句话说,如果是这样的话,你的真实循环会是这样的(我编的,但你明白了):

protectedvoidremoverange(int-fromfindex,int-toIndex){
ListIterator it=ListIterator(fromIndex);
对于(int i=0,n=toIndex-fromIndex;i
“这通常是列表上的O(n)操作”“通常”有点言过其实。对于ArrayList是O(n),但是对于LinkedList是O(1)。
protected void removeRange(int fromIndex, int toIndex) {
    ListIterator<E> it = listIterator(fromIndex);
    for (int i = 0, n = toIndex - fromIndex; i < n; i++) {
        E item = it.next();
        //it.remove();
        for (int j = ; j < n; j++) {
            if (list.get(j).equals(e)) {
                list.remove(e);
                break;
            }
        }
    }
}