关于java:更好的做法是重新实例化List或调用clear()

Better practice to re-instantiate a List or invoke clear()

使用Java(1.6)更好地在List上调用clear()方法还是重新实例化引用?

我有一个ArrayList,其中填充有未知数量的对象,并定期"刷新"-处理对象并清除列表。刷新后,列表将再次填满。刷新发生在随机时间。列表中的数字可能较小(10个对象)或较大(数百万个对象)。

因此最好使用" flush "调用clear()或new ArrayList()吗?

是否值得担心此类问题,还是让VM担心呢?我该如何看待Java的内存占用,以便自己完成这种事情?

任何帮助都将不胜感激。


主要要关心的是其他哪些代码可能引用了该列表。如果现有列表在其他位置可见,您是否希望该代码查看已清除列表,还是保留现有列表?

如果没有其他可以看到的列表,我可能会清除它-但不是出于性能原因;仅仅因为您描述操作的方式听起来比"创建新列表"更像是清除。

ArrayList<T>文档未指定底层数据结构会发生什么,但是在Eclipse中的1.7实现中,您似乎应该在clear()之后调用trimToSize(),否则您仍然可以使用由大量空引用支持的列表。 (当然,也许这对您来说不是问题,...也许比在再次建立大小时复制数组要更有效。您会比我们更了解这一点。)

(当然,创建新列表并不需要旧列表将所有数组元素设置为null ...,但我怀疑这在大多数情况下是否有意义。)


您使用它的方式非常类似于使用队列的方式。当您处理队列中的项目时,在处理它们时会将其删除。

使用其中一个Queue类可能会使代码更优雅。

还有一些变体以可预测的方式处理并发更新。


list.clear()没有比新的XXList更好的了。
这是我比较性能的调查。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
            import java.util.ArrayList;
            import java.util.List;

            public class ClearList {


                public static void testClear(int m, int n) {
                    List<Integer> list = new ArrayList<>();
                    long start = System.currentTimeMillis();

                    for (int i = 0; i < m; i++) {
                        for (int j = 0; j < n; j++) {
                            list.add(Integer.parseInt("" + j + i));
                        }
                        list.clear();
                    }

                    System.out.println(System.currentTimeMillis() - start);
                }

                public static void testNewInit(int m, int n) {
                    List<Integer> list = new ArrayList<>();
                    long start = System.currentTimeMillis();

                    for (int i = 0; i < m; i++) {
                        for (int j = 0; j < n; j++) {
                            list.add(Integer.parseInt("" + j + i));
                        }
                        list = new ArrayList<>();
                    }

                    System.out.println(System.currentTimeMillis() - start);
                }

                public static void main(String[] args) {
                    System.out.println("clear ArrayList:");
                    testClear(991000, 100);
                    System.out.println("new ArrayList:");
                    testNewInit(991000, 100);
                }

            }


            /*--*
             * Out:
             *
             * clear ArrayList:
             * 8391
             * new ArrayList:
             * 6871
            */

我认为如果Arraylist的刷新频率太高,例如它在循环中连续运行或某些事情,那么如果刷新不是太频繁,最好使用clear来创建一个新实例。从10个对象到数百万个对象,您可能可以为创建的每个新Arraylist设置一个介于中间的大小,这样该arraylist可以避免大量时间调整大小。