题
我有一个课程,我已将其简化为:
final class Thing {
private final int value;
public Thing(int value) {
this.value = value;
}
public int getValue() {
return value;
}
@Override public String toString() {
return Integer.toString(value);
}
}
我想对这个东西的数组进行排序。所以我创建了一个简单的copmarator:
private static final Comparator<Thing> reverse = new Comparator<Thing>() {
public int compare(Thing a, Thing b) {
return a.getValue() - b.getValue();
}
};
然后我使用 Arrays.sort
的两个参数形式。
这适用于我的测试用例,但有时它会以一个奇怪但可重复的顺序结束。 怎么会这样?
解决方案
整数溢出&#8230;或者更准确地说,是下溢。
相反,做一个明确的比较:
private static final Comparator<Thing> reverse = new Comparator<Thing>() {
public int compare(Thing a, Thing b) {
int av = a.getValue(), bv = b.getValue();
return (av == bv) ? 0 : ((av < bv) ? -1 : +1);
}
};
如果您确定差异不会“环绕”,则使用减法就可以了。例如,当有问题的数据被限制为非负数时。
其他提示
您无法使用减号来创建比较。当绝对差值超过 Integer.MAX_VALUE
。
相反,请使用此算法:
int compareInts( int x, int y ) {
if ( x < y ) return -1;
if ( x > y ) return 1;
return 0;
}
我喜欢在图书馆中使用此功能来实现此目的。
试
System.out.println(Integer.MAX_Value - Integer.MIN_VALUE);
这需要返回正数,如MAX_VALUE&gt; MIN_VALUE但是打印-1
在比较Java原语时,建议将它们转换为Object对象并依赖它们的 compareTo()
方法。
在这种情况下,你可以这样做:
return Integer.valueOf(a.getValue()).compareTo(b.getValue())
如有疑问,请使用经过充分测试的图书馆。
你扔在那里的是什么数字?如果你的数字足够大,你可以用整数的MIN / MAX值换行,最后就会搞得一团糟。
如果a的值非常负,且b的值非常正,则答案将非常错误。
IIRC,Int溢出在JVM中无声地环绕
- MarkusQ
不隶属于 StackOverflow