为 Double 列表覆盖 equals() 和 hashCode() 的问题

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

我有一个class如下:

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

现在,我想编写单元测试并将这个 class 与另一个进行比较,只是为了检查是否相等。但是,我想留出一些错误空间,这样即使双打 接近某些 epsilon,它们也被认为是相等的。现在,如果我重写 equals() 方法,NetBeans 和 Sonar 也会提示我重写 hashCode() 方法,这没有任何意义。原因是简单地实现一个为 CLOSE 列表输出相同哈希码值的 hashCode() 方法是不可行的。

我的问题是:

我是否应该继续覆盖 equals() 方法并只覆盖 hashCode() 以便通过 Sonar 检查? (hashCode() 的虚拟实现)

我是否应该只在我的单元测试中而不是在实际源代码中实施此方法来检查接近度?

这看起来像一个 XY 问题。

由于您的业务规则 ("if the Doubles are close with respect to some epsilon..."),您陷入了与覆盖 equals() 相关的重要传递性问题,正如在对 OP 的评论。

事实上,您不可能为该规则有意义地实现 equals() 方法,因为传递性 ("if x.equals(y) returns true 且 y.equals(z) returns 为真,则 x.equals(z) 应 return true") 无法保证。您可能有三个 Data 对象,d1、d2 和 d3,其中 d2 等于(即足够接近)d1 和 d3,但 d1 不等于(即不够接近)d3。

Java 在测试相等性时施加的规则没有任何问题,并且您确定 Data 实例是否相等的特定条件也没有任何问题。只是不相容而已。

但是当 there are a bunch of rules you should definitely follow if 你走 equals() 路径时,我在你的问题中没有看到任何表明你必须覆盖任何东西的东西.所以不要去那里。

为什么不直接在 Data class 中创建一个新方法 public boolean sameAs(Object other)?它可以根据您的规则检查是否相等,并且您的单元测试可以调用该方法。那么你根本没有必要也没有义务实施 equals()hashCode()

(于 2019 年 9 月 12 日更新,以阐明无法实施 equals() 的原因。)