ArrayList.clear()与ArrayList=null的区别

3

在Java中,哪个运行速度更快? 假设我想多次使用ArrayList,但是每次使用时都需要不同的值,那么使用clear()方法还是将ArrayList设置为null更好?

2个回答

3

1) 实际上,你想要比较的不是

temp=null; versus temp.clear();

但是。
temp=new ArrayList<>(); versus temp.clear();

或者换句话说:我们应该创建一个新的ArrayList,还是通过调用clear()来回收旧的ArrayList
看看这个没有回收旧ArrayList实例的代码:
    for(int i=0;i<2000;i++)
    {
        temp=new ArrayList<Integer>();
        for(int j=0;j<2000;j++)
        {
            temp.add(j);
        }
        ret.add((ArrayList<Integer>)temp.clone());
        temp=null;
    }

temp=null 是外部循环最后一条语句,在每次迭代的开始,之前由temp变量引用的ArrayList对象被丢弃,并创建并分配一个新的ArrayList对象。
因此将其赋值为null是毫无意义的。

2)你的测试有偏差。
重复使用ArrayList实例会获得更好的结果,因为你有一个适合的用例。

ArrayList是基于数组的。
在外部循环的第一次迭代中,内部循环的迭代使支持数组多次增长。
因此,在下一次外部循环的迭代中,它利用支持数组已经具有所需大小的特点。
因此,不需要增加支持数组的大小。

例如,如果您更改代码版本,每次迭代都重新创建一个ArrayList实例,调用构造函数public ArrayList(int initialCapacity)并将2000作为参数传递,应该可以改善实际上最慢的版本。


我已经处理了偏差并得到了相反和令人震惊的结果。 - panshul
确实。差别很大。请注意,在您的示例中,清除ArrayList会迭代2,000个元素2,000次。这很重要。因此,通过指定ArrayList的目标大小并避免迭代清除,这个版本可能只会更快。 - davidxxx
但是当分配一个新的数组时,之前的内存也必须被垃圾收集器清除。 - panshul
并不是立即进行垃圾回收。实际上,只有当堆的使用接近最大值时,GC才会进行回收。当对象不再被引用时,我们称其为可回收。这可能需要几毫秒或几秒钟。而clear()方法的实现则迭代所有元素将它们设置为null:for (int i = 0; i < size; i++) elementData[i] = null; - davidxxx

1
所以为了了解这个,我运行了这段代码两次,使用了不同的方式来清空一个数组。 首先我使用了clear方法。
    `class Check
     {
        public static void main (String[] args) throws java.lang.Exception
        {
            ArrayList<ArrayList<Integer>> ret=new ArrayList<ArrayList<Integer>>();
            ArrayList<Integer> temp=new ArrayList<Integer>(2000);
            for(int i=0;i<2000;i++)
            {

                for(int j=0;j<2000;j++)
                {
                    temp.add(j);
                }
                ret.add((ArrayList<Integer>)temp.clone());
                temp.clear();
            }
        }
    }

`

我得到了以下统计数据: 运行时间:1.87秒 内存:4386816KB
另一方面,当我使用以下代码运行null方法时。
`   class Check
    {
        public static void main (String[] args) throws java.lang.Exception
        {
            ArrayList<ArrayList<Integer>> ret=new ArrayList<ArrayList<Integer>>();
            ArrayList<Integer> temp;
            for(int i=0;i<2000;i++)
            {
                temp=new ArrayList<Integer>(2000);
                for(int j=0;j<2000;j++)
                {
                    temp.add(j);
                }
                ret.add((ArrayList<Integer>)temp.clone());

            }
        }
    }

我得到的统计数据为运行时间:0.19秒,内存使用量:4386816KB。

因此很明显,“clear()”方法比“null”方法慢,尽管它们所使用的内存相同。


null 不是一个方法,你也没有对数组列表 对象 做任何操作。你只是比原本稍早地丢弃了对它的 引用。当你重新进入循环并将新的数组列表赋值给变量时,你也会丢弃旧的引用。 - azurefrog
请参见 https://dev59.com/hHRB5IYBdhLWcg3wz6UK。 - azurefrog

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接