【发布时间】:2014-03-21 19:30:50
【问题描述】:
我已经使用 Netbeans 进行 Java 开发已有一段时间了,有些事情我只是依赖于工作而没有真正质疑如何工作。其中包括自动生成的 hashCode() 和 equals() 方法。
equals 方法很容易理解,但我发现 hashCode 方法有点神秘。我不明白为什么它选择乘数并应用它所做的操作。
import java.util.Arrays;
import java.util.Objects;
public class Foo {
int id;
String bar;
byte[] things;
@Override
public int hashCode() {
int hash = 7;
hash = 89 * hash + this.id;
hash = 89 * hash + Objects.hashCode(this.bar);
hash = 89 * hash + Arrays.hashCode(this.things);
return hash;
}
}
在文档、此站点和 Google 中搜索“netbeans 生成哈希码”之类的内容似乎没有任何相关信息。这里有没有人熟悉这个生成策略是什么以及 Netbeans 使用它的原因?
编辑:
感谢您到目前为止的答案!特别是由于this answer on the linked SO question,我现在更全面地理解了在设计 hashCode 方法时使用素数背后的逻辑。然而,到目前为止,没有人真正解决我的问题的另一个方面是 Netbeans 如何以及为什么选择它为其生成的方法所做的素数。 hash 字段和其他乘数(在我的示例中为 89)似乎因类的各种因素而异。
例如,如果我在类中添加第二个String,则 hashCode() 变为
public int hashCode() {
int hash = 7;
hash = 13 * hash + this.id;
hash = 13 * hash + Objects.hashCode(this.bar);
hash = 13 * hash + Objects.hashCode(this.baz);
hash = 13 * hash + Arrays.hashCode(this.things);
return hash;
}
那么,为什么 Netbeans 选择这些特定的素数,而不是其他任何素数?
【问题讨论】:
-
我认为这只是一种方法,IntelliJ IDEA使用31
-
乘以 31 很容易优化为移位和减号,不确定 89。不过两者都应该是素数。
-
一个不错的选择是:
return Objects.hash(id, bar, baz, things);或多或少做同样的事情。 -
今天早上看到你的编辑,因为我正在考虑如何用我的答案绕过这个问题。 :-) 这是一个很好的问题,所以我为你投了赞成票。
-
关于 netbeans 为什么选择那个素数,zapl 在他的评论中给出了一个很好的暗示。如果您真的想确定,请查看他们的代码。一般提示:如果您喜欢目前得到的答案,只需点赞即可,而不是在您的问题中表示感谢。