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
类中的Expression
为00*
而我尝试查找的String
将为00112233
。因此hashCode()
对于那些字符串不会相同。
客户端代码尝试使用HashMap
密钥从String
进行查找
map.get("0011"); //should get someObject as `0011` matches expression `00*`
有没有办法做到这一点?
我知道hashCode()
应该包含不可变的值以及hashCode()
和equals()
合同。
但我怀疑是否有办法实现这一点。
答案 0 :(得分:0)
有一个原因是没有实现这样的数据结构。 让我们进行逆向工程:
<强>要求:强>
keyA = Expression.getInstance("00*");
keyB = Expression.getInstance("0011");
map.get(keyA) == map.get(keyB)
现在hashmap()如何工作?
<强>曲线变化分析强>
这意味着,keyA
和keyB
应该具有相同的 hashCode ,并且 也应该
所以keyA.equals(keyB) == true
怎么样,keyC = Expression.getInstance("0010");
根据你的逻辑keyC.equals(keyA) = true
。但是因为等于是传递意味着keyB.equals(keyC) == true
。
这意味着在您的地图中,0010
和0011
会映射到相同的值!?事实上,以“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个正则表达式的集合,如果你的字符串与之匹配则一个接一个地尝试。
任何更聪明的方案都需要分析给定的正则表达式,很可能是等效有限自动机的图形。
我不知道这样的计划。
它还取决于你的正则表达式,也许它们有一些简单的形状,可以被利用。