我有同样的异常,当我在同一个列表/数组中排序时,它发生在 Java8 上运行的对象java.util.Date
。java.sql.Timestamp
(这种混合是由于一些对象是从具有该Timestamp
数据类型的数据库记录中加载的,而另一些对象是手动创建的,并且这些对象中只有一个Date
对象。)
每次对相同的数据集进行排序时,也不会发生异常,而且似乎数组中还必须至少有 32 个这些混合对象才能发生。
如果我使用传统的排序算法,这也不会发生(请参阅 Ortomala Lokni 的答案)。
java.util.Date
如果您仅使用对象或仅使用java.sql.Timestamp
数组中的对象,这也不会发生。
因此,该问题似乎TimSort
与 和 中的 compareTo 方法相java.util.Date
结合java.sql.Timestamp
。
但是,由于它已在 Java 9 中修复,因此研究为什么会发生这种情况并没有让我付出任何代价!
作为一种解决方法,直到 Java9 发布并且我们可以更新我们的系统,我们手动实现了一个Comparator
仅使用getTime()
. 这似乎工作正常。
以下是可用于重现该问题的代码:
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);
}
}
}
编辑:我已经删除了异常期望,所以你可以看到它在运行时抛出。