为包含布尔字段的持久实体覆盖 hashCode() 的正确方法?

Posted

技术标签:

【中文标题】为包含布尔字段的持久实体覆盖 hashCode() 的正确方法?【英文标题】:Correct way to override hashCode() for persistent entity containing a boolean field? 【发布时间】:2016-06-07 22:04:41 【问题描述】:
private long configKeyMasterId;
private String configKey;
private boolean isDisplay;

public int hashCode() 
    int result = (int) (configKeyMasterId ^ (configKeyMasterId >>> 32));
    result = 31 * result + (configKey != null ? configKey.hashCode() : 0);
    result = 31 * result + (isDisplay != null ? isDisplay.hashCode() : 0);
    return result;

这就是我所拥有的 isDisplay 是一个布尔字段。我知道第 3 行是错误的,但我该如何解决呢?

是不是很天真,

result = 31 * result + (isDisplay != false ? Boolean.hashCode(isDisplay) : 0);

好吗?

我不知道如何或为什么必须覆盖 hashCode(),但我正在阅读它。

【问题讨论】:

【参考方案1】:

检查false 是多余的。做吧

result = 31 * result + Boolean.hashCode(isDisplay);

EDIT 请注意,这假定isDisplay 是一个原始字段。如果是加框字段 (Boolean),则您发布的版本(带有空检查)应该是正确的。

【讨论】:

除此之外,别无他法,对吗? 另外,将false 的检查更改为true 的检查有什么效果吗? @AshharHasan 他们都会影响结果,但检查是不必要的。 如果 isDisplay 为空会抛出 NPE @SleimanJneidi 它没有在源代码中声明。如果您指的是空检查,我认为这只是上一行的副本,OP 承认这是错误的。如果它确实是装箱的,那么OP的代码就没有问题。【参考方案2】:

如果您使用的是 Java 7 或更高版本,则可以使用 Objects.hash(...) 而不是自己编写并避免空检查。

return Objects.hash(configKey, isDisplay);

【讨论】:

那么,为什么我看到大多数人都在编写冗长的 hashCode 函数?我缺少一些区别吗? @AshharHasan 我想他们不知道 如果你的字段是原语,效率会稍低。

以上是关于为包含布尔字段的持久实体覆盖 hashCode() 的正确方法?的主要内容,如果未能解决你的问题,请参考以下文章

实体持久注册验证侦听器

将学说实体布尔字段设置为 0 而不是 null

jpa序列ID生成

在 Java 中覆盖 equals 和 hashCode 时应该考虑哪些问题?

Spring:无法持久使用@JsonIgnore 注释的实体

Sonata Admin - 布尔字段类型,标签不显示