自动检查equals,hashCode和compareTo的一致性的技巧?

时间:2021-03-05 16:47:58

I'm well aware of the contractual needs to make sure that hashCode is consistent with equals and that equals is consistent with compareTo. However, this is often violated in practice. Are there any tools, techniques, or libraries that can test for this consistency automatically?

我很清楚合同需要确保hashCode与equals一致,并且equals与compareTo一致。但是,这在实践中经常被违反。是否有可以自动测试此一致性的工具,技术或库?

I suspect unfortunately that the answer is "no," but it would be useful to be able to have a unit test for this sort of thing that could make use of a library call or framework rather than needing to write a custom test by hand for each case where it is important.

我怀疑不幸的是答案是“不”,但能够对这种可以利用库调用或框架的东西进行单元测试而不是需要手动编写自定义测试是有用的。每个重要的案例。

In case it's not clear what I mean by consistency, for hashCode and equals I refer to the following:

如果不清楚我的一致性是什么意思,对于hashCode和equals,请参考以下内容:

If two objects are equal according to the equals(Object) method, then calling the hashCode method on each of the two objects must produce the same integer result.

如果两个对象根据equals(Object)方法相等,则对两个对象中的每一个调用hashCode方法必须生成相同的整数结果。

For equals and compareTo I refer to the following:

对于equals和compareTo我参考以下内容:

The natural ordering for a class C is said to be consistent with equals if and only if e1.compareTo(e2) == 0 has the same boolean value as e1.equals(e2) for every e1 and e2 of class C.

当且仅当e1.compareTo(e2)== 0具有与c的每个e1和e2的e1.equals(e2)相同的布尔值时,C类的自然排序被认为与equals一致。

5 个解决方案

#1


12  

Guava's tests have a utility called EqualsTester which we use as an everyday part of our unit tests to test equals and hashCode. Its use looks like

Guava的测试有一个名为EqualsTester的实用程序,我们将其用作单元测试的日常部分来测试equals和hashCode。它的用途看起来像

new EqualsTester()
  .addEqualityGroup("hello", "h" + "ello")
  .addEqualityGroup("world", "wor" + "ld")
  .addEqualityGroup(2, 1 + 1)
  .testEquals();

which tests that all values in the same group are equal and have the same hash codes, that different groups are not equal, and that various other invariants are all satisfied. You could either use it yourself, or just borrow its ideas.

它测试同一组中的所有值是相等的并且具有相同的哈希码,不同的组不相等,并且满足各种其他不变量。您既可以自己使用它,也可以借用它的想法。

I would be extremely surprised if it was possible to test without generating or explicitly specifying test values, just because that seems very likely equivalent to the halting problem.

如果可以在不生成或明确指定测试值的情况下进行测试,我会非常惊讶,因为这似乎很可能等同于暂停问题。

#2


5  

If you're using JUnit, the extensions package has the EqualsHashCodeTestCase, which fully tests both equals and hashCode for everything outlined in the Java spec (reflexive, transitive, symmetric, etc). All you have to do is provide an equal and not equal object for the parent class to use for checking.

如果你正在使用JUnit,那么扩展包就有了EqualsHashCodeTestCase,它可以完全测试equals和hashCode,以及Java规范中列出的所有内容(自反,传递,对称等)。您所要做的就是为父类提供一个相等且不相等的对象来用于检查。

Since the CompareTo method is part of the Comparable interface, it's actually split out into another test case - the ComparabilityTestCase. This takes three objects - one of lesser value, equal value, and greater value. Override these and the parent class will take care of the rest.

由于CompareTo方法是Comparable接口的一部分,因此它实际上分为另一个测试用例--ComparabilityTestCase。这需要三个对象 - 一个较小的值,相等的值和更大的值。覆盖这些,父类将负责其余部分。

#3


1  

I have written some utility methods to help unit testing hashCode and equals methods:

我编写了一些实用工具方法来帮助单元测试hashCode和equals方法:

http://softsmithy.sourceforge.net/devlib/docs/api/org/softsmithy/devlib/junit/Tests.html

http://softsmithy.sourceforge.net/devlib/docs/api/org/softsmithy/devlib/junit/Tests.html

The library is Open Source and can be downloaded from here: http://sourceforge.net/projects/softsmithy/files/softsmithy-devlib/v0.1/

该库是开源的,可以从这里下载:http://sourceforge.net/projects/softsmithy/files/softsmithy-devlib/v0.1/

or with Maven:

或与Maven:

    <dependency>
        <groupId>org.softsmithy.devlib</groupId>
        <artifactId>devlib-core</artifactId>
        <version>0.1</version>
        <scope>test</scope>
    </dependency>

#4


1  

There is a very cool tool called Korat that can do exhaustive searches to check the correctness of Java classes for small cases. It actually looks at the code that's executed in order to build all the different test cases of a given size that the program can actually distinguish between. I don't know how useful it is in large cases, but for many programs it can be used to automatically check whether cases like this work correctly.

有一个非常酷的工具叫做Korat,可以进行详尽的搜索,以检查小类的Java类的正确性。它实际上是查看为了构建程序可以实际区分的给定大小的所有不同测试用例而执行的代码。我不知道它在大型情况下有多大用处,但对于许多程序,它可以用来自动检查这样的情况是否正常工作。

Hope this helps!

希望这可以帮助!

#5


1  

