查找部分属性

时间:2016-05-17 08:36:59

标签: java data-structures hashmap in-memory

我有一张地图。键包含6个字符的String和Properties类,大致如下所示:

public class Properties {
    private String propertyOne;
    private String propertyTwo;
    private String propertyThree;
    private String propertyFour;
    ...
    ...
}

现在假设我在地图中有一些条目如下:

  

41111 - > {1,2,3,4,5}

     

41112 - > {1,2,3,4,6}

     

41234 - > {1,2,345,87,65}

     

51123 - > {100,200,30000,345,123}

     

51122 - > {100,200,30000,556,989}

现在,如果我map.get("12567"),我会得到所需的属性对象。

我遇到的挑战是,我必须创建一个可以保存部分数据的数据结构。根据部分数据,我的意思是,如果我map.get("4111")我应该得到{1,2,3,4,5} (41111的属性){1,2,3,4,6} <的交叉点 strong>(41112的属性),{1,2,3,4,null}.

同样map.get("41")应生成{1,2,null,null,null}

我现在有一个解决方案,即我创建了多个HashMaps,其中包含所有可能的部分键及其对应的值,如:

Map<String, Property>`` keyValuesForOneChar包含所有可能的单个字符作为键及其对应的值。

Map<String, Property> keyValuesForTwoChars包含所有可能的两个字符作为键及其对应的值。

我不喜欢这个解决方案,因为它非常直接,我不认为维护多个哈希图是个好主意。还有一个问题是我的原始数据计数大约是200000,并且所有排列组合我将创建巨大的部分数据,并且我认为哈希映射的性能会降低。请为此问题提出更好的解决方案。我有以下限制:

  1. 解决方案应严格限制在内存中。
  2. 查找应该更快。这就是为什么如果处理原始数据和准备数据结构需要额外的时间和内存,这应该是一个问题。

1 个答案:

答案 0 :(得分:4)

HashMap绝对不是最适合您问题的数据结构。由于您的键是字符串,您可以实现一个trie(也称为前缀树)。

它的工作原理是将字符串键拆分成较小的字符串或字符。这样,您可以存储键的值,也可以存储公共前缀。也就是说,你可以存储&#34; 41111&#34;和&#34; 41112&#34;在公共前缀&#34; 4111&#34;。当查找4111时,需要O(m)步,其中m是键的长度,并且您将能够检索{1,2,3,4,5}和{1,2,3的交集。 ,4,6}如果在trie中插入项目时更新交叉点。

检索部分属性

您可以在构建trie时更新部分属性。让我们说你插入这对夫妇(41111,{1,2,3,4,5})。尝试是特定的树,它看起来像这样。符号k,v表示这是一个键为k且值为v的节点。

4,{1,2,3,4,5}
      |
1,{1,2,3,4,5}
      |
1,{1,2,3,4,5}
      |
1,{1,2,3,4,5}
      |
1,{1,2,3,4,5}

在路径上的每个节点上,存储部分属性。现在,当插入这对夫妇(41112,{1,2,3,4,6})时,你更新了trie:

       4,{1,2,3,4,null}
             |
       1,{1,2,3,4,null}
             |
       1,{1,2,3,4,null}
             |
       1,{1,2,3,4,null}
      /                \
1,{1,2,3,4,5}     2,{1,2,3,4,6}

再次,如果您插入41234,{1,2,345,87,65},它将如下所示:

              4,{1,2,null,null,null}
                         |
              1,{1,2,null,null,null}
             /                      \
       1,{1,2,3,4,null}          2,{1,2,345,87,65}
             |                           |
       1,{1,2,3,4,null}          3,{1,2,345,87,65}
      /                \                 | 
1,{1,2,3,4,5}     2,{1,2,3,4,6}  4,{1,2,345,87,65}

执行此操作时,仅存储已插入项目的公共前缀的部分属性,您无需创建所有组合。另外,使用检索值的相同算法来检索部分属性。