简体   繁体   English

为什么我得到这个异常 java.lang.IllegalArgumentException:比较方法违反了它的一般契约

[英]Why did I get this exception java.lang.IllegalArgumentException: Comparison method violates its general contract

I have this code.我有这个代码。 The getCreatedAt is a long representing the timestamp of the record. getCreatedAt 是一个 long,表示记录的时间戳。

Collections.sort(records, new Comparator<Record>() {
    @Override
    public int compare(Record record1, Record record2) {
        return (int) (record2.getCreatedAt() - record1.getCreatedAt());
    }
});

When I run It with enough data (roughly 200 items in the list).当我用足够的数据运行它时(列表中大约有 200 个项目)。 I start to hit this exception我开始遇到这个异常

java.lang.IllegalArgumentException: Comparison method violates its general contract! java.lang.IllegalArgumentException:比较方法违反了它的一般约定!

Of course, I realized when I wrote this code that it could, in theory, have the integer overflow but feel it was unlikely since the timestamps would be days or weeks apart not decades.当然,当我编写这段代码时,我意识到理论上它可能会出现整数溢出,但我觉得不太可能,因为时间戳相隔几天或几周而不是几十年。

I have now fixed this by always returning 1, -1 or 0 but I am curious why this exception even happened in the first place.我现在通过总是返回 1、-1 或 0 来解决这个问题,但我很好奇为什么这个异常首先发生。

I assume the timestamps are long s, because otherwise you wouldn't need the (int) cast.我假设时间戳是long s,因为否则你不需要(int)

In that case, it's because of overflow.在这种情况下,这是因为溢出。 int can hold values from -2147483648 up to 2147483647. If the subtraction result is bigger or smaller than that, then converting the result to an int causes it to wrap around. int可以保存从 -2147483648 到 2147483647 的值。如果减法结果大于或小于该值,则将结果转换为int会导致它回绕。

For example, if record2.getCreatedAt() is 2147483648, and record1.getCreatedAt() is 0, then your function returns -2147483648 which indicates that record1 is greater (obviously wrong!).例如,如果record2.getCreatedAt()是 2147483648,而record1.getCreatedAt()是 0,那么你的函数返回 -2147483648,这表明 record1 更大(显然是错误的!)。

Now by itself that's okay, it means you'll get things in the wrong order but it shouldn't crash, right?现在这本身没问题,这意味着你会以错误的顺序得到东西,但它不应该崩溃,对吧? Actually, it can cause a crash.实际上,它可能会导致崩溃。

Let's call the one with 2147483648 record A, and the one with 0 record C. If there was another record B in the middle with a timestamp of say 1000000000, then your function says that C comes after A, A comes after B and B comes after C. It's a loop!让我们调用记录 A 为 2147483648 的记录 A 和记录 C 为 0 的记录。如果中间还有另一条记录 B 的时间戳为 1000000000,那么您的函数表示 C 在 A 之后,A 在 B 之后,B 在在 C 之后。这是一个循环! There's no way to sort these!没有办法对这些进行排序!

Some sorting algorithms will return a not-properly-sorted list anyway, but the one that Java uses gets totally confused and throws an exception.一些排序算法无论如何都会返回一个排序不正确的列表,但 Java 使用的排序算法完全混淆并抛出异常。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 线程“AWT-EventQueue-0”中的异常java.lang.IllegalArgumentException:比较方法违反了其总契约 - Exception in thread “AWT-EventQueue-0” java.lang.IllegalArgumentException: Comparison method violates its general contract Java 7:java.lang.IllegalArgumentException:比较方法违反了其一般合同 - Java 7 : java.lang.IllegalArgumentException: Comparison method violates its general contract java.lang.IllegalArgumentException:比较方法违反了它的一般约定,在 java7 中给出了错误 - java.lang.IllegalArgumentException: Comparison method violates its general contract giving Error in java7 Java sort抛出java.lang.IllegalArgumentException:比较方法违反了其一般合同 - Java sort throws java.lang.IllegalArgumentException: Comparison method violates its general contract Java 错误:java.lang.IllegalArgumentException:比较方法违反其一般约定 - Java Error: java.lang.IllegalArgumentException: Comparison method violates its general contract Java Rest Template throws java.lang.IllegalArgumentException: Comparison method violates its general contract - Java Rest Template throws java.lang.IllegalArgumentException: Comparison method violates its general contract java.lang.IllegalArgumentException:比较方法违反了它的一般约定! 日期 - java.lang.IllegalArgumentException: Comparison method violates its general contract! java.util.Date 错误:java.lang.IllegalArgumentException:即使使用替代方法,比较方法也违反了其常规协定 - Error: java.lang.IllegalArgumentException: Comparison method violates its general contract even using workaround 随机错误-java.lang.IllegalArgumentException:比较方法违反了其一般约定 - Random error - java.lang.IllegalArgumentException: Comparison method violates its general contract 获取java.lang.IllegalArgumentException:比较方法违反了其一般约定! 排序算法应该是100%稳定的 - Getting java.lang.IllegalArgumentException: Comparison method violates its general contract! with a sort algo that should be 100% stable
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM