Java Comparable返回值,是否必须恰好是1、-1或0?
这可能是一个微不足道的问题,但我还没有找到任何相关内容,所以这里是:
实现 Comparable
接口,我们应该定义方法 compareTo()
,以便根据文档,以下内容成立:
sgn(x.compareTo(y)) == -sgn(y.compareTo(x)) 对于所有 x 和 y。
关系是传递的:(x.compareTo(y)>0 && y.compareTo(z)>0) 意味着 x.compareTo(z)>0。
x.compareTo(y)==0 意味着 sgn(x.compareTo(z)) == sgn(y.compareTo(z)),对于所有 z。
现在,令人困惑的部分是返回值,其指定如下:
返回负整数、零或正整数作为该对象 小于、等于或大于指定对象。
似乎大多数实现都返回 1
、-1
或 0
,尽管没有提到返回值限制在这边走。
因此,以下代码适用于对包含类 Foo
的实例的列表进行排序(使用 Collections.sort()
):
public int compareTo(Foo other){
return this.value > other.value? 1 : this.value < other.value ? -1 : 0;
}
但这并不适用:
public int compareTo(Foo other){
return (int)(this.value - other.value);
}
Where value< /code> 是一个
long
,并且值之间的差异不超过Integer.MAX_VALUE
。
我是否在这里遗漏了一些东西,或者返回值是否要求恰好是 1
、-1
或 0
,与文档相矛盾?
更新:感谢您的所有回答,但似乎人为因素是罪魁祸首。我提到计算出的差值小于 Integer.MAX_VALUE
,这应该意味着没有溢出,但我的计算错误,所以我确实得到了溢出,这造成了奇怪的结果。
This might be a trivial question, but I have not found anything about it, so here goes:
When implementing the Comparable
interface, we are supposed to define the method compareTo()
, so that the following is true according to the documentation:
sgn(x.compareTo(y)) == -sgn(y.compareTo(x)) for all x and y.
The relation is transitive: (x.compareTo(y)>0 && y.compareTo(z)>0) implies x.compareTo(z)>0.
x.compareTo(y)==0 implies that sgn(x.compareTo(z)) == sgn(y.compareTo(z)), for all z.
Now, the part that gets confusing is the return value, that is specified as follows:
Returns a negative integer, zero, or a positive integer as this object
is less than, equal to, or greater than the specified object.
It seems that most implementations return 1
, -1
or 0
, even though it is not mentioned as a requirement that the return value is limited in this way.
The following code thus works for Sorting a list (using Collections.sort()
) containing instances of a class, Foo
:
public int compareTo(Foo other){
return this.value > other.value? 1 : this.value < other.value ? -1 : 0;
}
This however do not:
public int compareTo(Foo other){
return (int)(this.value - other.value);
}
Where value
is a long
, and the difference between the values do not exceed Integer.MAX_VALUE
.
Am I missing something here, or is the return value required to be exactly 1
, -1
or 0
, contradictory to the documentation?
Update: Thanks for all your answers, but it seems that the human factor was to blame here. I mentioned that the calculated difference was less than Integer.MAX_VALUE
, which should mean that there is no overflow, but my calculations were wrong, so I did actually get overflow, which caused the strange results.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
该合约非常灵活,允许使用
this.value - other.value
习惯用法(后来由于整数溢出而被证明是不正确的)。但在某些情况下它仍然很有价值,例如 str.length() - str2.length()。由于最小长度为 0,最大长度为Integer.MAX_VALUE
(0 - Integer.MAX_VALUE
),字符串或数组大小比较不太可能会溢出code> 仍然大于Integer.MIN_VALUE
),因此当您需要按长度/大小排序时很方便。此外,与 0(大于/小于)进行比较通常比与 1/-1 进行比较更快/生成更小的字节码/程序集,那么为什么要限制用户呢?您完全可以自由使用任何正/负值。
The contract was so flexible to allow
this.value - other.value
idioms (which later turned out to be incorrect due to integer overflow). But in some cases it is still valueable, likestr.length() - str2.length()
. It isunlikelyimpossible that string or array size comparison will overflow since the minimum length is 0 and the maximum isInteger.MAX_VALUE
(0 - Integer.MAX_VALUE
is still greater thanInteger.MIN_VALUE
) so it is convenient when you need to sort by length/size.Also comparing to 0 (greater-than/less-than) is often faster/genrates smaller bytecode/assembly than comparing to 1/-1, so why limit the users? You are absolutely free to use any positive/negative value.
不,您可以返回任何您想要的整数。您收到的错误到底是什么?
请测试以下类:
我得到以下输出:
您可能需要在
compareTo
方法中添加断点并进行调试以检查是否正在运行您期望的内容。Nope, you can return any integer you want. What exactly is the error you are getting?
Please test the following class:
I get the following output:
You might want to add a breakpoint in your
compareTo
method and debug to check if you are running what you are expecting.Javadoc 还说:
编辑:
是的,我误解了。你是对的。
Javadocs also say:
EDIT:
Yes, i misunderstood. you are right.