2013-08-22 22 views
4

我正在尋找一個基於元素屬性的查找的Set實現。以番石榴術語思考,可以使用Function<Element, SearchKey>(預計在所有集合元素中是唯一的)構建,並提供返回Element的方法find(SearchKey key),其功能將返回keyJava中的「IndexedSet」,「MapSet」或「SetMap」實現

明顯假設將需要滿足:

  • function(element)結果對element在集合整個生存期內保持不變。
  • 函數給出了所有元素集合
  • 獨特結果

原因是:
有時有必要對Set<Element>和場類型不能在JPA實體或在4RD的情況下被改變爲Map<SearchKey, Element>(像黨代碼)。儘管如此,當構建這樣一個對象時,人們可以安全地使用自己的Set實現類似Map的功能。

替代方案:

有一些替代方案,我已經發現,其中沒有一個似乎完全沒有

  • Map般的功能 - 使用線性搜索find(SearchKey)實現(與每位Set執行:)
  • 使用TreeSetComparator比較SearchKeys - 有點像破解,尤其是這不再尊重元素平等
    「查找」方法被調用ceiling,並要求您構建人工Element用於查找目的(uogh ...)
  • 「等價設置」(http://code.google.com/p/guava-libraries/issues/detail?id=576) - 但是,不落實,不似乎將是

如果你想回答,你不知道有更多的選擇 - 節省您的時間和沒有。這是我已經知道的東西,我將無法接受你的答案。)

+3

您是否肯定需要一個* single *對象來擔任這兩個角色,或者您是否擁有該集合,然後將其分別索引'Maps.uniqueIndex'?您始終可以創建自己的類型,使用該構思與組合和委派相結合,從一個對象中公開兩組接口。 –

+0

那麼你的理由部分說,你爲什麼仍然需要一個'集合' - 它並不能解釋爲什麼你不能*都*。 –

+0

你的意思是子類化一個'HashSet',並有一個額外的「索引」字段作爲地圖並由我自己管理?會做,但仍然有點容易出錯。 –

回答

1

我必須缺少一些東西,否則通過ForwardingSetHashBiMap.keySet()很容易。我的trivial implementation只關心addaddAll,所有其他的東西應該沒有任何努力。沒有單一測試,我建議使用Guava testlib。

+0

不錯。雖然不是圖書館:) –

+0

但幾乎...「BiMap」完成了幾乎所有的工作。你可以試圖說服番石榴傢伙增加這個功能,但我很懷疑,因爲我從來沒有聽說過任何人需要它。雖然我確定,但很久以前我還想要這個。 – maaartinus

2

我正在尋找一個基於元素屬性提供查找的Java實現。

這是一個地圖是和什麼,你需要建立一個關鍵的對象來表示如果被擡起。

這是Java中最簡單,更高效的解決方案,所以雖然稍微不愉快,但我不擔心它。

順便說一句:集合通常實現爲JRE中一個Map上的圖層,這不是理想的IMHO。

+0

不幸的是'Map'沒有'add(Element)'方法來計算調用者的密鑰。此外,我想我已經說過,我僅限於'Set '作爲'Map'沒有實現AFAIK的數據類型。在我*可以更改*數據類型的情況下 - 我全都和你在一起,理智和「地圖」。 –

+0

寫這樣一個方法或者Map的子類有多複雜?如果自己推導一個密鑰非常困難,我建議改變你的模型,否則它不會。爲什麼你僅限於給定集合有完全相同的方法。 –

+0

你是對的! 'IndexedCollection'也可以。有沒有現有的實施?如果沒有,我會留在我的解決方法 - 樹「TreeSet」。 –

1

如果我正確理解你的問題,2層的替代品來我的腦海:

  1. 你砍的一種變體:用與YourElement比較YourSearchKey比較一個TreeSet。您可以欺騙類型系統,或創建一個通用接口YourAbstractSearchKey。唯一的缺點是:
    • YourSearchKey對象可以插入SetCollections.checkedSet()可以幫助在這一點上。
    • 搜索結果很可能需要轉換爲YourElement。解決方法:定義公用接口YourAbstractSearchKey中的所有屬性,併爲其他節點執行YourSearchKey throw UnsupportedOperationException
  2. 相似,但有一個地圖。您不需要爲YourAbstractSearchKey添加額外的屬性,因爲該地圖將爲Map<YourAbstractSearchKey,YourElement>。要添加元素,您需要編寫myMap.put(newElement,newElement)
+0

Woow。我沒有想到這一點。這是我的一般hackish方法:) –

+0

(地圖不會做 - 如果是這樣,我會'Map ') –

+0

@PiotrFindeisen是的,這幾乎是我說的RE'Map單曲。 –