我正在尝试实现一个比较器,考虑到要比较的对象 (Word
) 有两个定义为 int
的属性。
我想得到这两个值的标准偏差(可能更多,但现在是 2),并根据对象的最低值对我的列表进行排序。但显然,它说我的方法不是基于 this question 的传递。 (我想,因为我有同样的异常(exception))。但是我看不出如何,这里只会比较标准差的结果。
我是否对数学感到困惑,没有考虑指出此方法不可传递或我做错了什么的特殊情况?
排序列表:
for(Map.Entry<String,List<Word>> entry: list.entrySet()){
Collections.sort(entry.getValue(), Collections.reverseOrder(new SimpleComparator()));
...
}
比较器类:
import java.util.Comparator;
public class SimpleComparator implements Comparator<Word> {
@Override
public int compare(Word word1, Word word2) {
int b1,b2,f1,f2;
double average1,average2, result1,result2;
b1 = word1.getAttr1();
b2 = word2.getAttr1();
f1 = word1.getAttr2();
f2 = word2.getAttr2();
average1 = (b1-f1)/2;
average2 = (b2-f2)/2;
result1 = Math.sqrt((Math.pow(b1-average1,2)+Math.pow(f1-average1,2))/2);
result2 = Math.sqrt((Math.pow(b2-average2,2)+Math.pow(f2-average2,2))/2);
return (int)(result1 - result2);
}
}
最佳答案
您应该使用 Math.signum(result1 - result2)
,如果结果为负,则生成 -1,如果结果为零,则生成 0,如果结果为正,则生成 1。确保将结果保留为 double - 将 double 转换为 int 时发生的截断会产生不准确的结果。
相反,将您的返回语句替换为:
return (int) Math.signum( result1 - result2 );
在这种情况下,0.9 - 0.3
的结果将为 0.6
,其符号将为 1
。但是,如果我们将 double 0.6
转换为 int,结果将是 0
,而不是 1
,这表明它们是相等的。然而,我们知道这不是真的。这样做的原因是,当将数字数据类型转换为较低精度的一种时,该值不会四舍五入——它只是失去了精度,这意味着小数点后的值会下降。
请参阅 Comparator.comare(T, T) 的 JavaDocs|
The implementor must ensure that sgn(compare(x, y)) == -sgn(compare(y, x)) for all x and y.
关于java - 标准差不传递?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26879776/