1. 程式人生 > 實用技巧 >踩坑日記之List.sort()排序丟擲異常Comparison method violates its general contract!

踩坑日記之List.sort()排序丟擲異常Comparison method violates its general contract!

場景 -> 從SVN上獲取所有專案的tag記錄然後按更新時間排序:

1 List<SVNDirEntry> list = new  ArrayList<SVNDirEntry>(entries);
2 List<SVNDirEntry> list2 = list.stream().sorted(Comparator.comparing(SVNDirEntry::getDate).reversed()).limit(15).collect(Collectors.toList());
3 list.sort((a1, a2) -> (int)(a1.getDate().getTime() - a2.getDate().getTime()));

意思是a1物件的更新時間大於a2的更新時間時不交換o1,o2的順序,否則交換順序,然後丟擲異常:

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

查閱資料後知道了JDK7之後更換了新的排序演算法TimSort(此處使用JDK8),沒有對兩值相等時的判定,直接當作1處理,因此報該異常。

解決方案:重寫排序規則,加上兩值相等的方案

1 private static class SVNTimeComparator implements Comparator<SVNDirEntry> {
2 3 public int compare(SVNDirEntry b1, SVNDirEntry b2) { 4 5 return b1.getDate().compareTo(b2.getDate()); 6 } 7 }

原list排序改為:SVNTimeComparator comparator = new SVNTimeComparator(); list.sort(comparator);