gpt4 book ai didi

java.lang.IllegalArgumentException : Comparison method violates its general contract! java.util.Date

转载 作者:塔克拉玛干 更新时间:2023-11-03 05:08:55 26 4
gpt4 key购买 nike

java.lang.IllegalArgumentException: Comparison method violates its general contract!
at java.util.TimSort.mergeLo(TimSort.java:747)
at java.util.TimSort.mergeAt(TimSort.java:483)
at java.util.TimSort.mergeCollapse(TimSort.java:410)
at java.util.TimSort.sort(TimSort.java:214)
at java.util.TimSort.sort(TimSort.java:173)
at java.util.Arrays.sort(Arrays.java:659)
at java.util.Collections.sort(Collections.java:217)

我正在根据以下比较器对集合进行排序。

public static Comparator<MyClass> CMP_TIME_DESC = new Comparator<MyClass>() {
@Override
public int compare(MyClass o1, MyClass o2) {
return o2.getOrderSendTime().compareTo(o1.getOrderSendTime());
}
};

值总是非空的。getOrderSendTime() 对象属于 java.util.Date 类。

我知道这是一种传递性不一致,我认为像这样的类不会有这样的问题。我搜索了 Unresolved 问题,但没有找到与该主题相关的任何问题。

有什么想法吗?

最佳答案

我有同样的异常,当我在排序时在同一个列表/数组中有 java.util.Datejava.sql.Timestamp 对象时发生, 在 Java8 上运行。 (这种混合是由于一些对象是从具有 Timestamp 数据类型的数据库记录中加载的,而其他对象是手动创建的,并且这些对象中只有一个 Date 对象。 )

每次对同一数据集进行排序时也不会发生异常,并且似乎数组中至少还必须有 32 个这样的混合对象才能发生。

如果我使用传统的排序算法,这也不会发生(请参阅 Ortomala Lokni 的回答)。

如果您仅使用数组中的 java.util.Date 对象或仅使用 java.sql.Timestamp 对象,这也不会发生。

因此,问题似乎是 TimSortjava.util.Datejava.sql.Timestamp 中的 compareTo 方法相结合。

但是,由于它已在 Java 9 中修复,因此我没有必要研究为什么会发生这种情况!

作为 Java9 发布之前的解决方法,我们可以更新我们的系统,我们手动实现了一个仅使用 getTime()Comparator。这似乎工作正常。

这是可用于重现问题的代码:

import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import org.junit.Test;

public class TimSortDateAndTimestampTest {

// the same test data with all Dates, all Timestamps, all Strings or all Longs does NOT fail.
// only fails with mixed Timestamp and Date objects
@Test
public void testSortWithTimestampsAndDatesFails() throws Exception {
List<Date> dates = new ArrayList<>();
dates.add(new Timestamp(1498621254602L));
dates.add(new Timestamp(1498621254603L));
dates.add(new Timestamp(1498621254603L));
dates.add(new Timestamp(1498621254604L));
dates.add(new Timestamp(1498621254604L));
dates.add(new Timestamp(1498621254605L));
dates.add(new Timestamp(1498621254605L));
dates.add(new Timestamp(1498621254605L));
dates.add(new Timestamp(1498621254605L));
dates.add(new Timestamp(1498621254606L));
dates.add(new Timestamp(1498621254607L));
dates.add(new Date(1498621254605L));
dates.add(new Timestamp(1498621254607L));
dates.add(new Timestamp(1498621254609L));
dates.add(new Date(1498621254603L));
dates.add(new Date(1498621254604L));
dates.add(new Date(1498621254605L));
dates.add(new Date(1498621254605L));
dates.add(new Date(1498621254607L));
dates.add(new Timestamp(1498621254607L));
dates.add(new Date(1498621254608L));
dates.add(new Timestamp(1498621254608L));
dates.add(new Date(1498621254611L));
dates.add(new Timestamp(1498621254612L));
dates.add(new Timestamp(1498621254613L));
dates.add(new Date(1498621254607L));
dates.add(new Timestamp(1498621254607L));
dates.add(new Timestamp(1498621254608L));
dates.add(new Timestamp(1498621254609L));
dates.add(new Timestamp(1498621254611L));
dates.add(new Date(1498621254603L));
dates.add(new Date(1498621254606L));

for (int i = 0; i < 200; i++) {
Collections.shuffle(dates);
Collections.sort(dates);
}
}
}

编辑:我已经删除了异常预期,因此您可以看到它在运行时抛出。

关于java.lang.IllegalArgumentException : Comparison method violates its general contract! java.util.Date,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31274578/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com