3

我有一个添加到几个不同 ArrayLists 的对象。我想避免更改每个列表,所以我试图更改指针,以便所有列表都更改。但是如果我想将对象设置为空,我就无法让它工作。例如:

ArrayList<Point> list1 = new ArrayList<Point>();
ArrayList<Point> list2 = new ArrayList<Point>();
Point a = new Point(2, 3);
list1.add(a); list2.add(a);

此时,两个列表都有一个指向同一个对象的项目。值为“2, 3”。如果我改变对象的值。然后两个列表都发生了变化:

a.set(5,5);

现在两个列表都有一个值为“5, 5”的项目。但是,如果我尝试将值设置为 null。

a = null;

现在a设置为null,但两个列表的对象仍然是“5, 5”而不是我想要的null。我什至尝试向Point该类添加一个方法以将其设置为 null。但我也无法让它发挥作用。我可以做些什么来通过仅更改指针来删除所有列表上的对象?

4

5 回答 5

5

您可以更改引用变量持有的对象的状态,这将反映在引用同一对象的所有变量中,但如果您更改引用变量的分配,它只会影响该变量。所指的对象没有改变——正如预期的那样。

于 2012-04-06T02:39:43.733 回答
2

在 Java 中,您不能从其“指针”(更准确地说是“引用”)中删除对象。当一个对象被取消引用(意思是:没有指向它的引用)它成为垃圾回收的候选对象;Java 的垃圾收集器会自动为您删除对象,没有free()像其他语言(想到 C/C++)那样您必须手动管理内存的操作。

关于您的问题:您可以使用remove()in 方法从两个列表中删除对象ArrayList,或者手动将对象设置为null给定索引 ( list.set(index, null)) 的列表中,但是无法通过设置外部引用来删除对象(那些在列表)到null

于 2012-04-06T02:49:15.153 回答
1

最简洁的答案是不'。您不能通过更改指向对象的指针来更改对象的内容。

一个=空;只是清除指针,而不是对象。

于 2012-04-06T02:38:41.133 回答
1

正如其他人所提到的,没有简单的方法可以满足您的要求。你可以做的,我不推荐这样做,是WeakReference在你的 s 中使用Lists。弱引用不会阻止您Point被垃圾收集。

List<WeakReference<Point>> list = new ArrayList<>();
Point p = new Point();
list.add(new WeakReference<>(p));
System.out.println(p);
System.out.println(list.get(0).get());

p = null;

System.gc(); System.gc(); System.gc(); System.gc(); // hopefully the GC collects p by now

System.out.println(list.get(0).get()); // null!

只需手动从您的两个removes .PointList

于 2012-04-06T03:22:00.820 回答
1

我可以做些什么来通过仅更改指针来删除所有列表上的对象?

没有。你不可能那样做。如果要将列表中对对象的引用设为空(或将它们从列表中删除),则必须对每个列表执行操作。

如果您无法修改列表,请考虑以下替代方案:

  1. 使用Point具有额外字段的不同类,该字段说明该点是否“有效”,并让正在查看列表的代码检查此字段。

  2. 创建一个自定义类,该类表示对 Point 的可为空引用;例如

      public class PointRef {
          private Point p;
          public PointRef(Point p) { this.p = p; }
          public Point get() { return p; }
          public void invalidate() { p = null; }
      }
    
      ArrayList<PointRef> list1 = new ArrayList<PointRef>();
      ArrayList<PointRef> list2 = new ArrayList<PointRef>();
      PointRef a = new PointRef(new Point(2, 3));
      list1.add(a); list2.add(a);
    
      ...
    
      a.invalidate;
      // Now both lists contain hold a PointRef that points to a null Point.
    

但是这两者都使得使用列表及其包含的 Point 对象变得更加复杂。

(@Jeffrey 的回答建议使用WeakReference该类,但这具有错误的语义。特别是,如果 GC 检测到没有对该对象的强引用,该引用将“中断”。这不是您的用例所要求的......如果我正确理解你的问题。)


顺便说一句,我想不出任何一种编程语言可以让你按照你建议的方式去做你想做的事情。

于 2012-04-06T03:42:55.237 回答