2010-06-03 50 views
1

我有一系列的項目到達了我的數據結構中的一個,我需要一種方法來跟蹤那些保留的項目。Java:自動過濾列表?

interface Item {} 
class Foo implements Item { ... } 
class Baz implements Item { ... } 

class StateManager 
{ 
    List<Foo> fooList; 
    Map<Integer, Baz> bazMap; 

    public List<Item> getItems(); 
} 

我想的是,如果我做到以下幾點:

for (int i = 0; i < SOME_LARGE_NUMBER; ++i) 
{ 
    /* randomly do one of the following: 
    * 1) put a new Foo somewhere in the fooList 
    * 2) delete one or more members from the fooList 
    * 3) put a new Baz somewhere in the bazMap 
    * 4) delete one or more members from the bazMap 
    */ 
} 

那麼,如果我做出StateManager.getItems()的調用,我想回到那些Foo和巴茲項目列表,它們在fooList和bazMap中按照它們添加的順序找到。從fooList和bazMap刪除或移動的項目不應位於返回的列表中。

我該如何實現? SOME_LARGE_NUMBER足夠大,我沒有可用的內存來保留所有Foo和Baz項目,然後過濾它們。


編輯:這似乎很難,因爲我真的不希望Foo類或類巴茲有一個插入索引的任何意識,我想的辦法是可擴展的,這樣我就不會必須讓StateManager知道它。

我也許想使用裝飾爲列表<的>和地圖<>在fooList和bazMap使用,每個都具有到主列表<基準的裝飾在getItems()>返回,從而使裝飾會默默地做所有的工作。

也只是爲了清楚起見,我們假設在fooList和bazMap的操作是:

fooList.add(foo1); 
bazMap.put(3, baz1); 
fooList.add(foo2);  
fooList.add(foo3); 
bazMap.put(10, baz2); 
bazMap.put(4, baz3); 
fooList.set(1, foo4); 
bazMap.put(7, baz4); 
bazMap.put(3, baz5); 
fooList.add(foo5); 
bazMap.put(7, baz6); 
fooList.set(0, foo6); 
bazMap.put(4, baz7); 
fooList.add(foo1); 

然後通過getItems返回的列表應該

[foo3, baz2, foo4, baz5, foo5, baz6, foo6, baz7, foo1] 

月底以來fooList = [foo6,foo4 ,foo3,foo5,foo1]和最終的bazMap = {10:baz2,4:baz7,3:baz5,7:baz6}。項目foo1,baz1,foo2,baz3和baz4都被移位(在最後一步添加foo1)

回答

0

我不明白過濾的來源。如果您要刪除步驟2和4中的項目,是不是被隱式過濾?

如果您問如何將兩個集合合併到一個列表中,那很簡單。

List<Item> items = new ArrayList<Item>(fooList.size() + bazMap.size()); 
items.addAll(fooList); 
items.addAll(bazMap.values()); 

也許你可以詳細說明「按順序添加」部分。 fooList可以很容易地擁有該屬性,但bazMap的順序可能不會擁有該屬性。如果你的意思是添加了foo,那麼baz,然後foo,並且你需要最終的結果集合以相同的順序進行,但這仍然更加複雜。

+0

如果我做fooList.set(K,someFoo),它會清除該列表中的老項目。另外,是的,如果按順序添加的項目是[Foo foo1,Baz baz1,Baz baz2,Foo foo2,Foo foo3],那麼我需要保持該順序。 – 2010-06-03 15:02:59

1

我不明白正在尋找什麼。如果問題是維持Foos和Bars的插入順序,那麼您可以將它們的索引(i存儲在您的循環中),並根據該順序對它們進行排序,可以通過排序列表或通過TreeMap或其他東西進行排序。另一種選擇是使用LinkedHashMap(同樣使用key的索引)來維護插入順序。

+0

這是有幫助的...雖然我不想將索引包含在對象本身中。 – 2010-06-03 15:03:56

+0

您是否在乎能否快速刪除元素?如果你也許知道未刪除的元素只有很少,你可以通過線性時間刪除來獲得。否則,你需要存儲一些你知道元素位置的東西(在插入順序列表中),這樣你就可以快速刪除它,可以是索引,或者是一個列表節點的引用等。 – 2010-06-03 15:29:49

+1

嗯,我見下文,你_do_關心避免線性時間刪除! :) 您是否看到LinkedHashMap建議?我在最初的答案後幾分鐘添加了它。這將使O(1)刪除,而不是O(logn)使用TreeMap。它確實存儲額外的狀態來做到這一點 - 每個元素都有一個對錶示插入順序的列表的引用。 – 2010-06-03 15:34:40

0

將項目添加到單獨的項目主列表中,並從主列表和類型特定的數據結構中刪除項目。

for (int i = 0; i < SOME_LARGE_NUMBER; ++i) 
{ 
    /* randomly do one of the following: 
    * 1) put a new Foo somewhere in the fooList 
    * 1a) put a new Foo at the end of masterList 
    * 2) delete one or more members from the fooList 
    * 2a) delete the same members from the masterList 
    * 3) put a new Baz somewhere in the bazMap 
    * 3a) put a new Baz at the end of masterList 
    * 4) delete one or more members from the bazMap 
    * 4a) delete the same members from masterList 
    */ 
} 
+0

,這將工作,我猜,但從列表<>刪除項目是O(N)不是嗎? – 2010-06-03 15:00:54

+0

不,它不起作用,因爲步驟(1)和(3)可能涉及將一個新項目放在舊項目存在的位置,所以被移動的舊項目必須從masterList中移除。 – 2010-06-03 15:09:20