基于表达式从HashMap查找

时间:2013-09-03 11:30:57

标签: java collections hashmap hashcode

class Expression{
   private final String expression; //can be 00* or 01* or 0101*

   public int hashCode(){
       //what should I put here
       //tried to use String hashCode but not useful
   }

   public boolean equals(Object obj){
       //Logic for testing of equality
       //Check if the obj is String check if expression matches
   }
}

//This is how map is initialized
map.put("00*",someObject);
map,put("0101*", someOtherObject);

为什么String hashCode实现没用?

因为String类中的Expression00*而我尝试查找的String将为00112233。因此hashCode()对于那些字符串不会相同。

客户端代码尝试使用HashMap密钥从String进行查找

map.get("0011"); //should get someObject as `0011` matches expression `00*`

有没有办法做到这一点?

我知道hashCode()应该包含不可变的值以及hashCode()equals()合同。

但我怀疑是否有办法实现这一点。

3 个答案:

答案 0 :(得分:0)

有一个原因是没有实现这样的数据结构。 让我们进行逆向工程:

<强>要求:

keyA = Expression.getInstance("00*");
keyB = Expression.getInstance("0011");

map.get(keyA) == map.get(keyB)

现在hashmap()如何工作?

  • 首先,计算密钥的哈希值,用于定位哈希桶。
  • 现在使用该存储桶键的equals()用于查找Entry对象,然后返回Entry.value()。

<强>曲线变化分析

这意味着,keyAkeyB应该具有相同的 hashCode ,并且 也应该

所以keyA.equals(keyB) == true

怎么样,keyC = Expression.getInstance("0010");

根据你的逻辑keyC.equals(keyA) = true。但是因为等于是传递意味着keyB.equals(keyC) == true

这意味着在您的地图中,00100011会映射到相同的值!?事实上,以“00”开头的任何内容都具有相同的值。因此,与使用00作为该值的键相同。 你知道我要去哪里吗?

简而言之,我认为它不适用于现有的HashMap()实现。

答案 1 :(得分:0)

我同意RocketBoy ..这不适用于Map。我建议查看Trie数据类型。它不在标准Java API中,因此您需要编写自己的实现或在线查找。

另一种选择是在List<Expression>之外保留Map。您可以在列表中循环执行类似

的操作
for (final Expression e : myExpressions) {
    if (myLookup.startsWith(e)) {
        return myMap.get(e);
    }
}

答案 2 :(得分:0)

让我重申你的问题:

你有超过L = {0,1} ^ *

的正则表达式
re_1
re_2
..
re_n

并且您已将对象存储在哈希映射中,并将正则表达式(或数字)的字符串作为键。

map.put(re_1, obj_1)
map.put(re_2, obj_2)
..
map.put(re_n, obj_n)

现在你有一个给定的字符串匹配(最大)一个正则表达式,你想要一个快速的

map.get(s) -> s matching regexp re_k -> map.get(re_k) -> obj_k

这需要一种方法来识别给定字符串匹配的正则表达式。

最简单的方法是循环遍历所有n个正则表达式的集合,如果你的字符串与之匹配则一个接一个地尝试。

任何更聪明的方案都需要分析给定的正则表达式,很可能是等效有限自动机的图形。

我不知道这样的计划。

它还取决于你的正则表达式,也许它们有一些简单的形状,可以被利用。