Java Comparable返回值,它必须是1,-1还是0?

时间:2012-02-01 11:17:51

标签: java comparable

这可能是一个微不足道的问题,但我还没有找到任何关于它的内容,所以这里有:
在实现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-10,即使没有提到返回值以这种方式受到限制的要求。
因此,以下代码适用于对包含类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);
}

其中valuelong,且值之间的差异不超过Integer.MAX_VALUE

我是否在此处遗漏了某些内容,或者返回值是1-1还是0,与文档相矛盾?

更新:感谢您的所有答案,但似乎人为因素应该归咎于此。我提到计算的差异小于Integer.MAX_VALUE,这应该意味着没有溢出,但我的计算是错误的,所以我确实得到了溢出,这导致了奇怪的结果。

3 个答案:

答案 0 :(得分:7)

合同非常灵活,允许this.value - other.value成语(后来由于整数溢出而变得不正确)。但在某些情况下,它仍然有价值,如str.length() - str2.length()。由于最小长度为0且最大值为Integer.MAX_VALUE0 - 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 之一,零或正面。

编辑:

是的,我误解了。你是对的。