我有同样的异常,当我在Java8上运行排序时,我在同一个列表/数组中有java.util.Date和java.sql.Timestamp对象时发生了这种情况. (这种混合是由于某些对象是从具有Timestamp数据类型的数据库记录加载的,而其他对象是手动创建的,而对象中只有Date对象.)
每次对同一数据集进行排序时也不会发生异常,并且似乎阵列中至少还有32个这样的混合对象才会发生.
如果我使用传统的排序算法,这也不会发生(请参阅Ortomala Lokni的回答).
如果仅使用java.util.Date对象或仅使用数组中的java.sql.Timestamp对象,也不会发生这种情况.
因此,问题似乎是TimSort与java.util.Date和java.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 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);
}
}
}
编辑:我已经删除了异常期望,因此你可以在运行时看到它抛出.