2012-04-09 52 views
5

假設我有一個List<Person> all數據結構,其中Person被定義爲:java的模式,以保持一致的數據索引集合中

class Person { 
    String firstName; 
    String secondName; 
    boolean hasValidDrivingLicense; 
} 

我想十個分量冗餘List<Person> drivers只包含人說擁有有效的駕駛執照。我認爲它也可以被看作是一個指數(一個指數將包含所有的項目,但目的非常相似)。
這是爲了避免每次需要這些數據時都需要遍歷整個列表。
(每次循環都有一個好處,就是我擁有我的hasValidDrivingLicense信息的單一權威性表示;放棄這條路需要:a)有效的理由b)經過測試的替代方案。原因取決於具體問題;另一種方法是什麼,我在這裏發展:-))
問題
我可能有這樣的事情:

void add(Person p) { 
    all.add(p); 
    if (p.hasValidDrivingLicense()) { 
     drivers.add(p); 
    } 
} 

這往往工作。

Person p = new Person(); //then set fields, of course. 
add(p); 
p.setHasValidDrivingLicense(true); 

這裏沒有。 所以問題是:冗餘信息可能會不一致。索引可能「爆發」。

解決方案

  1. 人的hasValidDrivingLicense財產實行可觀察設計模式(或發佈訂戶,在揮杆什麼是基於監聽器接口) 如果對象可以改變,我想我的指數將上升與他們的更改,我需要一種方式來通知索引mantainer一個對象已更改相關的屬性。可觀察似乎是一個確定的解決方案。沒有關於它的問題。
  2. 人是不可改變的

問題

不變性似乎是一個可行的解決方案,但是,從收集的維護者一點,那就是誰寫代碼的人:

public void add(Person p) { 
    ... 
} 

必須確保p不變或更好,至少hasValidDrivingLicense是最終的。

a)這可以通過反射來完成(http://stackoverflow.com/questions/203475/how-do-i-identify-immutable-objects-in-java) 但是這不需要一個新的績效評估?不反射是否有成本?

b)有沒有,也許在設計模式或語言的新功能(eg.annotations)這個問題的其他解決方案?

+0

@路易Wasserman這是我最好的。我認爲設計問題比實際問題難得多。不過,當我認爲設計問題非常重要時,我試着用一個簡單的例子來放下。在這裏,我感興趣的不是要排隊的收藏品,如果司機不包含「全部」的所有元素,他們怎麼可能?可能它們可能有相同的順序......但這不是一個請求。請求是真實的:如何確保一致性。改變項目狀態可能會破壞一致性。索引與實際數據之間。 – AgostinoX 2012-04-09 17:18:49

+0

我建議重新訪問單個列表計劃並根據需要創建子列表。 – samlewis 2012-04-09 17:40:05

回答

2

我想你想要的是一個「活」已過濾查看你的全部集合。

這可以很好地與谷歌番石榴和謂詞來完成:

http://docs.guava-libraries.googlecode.com/git-history/v11.0.2/javadoc/com/google/common/collect/Collections2.html#filter%28java.util.Collection,%20com.google.common.base.Predicate%29

在另一方面,剛剛實現列表personsWithDriversLicens(){...}也容易,所以也許番石榴是過度殺傷 - 取決於您的需求,包括性能特點。

相關問題