2015-05-26 129 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