简体   繁体   English

过滤Java中的列表,同时避免o(n)复杂性导致的ConcurrentModificationException

[英]Filtering a list in Java while avoiding ConcurrentModificationException in o(n) complexity

I found out that apparently iterator.remove() has an o(n) complexity. 我发现显然iterator.remove()具有o(n)复杂度。 Anybody, knows of a way of filtering a list while avoiding ConcurrentModificationException without using iterator.remove(). 任何人都知道一种在不使用iterator.remove()的情况下避免ConcurrentModificationException的同时过滤列表的方法。

Following is a code snippet showing the difference. 以下是显示差异的代码段。 It creates a large array list and then deletes large part of it from the middle using it.remove(). 它创建一个大数组列表,然后使用it.remove()从中间删除其中很大一部分。 Then it does the same thing just this time from the start. 然后只是从头开始这一次做同样的事情。 On my machine it reads: First test 699962ms Second test 329181ms 在我的机器上显示为:第一次测试699962ms,第二次测试329181ms

clearly a big difference 显然有很大的不同

package src;

import java.util.*;
import java.lang.*;

class Main {
    public static void main(String[] args) {
        ArrayList<Integer> a = new ArrayList<Integer>();
        long before, after;

        double elements = Math.pow(10, 3);

        for(int i = 0; i < elements; i++) {
            a.add(i);
        }

        Iterator<Integer> it = a.iterator();
        for(int i = 0; i < elements * 0.4; i++){
            it.next();
        }

        before = System.nanoTime();
        for(int i = 0; i < elements * 0.5; i++){
            it.remove();
            it.next();
        }
        after = System.nanoTime();
        System.out.println(after - before);

        a = new ArrayList<Integer>();
        for(int i = 0; i < elements; i++) {
            a.add(i);
        }


        before = System.nanoTime();
        it = a.iterator();
        it.next();
        for(int i = 0; i < elements * 0.5; i++){
            it.remove();
            it.next();
        }
        after = System.nanoTime();
        System.out.println(after - before);


    }
}

As informed, your benchmark is incorrect. 据告知,您的基准测试不正确。 Considering that a single remove from an ArrayList made with either remove() or Iterator.remove() is an O(n) operation (unless removing the last element) due to the resizing of the internal array, the code won't perform well under any circumstances. 考虑到由于内部数组的大小调整,使用remove()Iterator.remove()ArrayList进行的单个删除是O(n)操作(除非删除最后一个元素),所以该代码无法很好地执行在任何情况下。

A LinkedList would provide you an O(1) removal while iterating it, but you should go for the easiest solution and use List.removeIf() . LinkedList会在迭代时为您提供O(1)删除,但是您应该寻求最简单的解决方案并使用List.removeIf() ArrayList overrides it for O(n) performance and avoids CME too. ArrayListO(n)性能重写它,并且也避免使用CME

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

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