【问题标题】:Is there a way to clear arraylist but not deference the memory reference?有没有办法清除 arraylist 但不尊重内存引用?
【发布时间】:2020-01-26 16:01:21
【问题描述】:

这是我的代码的相关部分:

    List<List<String>> list2 = new ArrayList<>();
    public void process(List<String> z) {
        if (z.size() > 0) {
            String x = z.get(0);

            List<String> temp = new ArrayList<>();

            z.stream().filter(e -> !e.equals(x)).forEach(e -> {
                // some operations on temp
            });

            list2.add(temp);                   // adding temp to list2

            z.removeIf(e -> temp.contains(e));
            temp.clear();                      // clearing temp

            z.forEach(System.out::println);
            list2.forEach((System.out::println));   // empty list2

            process(z);
            list2.forEach(e -> process(e));
    }

在递归调用 process 之前,我必须清除 temp。
这里的问题是,我的list2 在清除temp 后变为空。
当我在 lambda 表达式中使用 temp 时,我无法将其重新分配为 nullnew ArrayList&lt;&gt;() (否则它会起作用)。

我想创建一个新列表并在临时列表和新列表之间复制,但感觉不是一个合适的方法。
有没有其他方法可以做到这一点?

【问题讨论】:

  • "我必须在递归调用 process 之前清除 temp。" - 为什么?
  • @DHS 没有理由。 temp 引用同样存储在 list2 中的列表有什么影响?
  • temp 是一个局部变量。每个递归调用都有自己的temp 副本。无需清空它。事实上,循环的每次迭代都会有一个新的temp-变量。
  • z.removeIf(e -&gt; temp.contains(e))z.removeAll(temp) 的效率较低的版本。一般来说,你似乎有过度使用 lambda 表达式的习惯。
  • 只知道 API 是不可能的……

标签: java arraylist collections garbage-collection


【解决方案1】:

虽然这个答案解决了在另一个列表中清除列表的问题,但真正的答案是在 Turing85's comment 中,因为 temp 是本地的,所以不需要清除 temp


如果您想清除temp 而不清除您在list2 中插入的该列表中的条目,则不能将temp 插入list2 然后清除temp,因为@987654329 @ 和 list2 中的条目都指向 same 列表。

相反,插入一个副本:

list2.add(new ArrayList<>(temp));

那么当你清除temp时,你在list2中的新列表将不受影响。

【讨论】:

  • @DHS - 我的荣幸。不过,Turing85 有一个很好的观点,你可能不需要清除 temp 反正... :-)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-01-06
  • 1970-01-01
  • 1970-01-01
  • 2022-01-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多