Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/375.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java Hashmap在尝试获取其中存在的对象时提供Null_Java_Hashmap_Hash - Fatal编程技术网

Java Hashmap在尝试获取其中存在的对象时提供Null

Java Hashmap在尝试获取其中存在的对象时提供Null,java,hashmap,hash,Java,Hashmap,Hash,我遇到了一个奇怪的问题,在这个问题上我重复了一系列的回答。当我试图从每个问题的回答中得到答案时,大多数答案都是正确的,除了一个从hashmap中得到的答案为空。我在eclipse中运行了调试模式,并将我试图从hashmap getAnswerMap()获取其值的问题与hashmap中的问题进行了比较,两者似乎完全相同,但我仍然得到null 对于(调查响应:响应){ multipleChiceAnswer-answer=(multipleChiceAnswer)response.getAnswer

我遇到了一个奇怪的问题,在这个问题上我重复了一系列的回答。当我试图从每个问题的回答中得到答案时,大多数答案都是正确的,除了一个从hashmap中得到的答案为空。我在eclipse中运行了调试模式,并将我试图从hashmap getAnswerMap()获取其值的问题与hashmap中的问题进行了比较,两者似乎完全相同,但我仍然得到null

对于(调查响应:响应){ multipleChiceAnswer-answer=(multipleChiceAnswer)response.getAnswerMap().get(问题); .... .... } 然后,我认为这是一个hashcode问题,所以我添加了另一行丑陋的代码来检查hashcodes,它们实际上有相同的hashcode,下面的附加行起作用了,并且正确地设置了答案

对于(调查响应:响应){ multipleChiceAnswer-answer=(multipleChiceAnswer)response.getAnswerMap().get(问题); for(条目:response.getAnswerMap().entrySet()){ if(entry.getKey().hashCode()==question.hashCode())answer=(multipleechoiceanswer)entry.getValue(); .... .... } 然而,这很难看,我真的很想从hashmap中得到正确的答案。有什么建议吗

更新:
对这两个对象同时调用hashCode()和equals()方法表明这两个对象的hashcodes和equals()都相等返回true。我怀疑下面的一个答案表明,问题可能是在将问题插入hashmap时使用了不同的hashcode。因此,调用问题中的get方法返回null,因为我尝试获取的对象没有与旧对象相同的hashcode。非常有用的answers伙计们!

很可能您没有覆盖
equals(…)
正确-需要一个
HashMap
才能正常工作

需要注意的一件事:确保用作键的类是不可变的——否则,当你放入一个键时,它会散列到一个对象,而当你取出它时,它会散列到另一个对象


编辑:它不必是不可变的,但它必须是真实的,它只能以不改变哈希代码的方式进行更改。使整个对象不可变是实现这一点的最简单的方法,但不是唯一的方法。

要使对象成为具有
哈希映射的100%确定性键,需要覆盖
哈希代码()
equals()
equals()
中一致,当
hashCode()
相同时,它们总是返回
true

下面是IBM developerWorks上Brian Goetz的一篇老文章,但内容至今仍然适用:

为什么覆盖equals()和hashCode()?

如果
Integer
没有,会发生什么 覆盖
equals()
hashCode()
? 如果我们从未使用过
整数
作为
哈希映射
或其他 基于散列的集合。但是,如果 我们将使用这样一个整数对象 HashMap中的一个键,我们不会 能够可靠地检索 关联值,除非我们使用 完全相同的
Integer
实例
get()
调用,就像我们在
put()
这需要确保 我们只使用
整数
与 特定整数值 我们的节目,不用说,这 这种方法会很不方便,而且 容易出错

接口合同 对于
对象
要求 根据不同的标准,对象是相等的
equals()
,则它们必须具有相同的
hashCode()
value。为什么我们的根 对象类需要
hashCode()
,当其 辨别能力完全不同 被
equals()
的包含
hashCode()
方法的存在纯粹是为了 效率:Java平台 建筑师们预见到了这一重要性 基于散列的集合类的定义-- 例如
Hashtable
HashMap
,以及
HashSet
——在典型的Java中 应用程序,并与 许多具有
equals()
的对象可以 计算上很昂贵 每个Java对象都支持
hashCode()
允许高效的存储和存储 基于哈希的检索 收藏


还有一个玻璃球猜测:

您有这样一个equals方法:

class Question {

    // ...


    public boolean equals(Question q) {
       // do intelligent comparison
    }

    public int hashCode() {
        // calculate hash code
    }

}
但是在这里您并没有真正覆盖对象中的
equals(Object)
方法,只需在此旁边声明一个新方法。HashMap对您的新方法一无所知,它只需调用原始方法,将映射中的键对象与查询键进行比较(在找到一个具有匹配hashCode的键对象后)

改为如下声明方法:

    @Override
    public boolean equals(Object o) {
        if(! (o instanceof Question))
           return false;
        Question q = (Question)o;
        // do intelligent comparison
    }

(通过
@Override
注释,编译器可以检查您是否真的在这里重写了一个方法,而不仅仅是创建了一个新方法。)

我刚刚通过system.out.println检查了这一点,entry.getKey().equals(question)返回true。是的,我完全同意您的说法。但是,我同时检查了equals()和hashCode()对于question和entry.getKey()和两者都是一致的。但是hashCode是否与将对象放入映射时的hashCode相同!“其中它们一致,当hashCode()相同时,equals()始终返回true”-事实上-正如你的文章所说-那不是真的。两个不同的对象可能有相同的hashcode,但仍然返回false作为equals,这将是一个完全有效的实现。Hashcollisions是很有可能的。我不知道这为什么会被否决,据我们所知,这可能是问题的解决方案。是和否-你是对的哈希代码必须保持为t