源码分析 Java 比较器的排序规则

话不多说,直接看代码,从 Collections 的 sort 方法开始。

Collections 类带有比较器的 sort 方法会进入到 List 接口的一个默认方法:

Collections.sort(dogs, new DogAgeComparator());
default void sort(Comparator<? super E> c) {
    Object[] a = this.toArray();
    Arrays.sort(a, (Comparator) c);
    ...
}

再进入到 Arrays 类的 sort 方法:

public static <T> void sort(T[] a, Comparator<? super T> c) {
    if (c == null) {
        sort(a);
    } else {
        if (LegacyMergeSort.userRequested)
            legacyMergeSort(a, c);
        else
            TimSort.sort(a, 0, a.length, c, null, 0, 0);
    }
}

如果有自定义的外部排序(Comparator),就会进入第 4 行的 else 语句块中,其中的 LegacyMergeSort 排序已经被废弃(如果你指定使用该方法也可以),现在用的是 TimSort 的排序方法,相比起旧版本直接使用 归并排序 算法,新版本在此基础上还引入了 “二分插入排序” 的优化。

接下来,因为我们讨论的主题是 Comparator 和 Comparable 中方法的返回值对排序结果的影响,新版本虽然优化了排序性能,但原本的思想不会有改变,所以我们采用旧版本排序代码的分析。

LegacyMergeSort 的 mergeSort 算法中的实现了外部比较器 Comparator的代码:
图片
或者实现了 Comparable 接口的实现:
图片
最为关键的部分,第 4 行使用到的 compare 方法中的 dest[j-1]dest[j]调用结果 > 0 的条件下,会进行 swap,交换他们的位置。
图片
看上面的图片代码, o1 代表的是暂时排在前面的元素,o2 代表排在后面的元素。

只要记住,return 值 > 0 的时候会交换 o1 和 o2 的位置,以此来实现你想要的排序规则。

最后,给两个具体的实现代码(重点看注释部分!):
在这里插入图片描述
在这里插入图片描述

如果本篇文章有帮助到你的话,可以点个赞呀。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值