我希望使用定义的公差 (epsilon
) 为实数(目前为 Double
)创建一个 HashSet
,(cf Assert.assertEquals(double, double, double)
由于使用 Double.equals()
仅适用于完全相等,而 Double
是最终类,我不能使用它。我最初的想法是使用 setEpsilon(double)
方法扩展 HashSet
(例如 DoubleHashSet
)并创建一个新类 ComparableDouble
其中 equals()
使用 DoubleHashSet
中的这个值。但是,我想检查是否已经存在现有的解决方案和现有的 F/OSS 库。
(将来我想将其扩展到实数元组 - 例如矩形和立方体 - 所以通用方法更可取
注意:@NPE 表示这是不可能的。不幸的是,我怀疑这正式是正确的:-) 所以我想知道是否有近似的方法......其他人一定有过这个问题并近似地解决了它。 (我已经经常使用工具 Real.isEqual(a, b, epsilon)
并且它非常有用。)我准备接受一些不常见的传递性错误。
注意:我将使用 TreeSet 来解决“几乎等于()”的问题。稍后我将比较 complexNumbers、矩形(和更复杂的对象),能够设置两个事物相等的限制非常有用。复数没有简单的自然排序(也许 Cantor 方法可行),但我们可以判断它们是否几乎相等。
最佳答案
这种方法存在一些根本性缺陷。
HashSet
使用 equals()
检查两个元素是否相等。 The contract on equals()
has the following among its requirements :
It is transitive: for any non-null reference values
x
,y
, andz
, ifx.equals(y)
returnstrue
andy.equals(z)
returnstrue
, thenx.equals(z)
should returntrue
.
现在考虑下面的例子:
x = 0.0
y = 0.9 * epsilon
z = 1.8 * epsilon
很明显,您提出的比较方案会破坏传递性要求(x
等于 y
并且 y
等于 z
,但 x
不等于 z
)。在这些情况下,HashSet
无法正常运行。
此外,hashCode()
将产生额外的挑战,原因如下 requirement :
If two objects are equal according to the
equals(Object)
method, then calling thehashCode
method on each of the two objects must produce the same integer result.
hashCode()
要求可以通过使用 TreeSet
而不是 HashSet
来回避。
关于java - 为 double 创建哈希集,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15997637/