这可能是一个微不足道的问题,但我还没有找到任何关于它的内容,所以这里有:
在实现Comparable
接口时,我们应该定义方法compareTo()
,以便根据文档提供以下内容:
所有x和y的
sgn(x.compareTo(y))== - sgn(y.compareTo(x))。
该关系是及物的:(x.compareTo(y)> 0& y.compareTo(z)> 0)暗示x.compareTo(z)> 0.
x.compareTo(y)== 0表示对于所有z,sgn(x.compareTo(z))== sgn(y.compareTo(z))。
现在,令人困惑的部分是返回值,具体如下:
返回负整数,零或正整数作为此对象 小于,等于或大于指定的对象。
似乎大多数实现返回1
,-1
或0
,即使没有提到返回值以这种方式受到限制的要求。
因此,以下代码适用于对包含类Collections.sort()
的实例的列表(使用Foo
)进行排序:
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);
}
其中value
为long
,且值之间的差异不超过Integer.MAX_VALUE
。
我是否在此处遗漏了某些内容,或者返回值是1
,-1
还是0
,与文档相矛盾?
更新:感谢您的所有答案,但似乎人为因素应该归咎于此。我提到计算的差异小于Integer.MAX_VALUE
,这应该意味着没有溢出,但我的计算是错误的,所以我确实得到了溢出,这导致了奇怪的结果。
答案 0 :(得分:7)
合同非常灵活,允许this.value - other.value
成语(后来由于整数溢出而变得不正确)。但在某些情况下,它仍然有价值,如str.length() - str2.length()
。由于最小长度为0且最大值为Integer.MAX_VALUE
(0 - Integer.MAX_VALUE
仍然大于Integer.MIN_VALUE
),字符串或数组大小比较将不会溢出不可能所以当你需要按长度/大小排序时很方便。
与0(大于/小于)相比,通常比1 / -1更快/生成更小的字节码/汇编,那么为什么要限制用户呢?您可以完全自由地使用任何正/负值。
答案 1 :(得分:1)
不,你可以返回你想要的任何整数。你得到的错误究竟是什么?
请测试以下课程:
public static void main(String[] args) {
final ToSort sort0 = new ToSort(-100);
final ToSort sort1 = new ToSort(1);
final ToSort sort2 = new ToSort(100);
List<ToSort> elements = new ArrayList<ToSort>(){{add(sort2); add(sort1); add(sort0);}};
System.out.println("Unsorted:" + elements.toString());
Collections.sort(elements);
System.out.println("Sorted:" + elements.toString());
}
static class ToSort implements Comparable{
long value;
public ToSort(long value){
this.value = value;
}
@Override
public int compareTo(Object other) {
return (int) (this.value - ((ToSort)other).value);
}
public String toString(){
return ""+value;
}
}
我得到以下输出:
run:
Unsorted:[100, 1, -100]
Sorted:[-100, 1, 100]
BUILD SUCCESSFUL (total time: 0 seconds)
您可能希望在compareTo
方法中添加断点并进行调试,以检查您是否正在运行您期望的内容。
答案 2 :(得分:-1)
Javadocs还说:
在前面的描述中,符号sgn(表达式)指定数学符号函数,根据表达式的值是否为负,定义为返回-1,0或1 之一,零或正面。
编辑:
是的,我误解了。你是对的。