此hashmap场景的数据结构

时间:2013-08-01 18:42:01

标签: java data-structures map

我有一个场景,我将值存储在一个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。有没有其他有效的方法来做到这一点,而不是迭代地图中的所有键

5 个答案:

答案 0 :(得分:2)

迭代地图似乎是非常简单和直截了当的方式。但是,由于您不想自己迭代密钥,因此如果您可以使用第三方库,则可以使用Guava's Maps#filterEntries

以下是它的工作原理:

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

但是,那也会在后院的地图上迭代。所以,如果你对效率感到困扰,迭代仍然存在。

答案 1 :(得分:2)

虽然这些是字符串,但对我来说,看起来这些是某些类别&amp;子类别,如水果,新鲜水果,水果柑橘等。

如果是这种情况,您可以改为实现Tree数据结构。这对搜索操作最有效。

由于Tree具有父子结构,因此存在根节点&amp;子节点。你可以有这样的结构:

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

在这种结构中,如果你想搜索柑橘类水果,你可以去柑橘,并列出它的所有孩子。最后,您可以通过将名称连接为从根到叶子的路径来构造全名。

答案 2 :(得分:1)

由于HashMap没有维护其键的任何顺序,因此对于这个问题不是一个很好的选择。更好的选择是TreeMap:它具有检索一系列键的子映射的方法。这些方法在O(log n)时间(n个条目)中运行,因此它比迭代密钥更好。

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

答案 3 :(得分:0)

散列映射的本质意味着无法对键进行“喜欢”比较 - 您必须遍历它们才能找到key.startsWith(input)的位置。

我想你可以嵌套哈希映射并拆分密钥。例如,

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

...等

性能影响可能在小范围内可怕,但在家庭作业环境中可能无关紧要,但如果您处理大量数据并且只有几层嵌套,则可能并不那么糟糕。

或者,使用List of Categories(子类别)和条目列表创建Category对象。

答案 4 :(得分:0)

我相信Radix Trie正是您所寻找的。它与@ ay89解决方案类似。

您可以使用此开源库Radix Trie example。它的性能优于O(log(N))。您将能够找到分配给密钥的平均常量时间(搜索关键字字符串中的下划线数)的散列图,并使用Radix Trie.fruits实现一个不错的实现 fruits_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,可能会获得更好的性能。