Java 如何从指针中删除对象?
我在几个不同的ArrayList中添加了一个对象。我想避免更改每个列表,所以我尝试更改指针,以便所有列表都会更改。但是如果我想将对象设置为null,我就不能让它工作。例如: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<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.