簡體   English   中英

此hashmap場景的數據結構

[英]which datastructure for this hashmap scenario

我有一個場景,我將值存儲在hashmap中。

鍵是字符串

fruits
fruits_citrus_orange
fruits_citrus_lemon
fruits_fleshly_apple
fruits_fleshly
fruits_dry

等等。

值是一些對象。 現在對於給定的輸入說fruits_fleshly我需要檢索它以“fruits_fleshly”開頭的所有情況在上面的例子中我需要獲取

fruits_fleshly_apple
fruits_fleshly

一種方法是在所有鍵上執行String.indexOf。 有沒有其他有效的方法來做到這一點,而不是迭代地圖中的所有鍵

迭代地圖似乎是非常簡單和直截了當的方式。 但是,由於您不想自己迭代鍵,因此如果您可以使用第三方庫,則可以使用Guava的 Maps#filterEntries

以下是它的工作原理:

Map<String, Object> = Maps.filterEntries(
                   yourMap, 
                   Predicate.containsPattern("^fruits_fleshly"));

但是,那也會在后院的地圖上迭代。 因此,如果您對效率感到困擾,迭代仍然存在。

雖然這些是字符串,但對我來說,看起來這些是某些類別和子類別,如水果,新鮮水果,水果柑橘等。

如果是這種情況,您可以改為實現樹數據結構。 這對搜索操作最有效。

由於Tree具有父子結構,因此存在根節點和子節點。 你可以有這樣的結構:

(0)   (1)        (2)
fruit
|_____citrus
|          |_____lemon
|          |_____orange
|
|_____freshly
           |_____apple
           |_____

在這種結構中,如果你想搜索柑橘類水果,你可以去柑橘,並列出它的所有孩子。 最后,您可以通過將名稱連接為從根到葉的路徑來構造全名。

由於HashMap沒有維護其鍵的任何順序,因此對於此問題不是一個非常好的選擇。 更好的選擇是TreeMap:它具有檢索一系列鍵的子映射的方法。 這些方法在O(log n)時間(n個條目)中運行,因此它比迭代密鑰更好。

Map subMap = myMap.subMap("fruits_fleshly", true, "fruits_fleshly\uffff", true);

hashmap的本質意味着沒有辦法對鍵進行“喜歡”的比較 - 你必須遍歷它們才能找到key.startsWith(input)

我想你可以嵌套哈希映射並拆分你的密鑰。 例如,

{
  "fruits":{
    "citrus":{
      "orange":(value), 
      "lemon":(value)
    }, 
    "fleshly":{
      "apple":(value), 
      "":(value)
    }
  }
}

...等等。

性能影響可能在小范圍內可怕,但在家庭作業環境中可能無關緊要,但如果您處理大量數據並且只有幾層嵌套,則可能並不那么糟糕。

或者,使用List of Categories(子類別)和條目列表創建Category對象。

我相信Radix Trie正是您所尋找的。 它與@ ay89解決方案類似。

您可以使用此開源庫Radix Trie示例 它的性能優於O(log(N))。 您將能夠找到一個平均恆定時間(搜索關鍵字字符串中的下划線數)分配給鍵的哈希映射,並使用Radix Trie.fruits的一個不錯的實現.fruit_citrus_orange fruits_citrus_lemon fruits_fleshly_apple fruits_fleshly fruits_dry

Trie<String, Map> trie = new PatriciaTrie<>;
trie.put("fruits", hashmap1);
trie.put("fruits_citrus_orange", hashmap2);
trie.put("fruits_citrus_lemon", hashmap3);
trie.put("fruits_fleshly_apple", hashmap4);
trie.put("fruits_fleshly", hashmap5);

Map.Entry<String, Map> entry = trie.select("fruits_fleshy");

如果你只想通過select返回一個hashmap,那么如果你實現自己的Radix Trie,你可能會獲得更好的性能。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM