我有一个课程,我已将其简化为:
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
的两个参数形式。
这适用于我的测试用例,但有时它会以一个奇怪但可重复的顺序结束。 怎么会这样?
答案 0 :(得分:20)
整数溢出......或更确切地说,下溢。
相反,做一个明确的比较:
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);
}
};
如果您确定差异不会“环绕”,则使用减法很好。例如,当有问题的数据被限制为非负数时。
答案 1 :(得分:15)
您无法使用减号来创建比较。当绝对差值超过Integer.MAX_VALUE
时,你会溢出。
相反,请使用此算法:
int compareInts( int x, int y ) {
if ( x < y ) return -1;
if ( x > y ) return 1;
return 0;
}
我喜欢在图书馆中使用此功能来实现此目的。
答案 2 :(得分:5)
试
System.out.println(Integer.MAX_Value - Integer.MIN_VALUE);
这需要返回正数,如MAX_VALUE&gt; MIN_VALUE但是打印-1
答案 3 :(得分:5)
在比较Java原语时,建议将它们转换为Object对象并依赖于compareTo()
方法。
在这种情况下,你可以这样做:
return Integer.valueOf(a.getValue()).compareTo(b.getValue())
如有疑问,请使用经过充分测试的图书馆。
答案 4 :(得分:3)
你扔在那里的是什么数字?如果你的数字足够大,你可以用整数的MIN / MAX值换行,最后就会搞得一团糟。
答案 5 :(得分:2)
如果a的值非常负,且b的值非常正,则答案将非常错误。
IIRC,Int溢出在JVM中无声地环绕
- MarkusQ