Java Comparable返回值,是否必须恰好是1、-1或0?

发布于 2025-01-01 07:39:05 字数 1420 浏览 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-10,尽管没有提到返回值限制在这边走。
因此,以下代码适用于对包含类 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-10,与文档相矛盾?

更新:感谢您的所有回答,但似乎人为因素是罪魁祸首。我提到计算出的差值小于 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

想你只要分分秒秒 2025-01-08 07:39:05

该合约非常灵活,允许使用 this.value - other.value 习惯用法(后来由于整数溢出而被证明是不正确的)。但在某些情况下它仍然很有价值,例如 str.length() - str2.length()。由于最小长度为 0,最大长度为 Integer.MAX_VALUE0 - 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, like str.length() - str2.length(). It is unlikely impossible that string or array size comparison will overflow since the minimum length is 0 and the maximum is Integer.MAX_VALUE (0 - Integer.MAX_VALUE is still greater than Integer.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.

情仇皆在手 2025-01-08 07:39:05

不,您可以返回任何您想要的整数。您收到的错误到底是什么?

请测试以下类:

  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 方法中添加断点并进行调试以检查是否正在运行您期望的内容。

Nope, you can return any integer you want. What exactly is the error you are getting?

Please test the following class:

  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;
        }
    }

I get the following output:

run:
Unsorted:[100, 1, -100]
Sorted:[-100, 1, 100] 
BUILD SUCCESSFUL (total time: 0 seconds)

You might want to add a breakpoint in your compareTo method and debug to check if you are running what you are expecting.

望喜 2025-01-08 07:39:05

Javadoc 还说:

在前面的描述中,符号sgn(表达式)表示数学符号函数,定义为根据表达式的值是否为负数返回-1、0或1之一 ,零或正数。

编辑:

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

Javadocs also say:

In the foregoing description, the notation sgn(expression) designates the mathematical signum function, which is defined to return one of -1, 0, or 1 according to whether the value of expression is negative, zero or positive.

EDIT:

Yes, i misunderstood. you are right.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文