尽管实现了 equals 和 hashcode 方法,Hashmap get 和 containskey 方法仍无法检索对象

Hashmap get and containskey method unable to retrieve object despite having implemented equals and hashcode methods

我有一个名为 Language 的 class,Language 有很多字段,但我只想使用一个字段来将它与其他 Language 对象进行比较。该字段称为 languageCode,它是一个字符串。我已经使用Intellij Idea的方法生成工具自动实现了equals和hashcode。这是具有相关字段和生成方法的 class。

public class Language implements Serializable{

    private String languageCode

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Language language = (Language) o;
        return languageCode.equals(language.getLanguageCode());
    }

    @Override
    public int hashCode() {
        return Objects.hash(languageCode);
    }

}

还有一个 class 叫做 Journal 期刊也有很多不同的领域,但只有一个是相关的,即:

public class Journal {

  private Map<Language, String> titleTranslations = new HashMap<>()

}

在整个程序中,我使用常量变量 ENGLISH_LANGUAGE,它包含来自数据库的英语表示语言对象。 titleTranslations 中的所有语言对象也来自同一个数据库 table。此外,Journal 在其 Hashmap titleTranslations 中肯定有一个英语语言对象。

但是当我运行进行以下测试时:

journal.getTitleTranslations().forEach((Language language, String string) ->{
    log.info(language.getLanguageCode() + " " + string);
    log.info("hashcode is " + language.hashCode());
});
log.info("default language " + ENGLISH_LANGUAGE.getLanguageCode());
log.info("hashcode is " + ENGLISH_LANGUAGE.hashCode());
log.info("contains key " + journal.getTitleTranslations().containsKey(ENGLISH_LANGUAGE));
log.info("key is not null " + (journal.getTitleTranslations().get(ENGLISH_LANGUAGE) != null));

它给出以下输出:

de deutsch 
hashcode is 3232 
en english 
hashcode is 3272 
fr francais 
hashcode is 3307 
nl nederlands 
hashcode is 3549 
defautl language en 
hashcode is 3272 
contiains key false 
key is not null false

你可以看到,尽管 ENGLISH_LANGUAGE 的哈希码和 titletranslations 中的英语对象完全相同 (3272),但在使用 get 方法时仍然找不到密钥 returns false 当我使用 containsKey 并使用 ENGLISH_LANGUAGE 作为参数时。

有人可以告诉我我做错了什么吗?单字段哈希码实现是否以某种方式不起作用?

谢谢

好的,问题似乎与框架有关。因为我使用的框架使用像 hibernate 这样的代理子类,所以应该稍微调整 equals 方法。这是当您选中 Accept subclasses as parameter to equals() method 选项时 intellij 可以自动为您做的事情,复选框下方是这样的解释:

While generally incomplaint to Object.equals() specifiation accepting subclasses might be necessary for generated method to work correctly with frameworks, which generate Proxy subclasses like Hibernate

检查这个将创建一个 equals 方法,它使用这个 if 语句 if (!(o instanceof Language)) return false; 而不是这个 if (o == null || getClass() != o.getClass()) return false;.

这以某种方式解决了问题。哈希码方法保持不变。完整代码如下:

@Override
public boolean equals(Object o) {
    if (this == o) return true;
    if (!(o instanceof Language)) return false;
    Language language = (Language) o;
    return getLanguageCode().equals(language.getLanguageCode());
}

@Override
public int hashCode() {
    return Objects.hash(getLanguageCode());
}