Java 基于表达式的HashMap查找

Java 基于表达式的HashMap查找,java,collections,hashmap,hashcode,Java,Collections,Hashmap,Hashcode,为什么字符串哈希代码实现没有用? 因为表达式类中的字符串是00*,而我试图查找的字符串将是00112233。因此,这些字符串的hashCode()将不同 客户端代码尝试使用String键从HashMap进行查找 class Expression{ private final String expression; //can be 00* or 01* or 0101* public int hashCode(){ //what should I put here

为什么字符串哈希代码实现没有用?

因为
表达式
类中的
字符串
00*
,而我试图查找的
字符串
将是
00112233
。因此,这些字符串的
hashCode()
将不同

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

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);
有没有办法做到这一点

我知道
hashCode()
应该包含关于
hashCode()
equals()
契约的不可变值


但我怀疑是否有任何方法可以实现这一点。

没有实现这种数据结构是有原因的。 让我们对其进行反向工程:

要求:

map.get("0011"); //should get someObject as `0011` matches expression `00*`
现在hashmap()是如何工作的

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

这意味着,
keyA
keyB
应该有相同的hashCode,并且应该相等

所以
keyA.equals(keyB)=true

那么,
keyC=Expression.getInstance(“0010”)

根据您的逻辑
keyC.equals(keyA)=true
。但是因为equals是可传递的,这意味着
keyB.equals(keyC)==true

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


简而言之,我不认为它在现有的HashMap()实现中起作用。

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

另一个选择是在
地图
之外保留
列表
。您可以循环浏览列表,执行以下操作

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

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

让我重申你的问题:

在L={0,1}上有n个正则表达式^*

for (final Expression e : myExpressions) {
    if (myLookup.startsWith(e)) {
        return myMap.get(e);
    }
}
您已经将对象存储在一个哈希映射中,其中正则表达式(或数字)字符串作为键

现在,您有了一个与正则表达式中的一个匹配(极限)的给定字符串,您需要一个快速的

map.put(re_1, obj_1)
map.put(re_2, obj_2)
..
map.put(re_n, obj_n)
这需要一种方法来识别给定字符串匹配的正则表达式

最简单的方法是在所有n个正则表达式的集合上循环,如果字符串匹配,则逐个尝试

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

我不知道这样的计划


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

在实现内部,您可以使用正则表达式验证所需内容,然后在Hashmap满足您的条件时将其添加到Hashmap中。@AurA map已使用表达式初始化。现在我想根据哪个字符串满足特定表达式来检查条目,并使用map中的值。@mvw我已经添加了对此的解释。检查更新后的答案。@NarendraPathai我在你的问题中漏掉了“正则表达式”一词。如果“0011”与“00*”和“001*”匹配怎么办?如果我没有误解,你也在暗示这是不可能的,对吗?不是通过标准的hashCode()和equals()方法。
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