Java 如何从指针中删除对象?

Java 如何从指针中删除对象?,java,Java,我在几个不同的ArrayList中添加了一个对象。我想避免更改每个列表,所以我尝试更改指针,以便所有列表都会更改。但是如果我想将对象设置为null,我就不能让它工作。例如: ArrayList<Point> list1 = new ArrayList<Point>(); ArrayList<Point> list2 = new ArrayList<Point>(); Point a = new Point(2, 3); list1.add(a);

我在几个不同的ArrayList中添加了一个对象。我想避免更改每个列表,所以我尝试更改指针,以便所有列表都会更改。但是如果我想将对象设置为null,我就不能让它工作。例如:

ArrayList<Point> list1 = new ArrayList<Point>();
ArrayList<Point> list2 = new ArrayList<Point>();
Point a = new Point(2, 3);
list1.add(a); list2.add(a);
现在两个列表都有一个值为“5,5”的项。但是如果我尝试将值设置为null

a = null;

现在
a
设置为null,但是两个列表中的对象仍然是“5,5”,并且不像我想要的那样为null。我甚至尝试向
类添加一个方法,将其自身设置为null。但我也不能让它发挥作用。如何通过仅更改指针来删除所有列表上的对象?

简短的回答是“否”。不能通过更改指向对象的指针来更改对象的内容


a=零;只需清除指针,而不是对象。

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

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


关于您的问题:您可以使用
ArrayList
中的
remove()
方法从两个列表中删除对象,或者在给定索引的列表中手动将对象设置为
null
list.set(index,null)
),但无法通过设置外部引用来删除对象(列表之外的)到
null
正如其他人所提到的,没有简单的方法来完成你的要求。你能做的,我不建议这样做,就是在你的
列表中使用。弱引用不会阻止你的
点被垃圾收集

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!
List List=new ArrayList();
点p=新点();
增加(新的WeakReference(p));
系统输出println(p);
System.out.println(list.get(0.get());
p=零;
System.gc();System.gc();System.gc();System.gc();//希望gc现在收集到p
System.out.println(list.get(0.get());//null!
只需手动从两个
列表中
删除
,就可以轻松得多

我可以通过仅更改指针来删除所有列表上的对象吗

什么都没有。你无法做到。如果你想使列表中对象的引用为空(或从列表中删除它们),你必须对每个列表执行操作

如果你不能修改列表,那么考虑下面的备选方案:

  • 使用另一个
    类,该类有一个额外字段,说明该点是否“有效”,并让查看列表的代码检查该字段

  • 创建一个自定义类,该类表示对一个点的可空引用;例如

      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.
    
    公共类PointRef{
    私人点p;
    公共点ref(点p){this.p=p;}
    公共点get(){return p;}
    public void invalidate(){p=null;}
    }
    ArrayList list1=新的ArrayList();
    ArrayList list2=新的ArrayList();
    PointRef a=新PointRef(新点(2,3));
    列表1.添加(a);列表2.添加(a);
    ...
    a、 使无效;
    //现在,两个列表都包含一个指向空点的hold PointRef。
    
  • 但这两种方法都使列表及其包含的点对象的使用更加复杂

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



    顺便说一句,我想不出有哪种编程语言能让你按照你的建议去做你想做的事情。

    从技术上讲,在Java中,它不是一个“指针”,而是一个“引用”。但是,无论哪种方式,更改指针/引用都不会更改对象,就像更改电话号码会更改头发的颜色一样。我认为部分问题在于Java中没有删除对象这样的事情。您只需等待对象被删除。因此,除了设置每个列表的元素单独为空?是的。除非您有一个列表对象,并且有一堆列表变量引用同一个列表对象。我不确定我是否理解,您能否对此进行扩展?这是我们已经讨论过的内容的扩展。列表变量是一个引用变量,您可以有多个引用变量refe指向同一列表对象。如果从列表中删除对象,则会更改其状态,该状态将反映在引用同一列表对象的所有引用变量中。仅此而已。
      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.