2015-05-26 93 views
3

请考虑下面的代码:通过指针检测对象删除

ArrayClass<someClass> list = new ArrayList<someClass>(); 
//Consider this list has been filled somewhere else 

someClass selectedObject = null; 

public void userAction(float x, float y){ 
    selectedObject = findObject(x, y); 
} 

public someClass findObject(float x, float y){ 
    for(int i=0; i<list.size(); i++) 
     if(--objects match--) 
      return list.get(i); 

    return null; 
} 

的问题是,我使用的selectedObject别的地方,我需要知道它所指向的对象仍然存在。我注意到,当selectObject指向的列表中的对象被删除时,selectedObjects会保留它用来指向的对象的属性(该对象不再存在)。一旦对象从列表中删除,我需要selectedObject指向null。我怎样才能做到这一点?

编辑1:澄清,发布代码的作品,这不是问题。问题在于指针selectedObject在它指向列表中的对象被删除时未被更新。还有一件事,我无法访问从列表中删除对象的方法。

+0

我没有看到你的代码的任何问题 - 它只是你的逻辑问题。你在哪里说把对象设置为null?你所描述的既是有效的,也是可以实现的,但是没有看到你现在正在做什么,我不能告诉你,如果你做错了。 – Aify

+0

您需要将对象的删除和selectedObject的保留封装到一个类中。从列表中删除对象的方法还需要检查它是否是当前选定的对象,并且如果是这种情况,则将字段'selectedObject'设置为null。 –

回答

0

如果你把一个对象在List,该JVM将保持一个对象和两个引用,所以,如果你需要确保selectedObject为空,只是分配null它时发现:

public someClass findObject(float x, float y){ 
    for(int i=0; i<list.size(); i++) { 
     if(--objects match--) { 
      selectedObject = null; 
      return list.get(i); 
     } 
    } 
    return null; 
} 

想想这个:在你的代码,因为你至少需要一个恢复它,你将永远无法抹去的对象的所有的所有引用....

+0

这种方式你需要每次调用findObject。 OP想要调用一次findObject(),不要再调用它,我想。 – walkeros

3

如果你让selectedObject弱引用,你可以做到这一点:

WeakReference<someClass> selectedObject = null; 

分配:

selectedObject = new WeakReference<someClass>(findObject(x, y)); 

查询:

someClass v = selectedObject.get(); 

selectedObject的get()如果该项目从列表中删除(而不是由任何其他的 “指针” 引用的方法将返回null )

+1

只有当垃圾收集器从堆中移除实际的对象(由WeakReference调用)时,这才会起作用。当实例从列表中移除但仍然堆在堆上时,这将不起作用,所以在我看来这不是解决方案。 – walkeros

+0

walkeros是对的,这并不能解决问题。 – AmiguelS

+0

就像我在答案中提到的 - 如果删除的项目没有被任何其他变量引用,这将工作正常。现代垃圾收集器非常快速地清除年轻一代堆。无论如何,这是Java提供的最佳解决方案。任何其他解决方案都必须在应用程序级别上。您可以保存对列表和所选对象的引用,然后查询列表,如果所选对象仍在其中。 –

0

您可以创建一个包装类,它将在您每次访问实例时检查列表:

class WrapperClass { 

    private final List<SomeClass> list; 
    private final float x; 
    private final float y; 


    WrapperClass(List<SomeClass> list, float x, float y) { 
     this.list = list; 
     this.x = x; 
     this.y = y; 
    } 

    SomeClass get() { 
     return findObject(); 
    } 

    private SomeClass findObject(){ 
     for(int i=0; i<list.size(); i++) 
      if(object_match(x, y) { 
       return list.get(i); 
      } 

     return null; 
    } 

} 

而且比你叫它:

WrapperClass wp = new WrapperClass(list, 1, 2); 
    System.out.println(wp.get()); // returns instance contained in the list 

    list.clear(); 

    System.out.println(wp.get()); // returns null 
+0

这种方式你需要每次调用findObject。 OP想要调用一次findObject(),不要再调用它,我想。 –

+0

@sharonbn至少调用findObject()在后台工作,但我同意这个解决方案远不是完美的 – walkeros