为什么我的简单比较器坏了?
我有一个类,我已将其简化为:
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 的两个参数形式。
这对于我的测试用例来说效果很好,但有时会出现问题,数组以奇怪但可重复的顺序结束。 怎么会这样?
I have a class, which I have simplified to this:
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);
}
}
I want to sort an array of this thing. So I have created a simple copmarator:
private static final Comparator<Thing> reverse = new Comparator<Thing>() {
public int compare(Thing a, Thing b) {
return a.getValue() - b.getValue();
}
};
I then use the two argument form of Arrays.sort
.
This works fine for my test cases, but sometimes it goes all wrong with the array ending up in a strange but repeatable order.
How can this be?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
你在那里输入什么样的数字? 如果您的数字足够大,您可能会遍历整数的 MIN/MAX 值并最终陷入混乱。
What kind of numbers do you throw in there? If your numbers are large enough, you could wrap through the MIN/MAX values for integers and end up in a mess.
如果a的值非常负并且b的值非常正,那么你的答案将是非常错误的。
IIRC,Int 溢出在 JVM 中悄无声息地缠绕
——MarkusQ
If a's value is very negative and b's value is very positive your answer will be very wrong.
IIRC, Int overflow silently wraps around in the JVM
-- MarkusQ
try
这需要返回一个正数,因为 MAX_VALUE > MIN_VALUE 但打印 -1
try
This needs to return a positive number as MAX_VALUE > MIN_VALUE but instead prints -1
比较 Java 基元时,建议将它们转换为对应的对象并依赖其
compareTo()
方法。在这种情况下,您可以这样做:
如有疑问,请使用经过良好测试的库。
When comparing Java primitives, it is advisable to convert them to their Object counterparts and rely on their
compareTo()
methods.In this case you can do:
When in doubt, use a well-tested library.
您不能使用减号来创建比较。 当绝对差值超过
Integer.MAX_VALUE
时,就会溢出。相反,请使用此算法:
我喜欢在库中将此函数用于此类目的。
You cannot use minus to create the comparison. You'll overflow when the absolute difference exceeds
Integer.MAX_VALUE
.Instead, use this algorithm:
I like to have this function in a library for such purposes.
整数溢出……或更准确地说,下溢。
相反,进行显式比较:
如果您确定差异不会“环绕”,则可以使用减法。 例如,当所讨论的值被限制为非负时。
Integer overflow… or more precisely, underflow.
Instead, do an explicit comparison:
Using subtraction is fine if you are sure that the difference won't "wrap around". For example, when the values in question are constrained to be non-negative.