如何对 hashCode() 进行单元测试?

发布于 2024-10-07 21:40:27 字数 257 浏览 5 评论 0原文

如何在单元测试中测试 hashCode() 函数?

public int hashCode(){
    int result = 17 + hashDouble(re);
    result = 31 * result + hashDouble(im);
    return result;
}

How can I test the hashCode() function in unit testing?

public int hashCode(){
    int result = 17 + hashDouble(re);
    result = 31 * result + hashDouble(im);
    return result;
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

清眉祭 2024-10-14 21:40:27

每当我重写 equals 和 hash 代码时,我都会遵循 Joshua Bloch 在“Effective Java”第 3 章中的建议编写单元测试。我确保 equals 和 hash 代码是自反的、对称的和传递的。我还确保“不等于”适用于所有数据成员。

当我检查 equals 调用时,我还确保 hashCode 的行为符合预期。像这样:

@Test
public void testEquals_Symmetric() {
    Person x = new Person("Foo Bar");  // equals and hashCode check name field value
    Person y = new Person("Foo Bar");
    Assert.assertTrue(x.equals(y) && y.equals(x));
    Assert.assertTrue(x.hashCode() == y.hashCode());
}

Whenever I override equals and hash code, I write unit tests that follow Joshua Bloch's recommendations in "Effective Java" Chapter 3. I make sure that equals and hash code are reflexive, symmetric, and transitive. I also make sure that "not equals" works properly for all the data members.

When I check the call to equals, I also make sure that the hashCode behaves as it should. Like this:

@Test
public void testEquals_Symmetric() {
    Person x = new Person("Foo Bar");  // equals and hashCode check name field value
    Person y = new Person("Foo Bar");
    Assert.assertTrue(x.equals(y) && y.equals(x));
    Assert.assertTrue(x.hashCode() == y.hashCode());
}
紫南 2024-10-14 21:40:27

当您编写一般的数学函数(如哈希码)时,您会在测试中测试一些示例,直到您确信该函数按预期工作。有多少示例取决于您的功能。

对于哈希码函数,我认为您至少测试两个被认为相等的不同对象具有相同的哈希码。 与进一步一样

assertNotSame(obj1, obj2); // don't cheat
assertEquals(obj1.hashcode(), obj2.hashcode());

,您应该测试两个不同的值是否具有不同的哈希码,以避免像 return 1; 那样实现 hashcode()

When you write a mathematical function in general (like hash code) you test some examples in your tests until you are convinced that the function works as expected. How many examples that are depends on your function.

For a hash code function I'd think you test at least that two distinct objects, that are considered equal have the same hash code. Like

assertNotSame(obj1, obj2); // don't cheat
assertEquals(obj1.hashcode(), obj2.hashcode());

Further you should test that two different values have different hash codes to avoid implementing hashcode() like return 1;.

风蛊 2024-10-14 21:40:27

hashCode 被覆盖,以使 HashSet/HashMap 等具有相同字段的实例相同。
因此 Junit 测试应该断言具有相同值的两个不同实例返回相同的 hashCode。

hashCode is overrided so as to make instances with same fields identical for HashSet/HashMap etc.
So Junit test should assert that two different instances with same values return identical hashCode.

硬不硬你别怂 2024-10-14 21:40:27

创建许多(数百万个)可重现的随机对象,并将所有 hashCode 添加到一个 Set 中,并检查您是否获得了几乎和许多不同的值作为生成 id 的数量。为了使它们可随机再现,请使用固定的随机种子。

另外,检查您是否可以将这些项目添加到 HashSet 中并再次找到它们。 (使用具有相同值的不同对象)

确保您的 equals() 与您的 hashCode() 行为匹配。我还会检查您的字段是否都是最终的。

Create many (millions of) reproduceably random objects and add all the hashCodes to a Set and check you get almost and many unqiue values as the number of generate ids. To make them reproduceable random use a fixed random seed.

Additionally check you can add these Items to a HashSet and find them again. (Using a differnt object with the same values)

Make sure your equals() matches your hashCode() behaviour. I would also check that your fields are all final.

删除会话 2024-10-14 21:40:27

我认为不需要对哈希码方法进行单元测试。特别是如果它是由您的 IDE 或 HashCodeBuilder(apache 公共资源)

I don't think there's a need to unit-test a hashcode method. Especially if it is generated by either your IDE or a HashCodeBuilder (apache commons)

万人眼中万个我 2024-10-14 21:40:27

除了 @duffymo 测试哈希码的自反性、对称性和传递性之外,另一种测试方法是通过“Map”,这是哈希码实际上派上用场的地方。

 @Test
public void testHashcode() {
    Person p1 = new Person("Foo Bar"); 
    Person p2 = new Person("Foo Bar");
    Map<Person, String> map = new HashMap<>();
    map.put(p1, "dummy");
    Assert.assertEquals("dummy", map.get(p2));
}

Apart from @duffymo test for hashcode being reflexive, symmetric, and transitive, another way of testing would be via "Map" which is where hashcodes actually come handy.

 @Test
public void testHashcode() {
    Person p1 = new Person("Foo Bar"); 
    Person p2 = new Person("Foo Bar");
    Map<Person, String> map = new HashMap<>();
    map.put(p1, "dummy");
    Assert.assertEquals("dummy", map.get(p2));
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文