我有一个生成的域对象库(在我的直接控制之外)。在此库中,以下对象位于:
public class SomeObject {
public float someField;
public boolean equals(SomeObject cmp) {
if(someField != cmp.someField)
return false;
return true;
}
}
我想将SomeObject
实例与给定的容差(或类似的“不精确”方法)进行比较。是否有可用于JAVA的库已经执行此操作?
此外,我正在寻找nullSafe实现。
我已经查看了Spring的ObjectUtils和JAVA 7的Objects以及Apache的commons-lang,它们对浮动进行了一些比较,而不是给我提供epsilon。
修改 我不希望库选择容差,因为这需要了解应用程序细节。但是,如果我知道容差值,那么这样的函数可能存在吗?
public boolean equals(Object o1, Object o2, double toleranceToUseForThisComparison)
答案 0 :(得分:3)
没有这样的库例程,并且没有,因为没有通用的方法来比较包含适用于所有应用程序的错误的数字。
数值计算中可能出现的错误类型(无论是浮点还是其他)包括相对于某些已知最终值的错误,绝对错误或相对于某个值而非最终值的错误甚至输入值,这些的组合等等。误差的大小范围可以从零到无穷大,甚至可以是非数字的(当计算过程中的误差产生NaN时)。
为了确定可以容忍的错误,必须知道执行了哪些计算,输入数据和中间值的界限,以及错误地接受相等的两个数字会导致什么危害如果精确计算则不相等,相反,如果精确计算则错误拒绝等于两个数相等。
所有这些都是特定于应用程序的,因此无法通过常规库例程来解决。解决这个问题的大部分工作是分析错误并判断潜在选择的好处和危害。一旦完成这项工作,实际的比较是如此简单(测试两个数字之间的差异是否在判断为可接受的区间内),通过为它提供一个库例程来实现这一点。
有些人将此问题解决为“我们进行数值计算,得到一些错误,错误是由数字舍入引起的,而不是由实际数学引起的,所以让我们忽略它。”但实际问题是“这个程序计算<强>错误的数字;我们如何从错误的数字中得到正确的答案?“
一般情况下,你不能。没有库例程接受错误的数字作为参数,并返回正确的答案作为结果。
总之,您必须查看您的代码和您正在使用的数字,并找出您可以接受的错误。
答案 1 :(得分:0)
equals
关系必须是可传递的。这意味着除非所有数字都相等,否则无法避免两个数字的存在,这两个数字只是无穷小但有所不同。
让对象根据舍入值定义相等可能会有所帮助(独立地舍入值,然后检查它们是否相等),但是,例如,一个集合存储四舍五入到最接近的整数的值,一个想要找到value
的0.1以内的东西,一个应该搜索value+0.1
和value-0.1
[如果它们都是相同的整数,一个只需要搜索一个]。如果该项目存在于集合中,则其中一个搜索将找到它。它也可能找到超过0.1个单位的物品,但是人们可以检查一个找到的物品并简单地拒绝任何不够接近的物品。
答案 2 :(得分:0)
使用名为getFloat(或类似)的方法使对象实现名为ComparableByTolerance的接口。您现在决定该对象如何赋予它浮动。
创建一个名为ToleranceUtils的类
public static class TolerenceUtils {
public float tolerance =0;
public void setTolerance( float tolerance) {
this.tolerance =tolerance;
}
public boolean toleranceCompare(ComparableByTolerance objectWithFloat1,ComparableByTolerance objectWithFloat2){
(objectWithFloat1.getFloat() - objectWithFloat2.getFloat())<=tolerance;
}
}
这样,您可以在比较两者时指定容差。