java - 可比接口(interface)取决于大小?

标签 java comparable

我在 Comparable 接口(interface)上工作,发现当我将 size=50 放入下面的程序中并且正在运行时,它会抛出 IllegalArgumentException当我输入 size =5 时很好。

    public class Test {
    public static void main(String[] args) {
        int size = 50;
        Test compareTest = new Test();
        compareTest.test(size);
    }

    public void test(int size) {
        List<TestObject> requests = new ArrayList<TestObject>();
        for (int index = 0; index < size; index++) {
            TestObject request = new TestObject();
            request.value = index;
            requests.add(request);
        }
        Collections.sort(requests);
    }

}

class TestObject implements Comparable<TestObject> {
    public int value;

    public int compareTo(TestObject req) {
        if (value % 3 == 0) {
            return -1;
        } else if (value % 3 == 1) {
            return 0;
        }

        return 1;
    }
}

我不确定这个问题的根本原因,有人可以帮我解决这个问题吗。

异常堆栈跟踪如下。

Exception in thread "main" java.lang.IllegalArgumentException: Comparison method violates its general contract!
    at java.util.ComparableTimSort.mergeLo(ComparableTimSort.java:744)
    at java.util.ComparableTimSort.mergeAt(ComparableTimSort.java:481)
    at java.util.ComparableTimSort.mergeCollapse(ComparableTimSort.java:406)
    at java.util.ComparableTimSort.sort(ComparableTimSort.java:213)

最佳答案

您违反了 Comparable 契约(Contract)。

实际上你不比较两个对象,你只是比较当前TestObject对象的value字段,根据对3取模的结果。你不在 compareTo() 方法中不要使用作为参数传递的 TestObject 对象。

假设您有一个包含两个 TestObject 对象的 List3 作为 value 字段

这两个对象将返回 -1 :

    if (value % 3 == 0) {
        return -1;
    } 

但是根据规则:

The implementor must ensure sgn(x.compareTo(y)) == -sgn(y.compareTo(x)) for all x and y. (This implies that x.compareTo(y) must throw an exception iff y.compareTo(x) throws an exception.)

假设第一个对象是x,第二个对象是y
如果 y.compareTo(x) 返回一个负数(例如 -1),那么 x.compareTo(y) 应该返回一个正数(例如 1)。

I was working on Comparable interface and found that it is throwing IllegalArgumentException when i put size=50 in the program below and is working fine when i put size =5

事实上,当您违反Comparable 契约时,结果是不可预测的。它可能适用于某些特定值,不适用于其他特定值。
它可能在特定的 JVM 版本中工作,而在另一个版本中不工作。
试图理解为什么它失败或成功的特定值可能很有趣,但实际上没有帮助。
努力理解契约(Contract)以尊重它要好得多。 因为今天它正在运行,但明天在未来的实现中,它可能会改变。只有 API 是保证。

关于java - 可比接口(interface)取决于大小?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44321624/

相关文章:

java.util.Random 使计算速度提高 100 倍?

java - 为什么在下面的线程代码中,for 循环比 if 迭代更多的素数

java - Collections.sort、Enum、Comparable接口(interface)问题

java - 如何实现自定义对象的 Compare to 方法

java - 开箱即用的 Java 直接比较器

java - OSX 上 JAR 文件的推荐位置

java - Mapstruct:如何将两个字段合并为一个

java - 在Java中以通用方式实现comprable方法进行排序

java - 为什么这个数组会不一致地越界?

java - 资源文件在构建Java 9模块的Gradle项目中位于何处?