Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/list/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 重新实例化列表或调用clear()的更好实践_Java_List - Fatal编程技术网

Java 重新实例化列表或调用clear()的更好实践

Java 重新实例化列表或调用clear()的更好实践,java,list,Java,List,使用Java(1.6)对列表调用clear()方法更好,还是只是重新实例化引用 我有一个ArrayList,其中填充了未知数量的对象,并定期“刷新”——处理对象并清除列表。刷新后,列表将再次填充。冲洗在随机时间进行。列表中的数字可能较小(10个对象)或较大(数百万个对象) 那么,使用“flush”调用clear()还是新的ArrayList()更好呢 这类问题值得担心吗?还是应该让虚拟机来担心?我怎样才能通过查看Java的内存占用来解决这类问题呢 非常感谢您的帮助。需要关注的主要问题是,还有哪些

使用Java(1.6)对列表调用clear()方法更好,还是只是重新实例化引用

我有一个ArrayList,其中填充了未知数量的对象,并定期“刷新”——处理对象并清除列表。刷新后,列表将再次填充。冲洗在随机时间进行。列表中的数字可能较小(10个对象)或较大(数百万个对象)

那么,使用“flush”调用clear()还是新的ArrayList()更好呢

这类问题值得担心吗?还是应该让虚拟机来担心?我怎样才能通过查看Java的内存占用来解决这类问题呢


非常感谢您的帮助。

需要关注的主要问题是,还有哪些代码可能引用了该列表。如果现有列表在别处可见,您希望该代码看到已清除的列表,还是保留现有列表

如果没有其他人可以看到这个列表,我可能会清除它——但不是出于性能原因;只是因为您描述操作的方式听起来更像是清除,而不是“创建一个新列表”

ArrayList
文档没有指定底层数据结构会发生什么情况,但是看看Eclipse中的1.7实现,您可能应该在
clear()
之后调用
trimToSize()
——否则您仍然可以拥有一个由大量空引用支持的列表。(当然,这对您来说可能不是问题……也许这比在阵列大小再次增大时复制阵列更有效。您将比我们了解更多。)


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

我认为如果Arraylist被频繁刷新,例如,如果它是在循环中连续运行的,或者更好地使用clear,如果刷新不太频繁,那么您可以创建一个新实例。此外,由于您说元素可能从10个对象到数百万个不等,您可以为您创建的每个新Arraylist选择介于两者之间的大小,以便Arraylist可以避免大量调整大小时间

您使用它的方式与a的使用方式非常相似。当您处理队列中的项目时,它们将在您处理它们时被删除

使用其中一个队列类可能会使代码更加优雅


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

list.clear()与new XXList相比没有任何优势。 这里是我的调查,以比较性能

            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
            */
import java.util.ArrayList;
导入java.util.List;
公共类清除列表{
公共静态void testClear(int m,int n){
列表=新的ArrayList();
长启动=System.currentTimeMillis();
for(int i=0;i
可见性不是问题。我喜欢你对清晰方法的推理,因为它有助于描述正在发生的事情。我以前从未见过trimToSize()-我也会检查一下,你是说“1.7实现”吗?当然Eclipse不支持Java1.7(因为它还没有推出),或者我误解了它。@Phil:我使用的是Build1.7.0-ea-b78。它是这个系统上唯一的JVM。尽管它还没有发布,但已经有很多年的版本了,Eclipse在它上面运行,我没有看到任何问题。我想知道:我过去常常清除列表,然后将其设置为null——但这只是因为我不完全确定如果直接将列表设置为null会发生什么(该列表中的所有元素是否都自动设置为null?),而不首先清除它。我想确保没有任何列表元素保持“挂起”@Zainodis:这完全取决于是否有其他对同一对象的引用。但是你当然不需要清除列表或将变量设置为null,前提是该变量没有在其他地方使用。将变量设置为null对列表没有任何作用-它只是一个变量。别忘了,可能还有其他对列表的引用相同的列表。请注意Jon关于优化部分的回答-如果您处理的是高强度,并且存在缓慢性,那么请对其进行分析。如果问题很明显,那么您可以轻松测试将其更改为创建一个新列表。但是,否则,请使用语义上最正确的内容-即代码实际尝试的内容是否与绩效相关: