为什么我从字符串中得到错误的HashCode?

时间:2015-07-19 17:37:21

标签: java string hashmap key hashcode

我有这个结构:

private HashMap<Integer,HashMap<Object,Integer>> commandList= new HashMap<>();

以这种方式填充:

{1={1=2, 2=3, 3=4, -999=-999, -998=-998}}

来自此代码:

if ((msgTypeTemp=commandList.get(this.msgType).get(msgContent))==null) {
    Object s= "1";
    System.out.println("Class of s: "+s.getClass().getSimpleName()+"\nClass of msgContent: "+msgContent.getClass().getSimpleName());
    System.out.println("msgMap:\n"+msgMap);
    System.out.println("commandList:\n"+commandList);
    System.out.println(s.hashCode());
    System.out.println(msgContent.hashCode());
    System.out.println(commandList.get(this.msgType).get(s));
    this.msgType=JSockOS_UndefinedMsg.MSG_CODE;
    specialMsg=true;
} else {                
    this.msgType=msgTypeTemp;
    if (specialMsgType(this.msgType)){          
        specialMsg=true;
    }
}

我的HashMap是通用类型<String,Integer>

然而,每当我在msgContent上调用get方法时,就会发现代替"1"的哈希码,它是的哈希码,直到那一刻被设置为到0,然后在get方法调用后更改。

仅在使用"msgContent"参数...

的调用中发生这种情况

如果我使用它:System.out.println(commandList.get(this.msgType).get(s));

它返回&#34; 2&#34;正如所料......

看看这张图片,它可能会有所帮助。

Notice the differences in the two yellow boxes showed while debugging

以这种方式在上述代码之前更改msgContent:

它是第一个:2.1。 然后它得到:1。

剩下一个字符串。

msgContent=msgContent.toString().split(Pattern.quote("."))[1];
do(msgContent); // a methods which implements the code showed before.

//msgContent is a parameter, --> public void do(Object msgContent)

[编辑]: 问题发现:msgContent是495个字符...将修复其更改并更新!

1 个答案:

答案 0 :(得分:1)

即使hashCode是不可变的,出于性能原因,public int hashCode() { int h = hash; if (h == 0 && value.length > 0) { char val[] = value; for (int i = 0; i < value.length; i++) { h = 31 * h + val[i]; } hash = h; } return h; } 的值为computed lazilyas shown here

String

就您的实际问题而言,您是否完全确定您的密钥是<Object, Integer>?您在此处提供的类型为<String, Integer>,而不是elseSide

我的测试用例正常,如此处所示(这打印public static void main(String... args) { HashMap<Integer, HashMap<Object, Integer>> map = new HashMap<>(); HashMap<Object, Integer> innerMap = new HashMap<>(); innerMap.put("1", 2); innerMap.put("2", 3); innerMap.put("-999",-999); innerMap.put("-998",-998); map.put(1, innerMap); int msgType = 1; String msgContent = "2.1"; msgContent = msgContent.toString().split(Pattern.quote("."))[1]; System.out.println(map); if(map.get(msgType).get(msgContent) == null) { System.out.println("ifSide"); } else { System.out.println("elseSide"); } } ):

HashMap<Object, Integer> innerMap = commandList.get(this.msgType);
for(Map.Entry<Object, Integer> entry : innerMap.entrySet()) {
    System.out.println("KeyClass: " + entry.getKey().getClass() + 
             "\tKeyValue:" + entry.getKey());
    // This will make sure the string doesn't have any unprintable characters
    if(entry.getKey() instanceof String) {
        String key = (String) entry.getKey();
        System.out.println("Key Length: " + key.getLength());
    }
}

我认为您应该尝试添加以下调试语句:

String

我不认为你的内部地图中的密钥实际上是一个字符串,或者630719471可能不知道具有不可打印的字符。对于一个字符StringmsgContent的哈希值太高。 {{1}}也可能有不可打印的字符。