为何Collections.sort()会报IllegalArgumentException异常


案发现场


在Java开发中,我们对集合List进行排序,常会使用Collections.sort()方法进行排序,或者对于数组,使用Arrays.sort()方法进行排序。其实两者的sort()方法都是同一个,如下jdk源码:


Collections#sort

public static <T> void sort(List<T> list, Comparator<? super T> c) {
   
    list.sort(c);
}

ArrayList#sort

@SuppressWarnings("unchecked")
public void sort(Comparator<? super E> c) {
   
    final int expectedModCount = modCount;
    // 这里,其实是调用了Arrays的sort方法
    Arrays.sort((E[]) elementData, 0, size, c);
    if (modCount != expectedModCount) {
   
        throw new ConcurrentModificationException();
    }
    modCount++;
}

即最终都是调用了Arrays.sort()方法。
平时日常开发使用这个排序方法都没有问题的,但最近我开发的一个Android应用线上报了一个异常,异常栈是有Colletions.sort()引起的,异常栈信息如下:
Exception in thread "main" java.lang.IllegalArgumentException: Comparison method violates its general contract!
	at java.util.TimSort.mergeHi(TimSort.java:899)
	at java.util.TimSort.mergeAt(TimSort.java:516)
	at java.util.TimSort.mergeForceCollapse(TimSort.java:457)
	at java.util.TimSort.sort(TimSort.java:254)
	at java.util.Arrays.sort(Arrays.java:1438)
	at java.util.Arrays$ArrayList.sort(Arrays.java:3895)
	at java.util.Collections.sort(Collections.java:175)

我的代码调用大概长这样:
List<FilerPackage> allPack = //省略数据赋值操作
Collections.sort(allPack, (f1, f2) -> f1.getSort() - f2.getSort());

就是这样的调动方式,平时好好的,突然某一天线上就报异常了,然后更尴尬的是,我想用线上真实数据去复现这个异常,竟然也很难复现出来,无奈,最终只能去看JDK源码,探究其真面目了。


异常分析


Collections.sort()方法注释有这么一段说明:

   / * (省略其他内容)     
     *  @throws ClassCastException if the list contains elements that are not
     *         <i>mutually comparable</i> using the specified comparator.
     * 	@throws UnsupportedOperationException if the specified list's
     *         list-iterator does not support the {
   @code set} operation.
     *	@throws IllegalArgumentException (optional) if the comparator is
     *         found to
  • 11
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Yeqiu1024

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值