简体   繁体   中英

Problem with overriding equals() and hashCode() for a List of Double

I have a class as follows:

public class Data{
   int x;
   ArrayList<Double> list;
}

Now, I want to write unit tests and compare this class with another one merely to check equality. However, I want to allow some room for error so that even if the Doubles are close with respect to some epsilon they're considered equal. Now, if I override the equals() method NetBeans and Sonar prompt me to override the hashCode() method as well which doesn't make any sense. The reason is that it's not feasible to simply implement a hashCode() method that outputs the same hash code value for CLOSE lists.

My question is this:

Should I continue with overriding the equals() method and just override hashCode() for the sake of passing Sonar check? (A dummy implementation for hashCode())

OR

Should I just implement this method to check closeness in my unit tests and not in the actual source code?

This looks like an XY problem.

You are entangled in a non-trivial transitivity issue associated with overriding equals() due to your business rule ( "if the Doubles are close with respect to some epsilon..." ), as pointed out in a comment to the OP.

In fact it is impossible for you to meaningfully implement an equals() method for that rule, because transitivity (" if x.equals(y) returns true and y.equals(z) returns true, then x.equals(z) should return true ") cannot be guaranteed. You might have three Data objects, d1, d2 and d3, where d2 was equal (ie close enough) to both d1 and d3, but d1 was not equal (ie not close enough) to d3.

There is nothing wrong with the rules Java imposes when testing for equality, and there is nothing wrong with your specific condition for determining the equality of your Data instances either. It's just that they are incompatible.

But while there are a bunch of rules you should definitely follow if you go down the equals() path, I don't see anything in your question that indicates you have to override anything. So don't go there.

Why not just create a new method public boolean sameAs(Object other) in the Data class? It can check for equality based on your rule(s), and your unit tests can call that method. Then you have no need or obligation to implement equals() and hashCode() at all.

(Updated on 9/12/19 to clarify why equals() cannot be implemented.)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM