问题

这个问题在这里已有答案:

  • 清空一个ArrayList或者只是创建一个新的ArrayList并将旧的那个垃圾收集? [重复] 4个答案
  • Map.clear()vs new Map:哪一个更好? [重复] 7个答案

清除ArrayList的两个选项中哪一个更好更快,为什么?

list.clear()

要么

list = new ArrayList<Integer>();

碰巧我必须在随机的时间清除我的ArrayList中的所有条目,我无法知道将来会有多少新条目,可能有0或1000.哪种方法更快更好,为什么?


#1 热门回答(67 赞)

没有基准测试很难知道,但是如果你的ArrayList中有很多项目并且平均大小较低,那么创建一个新的ArrayList可能会更快。
http://www.docjar.com/html/api/java/util/ArrayList.java.html

public void clear() {
    modCount++;

    // Let gc do its work
    for (int i = 0; i < size; i++)
        elementData[i] = null;

    size = 0;
}

#2 热门回答(23 赞)

List.clear将删除元素而不会降低列表的容量。

groovy:000> mylist = [1,2,3,4,5,6,7,8,9,10,11,12]
===> [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
groovy:000> mylist.elementData.length
===> 12
groovy:000> mylist.elementData
===> [Ljava.lang.Object;@19d6af
groovy:000> mylist.clear()
===> null
groovy:000> mylist.elementData.length
===> 12
groovy:000> mylist.elementData
===> [Ljava.lang.Object;@19d6af
groovy:000> mylist = new ArrayList();
===> []
groovy:000> mylist.elementData
===> [Ljava.lang.Object;@2bfdff
groovy:000> mylist.elementData.length
===> 10

这里mylist被清除了,对它所持有的元素的引用被删除了,但它保留了相同的后备数组。然后mylist重新初始化并得到一个新的后备阵列,旧的得到了GCed。因此,一种方式保留在内存中,另一种方式抛出其内存并从头开始重新分配(使用默认容量)。哪个更好取决于你是否要减少垃圾收集流失或最小化当前未使用的内存量。列表是否足够长以便移出伊甸园可能是决定哪个更快的一个因素(因为这可能使垃圾收集更加昂贵)。


#3 热门回答(15 赞)

我认为答案是它取决于一系列因素,例如:

  • 是否可以预先预测列表的大小(即,你是否可以准确设置容量),
  • 列表大小是否可变,
  • 列表的生命周期在两个版本中都有多长,和
  • 你的堆/ GC参数和CPU。

这些使得很难预测哪个更好。但我的直觉是差异不会那么大。

两点建议:

  • 不要浪费时间尝试优化这个...除非应用程序客观上太慢>>和<<分析器告诉你这是一个性能热点。 (很可能这些先决条件中的一个或另一个不是真的。)
  • 如果你决定优化这个,那就科学地做。尝试两种(所有)备选方案,并通过在实际问题/工作负载/输入集上测量实际应用程序的性能来确定哪种方案最佳。 (由于上面列出的因素,人工基准测试不太可能为你提供可以使用的答案。)

原文链接