从ArrayList中删除元素的哪种方式更有效?

时间:2012-04-16 01:19:35

标签: java arraylist

我有以下声明:

ArrayList<String> list = new ArrayList<String>();
list.add("1");
list.add("2");
list.add("2");
list.add("3");
list.add("4");

现在我的问题是:如果我想从列表中删除“2”,哪种方式更好?

第一种方式:

for(int i = 0; i < list.size(); i++) {
    if(list.get(i).equals("2")) {
        list.remove(i);
        i--;
    }
}
第二种方式:

Iterator<String> iterator = list.iterator();
    while(iterator.hasNext())
        if(iterator.next().equals("2"))
            iterator.remove();

两者是否正确安全且效率更高?

是否还有其他方法可以从ArrayList中删除元素而不会出现IndexOutOfBounds错误?

4 个答案:

答案 0 :(得分:5)

实际上,可能更快的是

list.removeAll(Collections.singleton("2"));

在幕后,对于ArrayList,它基本上会像@Edmund建议的那样创建一个新的数组副本,但是在较低的级别,这可能会带来更高的性能。

正如其他人所提到的,LinkedList通常可以从大型列表中删除多个元素。

(即使您决定切换到LinkedList,您仍然可以使用上面的代码,它将等同于使用迭代器方法,对于创建的单例集合以及某些发生额外的方法调用。)

答案 1 :(得分:2)

无论哪种方式都需要为每个删除的元素向下移动元素。如果您的列表非常大,那么创建新列表可能会更快:

ArrayList<String> newList = new ArrayList<String>();
Iterator<String> iterator = list.iterator();
while (iterator.hasNext()) {
    String val = iterator.next();
    if(!val.equals("2"))
        newList.add(val);
}

/* Or just return newList, depending on how list is used in subsequent code. */
list.clear();
list.addAll(newList);

您可以考虑使用LinkedList代替ArrayList。但基准测试(使用实际用例)是找出效率最高的最佳方法。

答案 2 :(得分:0)

对于单个元素,你的for循环将正常工作(当你移除i--时它会移动 - remove()自动将元素移到左边)(不,真的,它会工作正常)。你的迭代方法也是如此。

你只是迭代到ArrayList的末尾,你不会离开它。在效率方面,它是一种洗涤方式 - 我建议您使用大小为100,000的样本运行时间,看看它是如何运行的。 (无论列表有多大,它仍然是O(N)操作的顺序。)

答案 3 :(得分:-1)

我在一些数据结构书中已经阅读过,迭代器方法更好,

如果list.remove调用循环,evety time它将从0索引开始索引ot项目删除,然后删除元素并移动受影响的元素,它将是o(n2)进程。

但是在iterator.remove的情况下,元素被删除,因为它们被迭代器访问而不必返回列表的开始,因此o(n)进程。