【问题标题】:Will this work like a destructor?这会像析构函数一样工作吗?
【发布时间】:2018-06-12 22:59:41
【问题描述】:

我正在开发用于布朗运动跟踪的处理程序。

我有一个 ArrayList blobs 和 ArrayList tomerge。第一个是我跟踪的粒子列表,第二个是我要合并的粒子列表。

每个粒子都是一个 Blob 类对象。 Blob 对象在其数据中包含称为 lespoints 和 int id 的向量的 ArrayList。

由于我需要将几个粒子合并为一个,我需要销毁一些 Blob 对象,但是 Java 没有任何析构函数,我不想使用 finalise()。这会像合并 + 破坏一样工作吗?

 public void delete(Blob a)
 {
   a = null;
 }

   void merge(ArrayList<Blob> tomerge)
   {

    int i = 0;
    int j = 0;

   while (i <= tomerge.size())
   {
     Blob k = new Blob();
       k = tomerge.get(i);
     while (j <= tomerge.get(i).siz()) {
       Vector g = k.lespoints.get(j);
      lespoints.add(g);
      j++;
     }
     if (i > 0)
     {
       delete(tomerge.get(i));
     }
     i++;
   }
   }

【问题讨论】:

  • 是的,只需从 ArrayList 中删除合并的 blob,Garbage Collect 就会在适当的时候捡起它们
  • 你的delete 函数没用,永远不会做任何事情。它复制一个引用并将副本清空
  • 我只是需要修复这个问题的代码格式,它伤害了我的眼睛

标签: java processing


【解决方案1】:

您无需手动执行任何操作。只需确保您没有对要删除的变量的任何引用,其余的将由 Java 处理。

例如:

String x = "test";
x = null;

此时,值"test" 可以被垃圾回收,因为没有任何东西指向它。

对比一下:

String x = "test";
ArrayList<String> list = new ArrayList<>();
list.add(x);
x = null;

此时,"test" 的值无法被垃圾回收,因为ArrayList 仍然指向它。

但如果你这样做:

list.remove("test");

然后它可能会被垃圾收集。

所以基本上,您需要做的就是从您的ArrayList 中删除该元素,然后Java 会处理剩下的事情。请注意,您可能不想在当前循环中执行此操作,因为在迭代列表时删除元素可能会导致您跳过元素。

相反,您可能想要使用迭代器或只是在 ArrayList 上向后循环。

无耻的自我推销:here 是关于 ArrayLists 的教程,包括从中删除元素。

【讨论】:

  • +1 我们可以忽略字符串文字将被实习的例子,在这些情况下,“test”实际上不会被 GCed
  • 我正在考虑否决这个。当您使用数字索引遍历它时,您不应该这样做 list.remove("test"),因为您最终会跳过值。最好使用迭代器,并通过迭代器删除值。或者,如果您不介意在列表中留下空白,您可以将它们设置为 null。
  • @DawoodibnKareem Downvote 如果你愿意,但请注意,我的答案中的所有代码都是一个独立的示例。我没有在我的任何代码中进行任何迭代。
  • @DawoodibnKareem 实际上我刚刚编辑了我的答案,提到在迭代它时从 ArrayList 中删除该项目。
  • @DawoodibnKareem 请注意这是一个processing 问题。我故意选择不提迭代器。另请参阅:Processing != Java。但我们非常欢迎您发布自己的答案。
【解决方案2】:

您的代码示例无法运行的确切原因。

public void delete(Blob a)
{
    a = null;
}

Blob b = new Blob();
delete(b);

在此代码示例中,设置为nullreferencea,而不是b

您不是在删除Blob 对象,而是在设置对null 的引用。

当调用delete()方法时,存在2个对Blob的引用。

一个引用是b,在调用代码中。

另一个引用是a,在被调用代码中。

a 设置为 null,然后方法退出。但是b 引用始终存在。因此,Blob 永远不会被垃圾回收。

要实现垃圾回收,您必须删除对对象的所有引用;然后它会在 JVM 方便时被销毁。


用于在迭代期间删除对象的 Java Collections API 的工作方式如下:

Iterator<Blob> itr = list.iterator();
while( itr.hasNext() ) {
    Blob b = itr.next();
    if( /* test condition */ ) {
        itr.remove();  // Safely removes object from List during iteration
    }
} // Object `b` goes out of scope, and so this Blob is "lost" to the the code and is going to be destroyed

【讨论】:

    猜你喜欢
    • 2015-02-10
    • 1970-01-01
    • 1970-01-01
    • 2012-09-06
    • 2013-08-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-05-19
    相关资源
    最近更新 更多