在尝试操作ArrayList时是否更快地复制ArrayList或使用ListIterator?

时间:2015-12-01 15:59:12

标签: java arraylist listiterator

我有多个ArrayList包含大量数据,我需要快速有效地操作数据。我的代码目前复制了原始ArrayList,以便我可以进行更改(避免ConcurrentModificationException)。这种方法似乎效率低下。

我已经查看了ListIterator,他们看起来更多"干净"高效。我跑了一个快速测试,看看哪个实际上更快,看起来重复原始的ArrayList可能会更快。这是真的还是我的测试在某种程度上存在缺陷?如果是真的,它只适用于较小的ArrayList s吗?

我跑的测试如下:

long startTime, stopTime;

ArrayList<ArrayList<String>> array = new ArrayList<>();

ArrayList<String> a1 = new ArrayList<>();
ArrayList<String> a2 = new ArrayList<>();
ArrayList<String> a3 = new ArrayList<>();

for (int i = 0; i < 5; i++) {
    a1.add(Integer.toString(i));
    a2.add(Integer.toString(i));
    a3.add(Integer.toString(i));
}

array.add(a1);
array.add(a2);
array.add(a3);

startTime = System.nanoTime();

ArrayList<ArrayList<String>> arrayCopy = new ArrayList<>();
for (int i = 0; i < array.size(); i++) {
    ArrayList<String> line = array.get(i);
    arrayCopy.add(i, new ArrayList<>(line.size()));
    for (int j = 0; j < line.size(); j++) {
        arrayCopy.get(i).add(j, line.get(j));
    }
}

for (int j = 0; j < array.size(); j++) {
    for (int i = 0; i < array.get(j).size(); i++) {
        if (array.get(j).get(i).equals("2")) {
            arrayCopy.get(j).add(i, "1.5");
        }
    }
}

stopTime = System.nanoTime() - startTime;

System.out.println(arrayCopy.get(0));
System.out.println(arrayCopy.get(1));
System.out.println(arrayCopy.get(2));

System.out.println(stopTime);

ArrayList<ArrayList<String>> brray = new ArrayList<>();

ArrayList<String> b1 = new ArrayList<>();
ArrayList<String> b2 = new ArrayList<>();
ArrayList<String> b3 = new ArrayList<>();

for (int i = 0; i < 5; i++) {
    b1.add(Integer.toString(i));
    b2.add(Integer.toString(i));
    b3.add(Integer.toString(i));
}

brray.add(b1);
brray.add(b2);
brray.add(b3);

startTime = System.nanoTime();
for (ArrayList<String> s : brray) {
    ListIterator<String> i = s.listIterator();
    while (i.hasNext()) {
        if (i.next().equals("1")) {
            i.add("1.5");
        }
    }
}

stopTime = System.nanoTime() - startTime;

System.out.println(b1);
System.out.println(b2);
System.out.println(b3);

System.out.println(stopTime);

运行代码五次,给我时间(以纳秒为单位)的重复方法73307, 46916, 77705, 76606 and 82470307888, 319984, 304590, 363235 and 280032方法的ListIterator

2 个答案:

答案 0 :(得分:2)

我不确定他们的实施情况,但是从一些测试来看:

对于较大的尺寸,ListIterator将击败ArrayList方法。

对于较小的尺寸,只需创建ListIterator所需的时间比ArrayList方法长。

此外,时间基准有点值得怀疑,因为它不仅仅是程序本身。特别是在10 ^( - 3)秒内的那些。

答案 1 :(得分:0)

查看ArrayList实现。 http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/6-b14/java/util/ArrayList.java#ArrayList.add%28java.lang.Object%29

你需要更多的物品才能做出好的测试。 ArrayList使用内部数组,默认情况下创建一个10项的数组。所以你的add / get等方法的复杂度为O(1)。您可以查看listIterator方法。它使用相同的方法。我想,当你明确使用ArrayList但是使用List接口时,你不需要使用迭代器,因为实现可能会有所不同。