【问题标题】:Delete an object that was created in an arraylist in a loop Java删除在循环 Java 中的数组列表中创建的对象
【发布时间】:2014-10-19 02:29:59
【问题描述】:

我正在尝试删除我在 ArrayList 中创建的对象:

turtles.add(new Turtle());

我想去掉 ArrayList 中的最后一个海龟,像这样:

turtles.get(turtles.size() - 1) = null;

有什么想法吗?简单地从列表中删除是行不通的,Java 不会让我以上述方式无效。我很确定只有一个对给定 Turtle 对象的引用,因为它们只是以这种方式创建的。

P.S:Turtle 类是一个线程,以防万一。

【问题讨论】:

  • 没有办法“破坏”一个对象。你想完成什么?
  • 是对正在运行的线程的引用,并且您正试图让线程停止执行?
  • 我不再希望该对象存在。基本上只是希望它被垃圾收集。我想我已经回答了我自己的问题,见下文。

标签: java multithreading memory


【解决方案1】:

当没有剩余引用时,JVM 垃圾收集器会自动释放与对象关联的内存。

在这种情况下,将其从列表中删除会非常好,除非您保留了对该对象的另一个引用。

如果您已将此线程传递给要运行的 ExecutorService(或称为 start 方法),那么在 run 方法完成之前它不会被销毁。如果是这种情况,并且您想立即停止线程,则有多种方法可以突破run 方法。

【讨论】:

  • 是的,我调用了start方法。它被设置为运行很多次(我认为是 200000 次)。给它一个布尔标志以在每次运行时进行检查,并在我想摆脱对象并将其从列表中删除时将标志设置为 false。
【解决方案2】:

只需使用ArrayList.remove(int) 喜欢,

turtles.remove(turtles.size() - 1);

turtles 中用于创建单个实例的方法无关紧要,当一个实例不再可访问时,它就有资格进行垃圾回收。

【讨论】:

    【解决方案3】:

    当您使用 = 运算符时,rvalue 会被计算,然后分配给 lvalue
    但是在您的代码中,您期望 lvalue 被评估,这是不可能的。这就是您遇到错误的原因。
    ArrayList 提供了自己的方法来从其列表中删除对象。

    turtles.remove(turtles.size() - 1);

    【讨论】:

      【解决方案4】:

      使用:

      turtles.remove(turtles.size() -1 );
      

      因为:

      turtles.get(turtles.size() - 1) = null;
      

      将不起作用,因为您只能为变量赋值

      .remove(int) 方法从ArrayList 中删除具有指定ID 的对象。 这是.remove() 方法的“描述”:http://docs.oracle.com/javase/7/docs/api/java/util/ArrayList.html#remove%28int%29

      【讨论】:

        【解决方案5】:

        在 JAVA 中,只有对象的创建在我们手中,而销毁它们则由垃圾收集器 (GC) 自行决定。

        当你执行 turtles.add(new Turtle()) 行时,JVM 在 java HEAP 中创建一个新的 Turtle 对象,并将对应的引用添加到 list。

        同样,当您执行 turtles.get(turtles.size() - 1) == null 时,您实际上是在获取对该对象的引用并使引用为 null。您实际上并没有删除该对象。只有 GC 负责删除对象。

        请注意,GC 是一个较低优先级的线程,我们没有任何控制让它启动。但是我们可以使用 System.gc() 请求 GC 启动。

        【讨论】:

          【解决方案6】:

          感谢大家的帮助。

          我尝试过使用

          turtles.remove(turtles.size() -1 );
          

          当它从列表中删除它时,我可以看出线程仍在运行,因为它仍在产生输出。我很确定问题实际上是它正在运行(记住 Turtle 是一个线程),并且在它完成之前不会死。我想我通过给线程一个 isAlive 布尔值来解决这个问题,它在每次调用 run 时检查它,并将其设置为 false,然后在我想删除它时将其从列表中删除:

          turtles.get(turtles.size() - 1).selfDestruct();
          turtles.remove(turtles.size() - 1);
          

          selfDestruct 在哪里执行此操作:

          isAlive = false;
          

          我很确定这有效,我没有看到 perfmon 有任何泄漏。

          【讨论】:

          • 这正是我在回答中所描述的。
          • 是的,你是对的。在其他地方进行更多研究之前,我没有仔细阅读您的答案并且错过了关键部分。我已经投票并接受它作为最佳答案。
          【解决方案7】:

          如果你想在 Java 中销毁一个对象,你只需设置它null:

          object = null;
          

          【讨论】:

          • 试过了。 Java 需要一个命名对象来执行此操作:someTurtle = null;,但因为我的对象是在列表中创建的,所以它没有名称,访问它的唯一方法是使用 ArrayList 的.get(),而这没有工作:turtleList.get(turtleList.size() - 1) = null。 Java 不喜欢这样,我只收到错误消息,即赋值的左侧必须是变量。
          • 你读过这个问题吗?目标是从列表中删除它
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2021-03-24
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-11-05
          • 2017-04-13
          相关资源
          最近更新 更多