I’ve recently used meanbean (http://meanbean.sourceforge.net/) to automatically test a class for the equals() and hashCode() contracts (plus setter/getter pairs).

我最近使用meanbean(http://meanbean.sourceforge.net/)自动测试equals()和hashCode()契约的类(加上setter / getter对)。

"Mean Bean:

“卑鄙的豆子:

1. Tests that the getter and setter method pairs of a JavaBean/POJO function correctly.

2. Verifies that the equals and hashCode methods of a class comply with the Equals Contract and HashCode Contract respectively.

3. Verifies property significance in object equality."

I still have a lot of questions specific to meanbean: whether it verifies equals() and hashCode() consistency. Plus I haven’t tried hard to defeat it. I believe it has no support for compareTo(). And I haven’t tried alternatives. Interested in other's experience.

我仍然有很多特定于meanbean的问题:它是否验证了equals()和hashCode()的一致性。另外,我没有努力打败它。我相信它不支持compareTo()。而我还没有尝试过替代方案。对其他人的体验感兴趣。

#1


12  

Guava's tests have a utility called EqualsTester which we use as an everyday part of our unit tests to test equals and hashCode. Its use looks like

Guava的测试有一个名为EqualsTester的实用程序,我们将其用作单元测试的日常部分来测试equals和hashCode。它的用途看起来像

new EqualsTester()
  .addEqualityGroup("hello", "h" + "ello")
  .addEqualityGroup("world", "wor" + "ld")
  .addEqualityGroup(2, 1 + 1)
  .testEquals();

which tests that all values in the same group are equal and have the same hash codes, that different groups are not equal, and that various other invariants are all satisfied. You could either use it yourself, or just borrow its ideas.

它测试同一组中的所有值是相等的并且具有相同的哈希码,不同的组不相等,并且满足各种其他不变量。您既可以自己使用它,也可以借用它的想法。

I would be extremely surprised if it was possible to test without generating or explicitly specifying test values, just because that seems very likely equivalent to the halting problem.

如果可以在不生成或明确指定测试值的情况下进行测试,我会非常惊讶,因为这似乎很可能等同于暂停问题。

#2


5  

If you're using JUnit, the extensions package has the EqualsHashCodeTestCase, which fully tests both equals and hashCode for everything outlined in the Java spec (reflexive, transitive, symmetric, etc). All you have to do is provide an equal and not equal object for the parent class to use for checking.

如果你正在使用JUnit,那么扩展包就有了EqualsHashCodeTestCase,它可以完全测试equals和hashCode,以及Java规范中列出的所有内容(自反,传递,对称等)。您所要做的就是为父类提供一个相等且不相等的对象来用于检查。

Since the CompareTo method is part of the Comparable interface, it's actually split out into another test case - the ComparabilityTestCase. This takes three objects - one of lesser value, equal value, and greater value. Override these and the parent class will take care of the rest.

由于CompareTo方法是Comparable接口的一部分,因此它实际上分为另一个测试用例--ComparabilityTestCase。这需要三个对象 - 一个较小的值,相等的值和更大的值。覆盖这些,父类将负责其余部分。

#3


1  

I have written some utility methods to help unit testing hashCode and equals methods:

我编写了一些实用工具方法来帮助单元测试hashCode和equals方法:

http://softsmithy.sourceforge.net/devlib/docs/api/org/softsmithy/devlib/junit/Tests.html

http://softsmithy.sourceforge.net/devlib/docs/api/org/softsmithy/devlib/junit/Tests.html

The library is Open Source and can be downloaded from here: http://sourceforge.net/projects/softsmithy/files/softsmithy-devlib/v0.1/

该库是开源的,可以从这里下载:http://sourceforge.net/projects/softsmithy/files/softsmithy-devlib/v0.1/

or with Maven:

或与Maven:

    <dependency>
        <groupId>org.softsmithy.devlib</groupId>
        <artifactId>devlib-core</artifactId>
        <version>0.1</version>
        <scope>test</scope>
    </dependency>

#4


1  

There is a very cool tool called Korat that can do exhaustive searches to check the correctness of Java classes for small cases. It actually looks at the code that's executed in order to build all the different test cases of a given size that the program can actually distinguish between. I don't know how useful it is in large cases, but for many programs it can be used to automatically check whether cases like this work correctly.

有一个非常酷的工具叫做Korat,可以进行详尽的搜索,以检查小类的Java类的正确性。它实际上是查看为了构建程序可以实际区分的给定大小的所有不同测试用例而执行的代码。我不知道它在大型情况下有多大用处,但对于许多程序,它可以用来自动检查这样的情况是否正常工作。

Hope this helps!

希望这可以帮助!

#5


1  

I’ve recently used meanbean (http://meanbean.sourceforge.net/) to automatically test a class for the equals() and hashCode() contracts (plus setter/getter pairs).

我最近使用meanbean(http://meanbean.sourceforge.net/)自动测试equals()和hashCode()契约的类(加上setter / getter对)。

"Mean Bean:

“卑鄙的豆子:

1. Tests that the getter and setter method pairs of a JavaBean/POJO function correctly.

2. Verifies that the equals and hashCode methods of a class comply with the Equals Contract and HashCode Contract respectively.

3. Verifies property significance in object equality."

I still have a lot of questions specific to meanbean: whether it verifies equals() and hashCode() consistency. Plus I haven’t tried hard to defeat it. I believe it has no support for compareTo(). And I haven’t tried alternatives. Interested in other's experience.

我仍然有很多特定于meanbean的问题:它是否验证了equals()和hashCode()的一致性。另外,我没有努力打败它。我相信它不支持compareTo()。而我还没有尝试过替代方案。对其他人的体验感兴趣。