Comparable和Comparator

一、排序原理简介

1.数组Arrays.sort()排序原理

  通过Java API文档知道,Arrays.sort()调用的是DualPivotQuicksort.sort()方法,如下代码片段所示:

public static void sort(int[] a) {
   
    DualPivotQuicksort.sort(a, 0, a.length - 1, null, 0, 0);
}

  DualPivotQuicksort.sort()排序算法是双枢轴快速排序,时间复杂度为O(n log(n)),具体排序代码参见JDK API文档DualPivotQuicksort类中的sort()方法。Arrays.sort()只能用于基本数据类型:int、short、byte、long、float、double、char的排序。

2.排序方法Arrays.sort(Object[])

  根据元素的自然顺序对指定对象数组按升序进行排序。数组中的所有元素都必须实现 Comparable 接口。此外,数组中的所有元素都必须是可相互比较的(也就是说,对于数组中的任何 e1 和 e2 元素而言,e1.compareTo(e2) 不得抛出 ClassCastException)。该排序算法是一个经过修改的合并排序算法(其中,如果低子列表中的最高元素小于高子列表中的最低元素,则忽略合并)该排序算法的时间复杂度为O(n log(n)),且是稳定的排序算法:不会因调用 sort 方法而对相等的元素进行重新排序, 如果数组包含不可相互比较的 的元素(例如,字符串和整数)抛出ClassCastException,此方法主要用于集合排序Collections.sort(),其调用List接口中的sort()方法进行排序。

3.集合Collections.sort()排序原理

  通过Java API文档知道,Collections.sort()有两个实现方法,如下代码片段所示:

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

  代码中list.sort()方法调用的就是Arrays.sort(Object [])方法,如下代码片段所示:

default void sort(Comparator<? super E> c) {
   
    Object[] a = this.toArray();
    Arrays.sort(a, (Comparator) c);
    ListIterator<E> i = this.listIterator();
    for (Object e : a) {
   
        i.next();
        i.set((E) e);
    }
}

二、Comparable和Comparator接口

1. Comparable接口简介

  Comparable 是内比较器接口,在比较排序时是以自身作为基对象与传入的对象进行大小比较。如果一个类实现了Comparable接口,那么说明该类支持按照指定规则(compareTo方法)进行大小比较:如果A.compareTo(B)返回小于零的数(负数),则说明A小于B;如果A.compareTo(B)返回等于零的数,则说明A与B相等;如果A.compareTo(B)返回大于零的数(正数),则说明A大于B。

2. Comparator接口简介

  Comparator 是外比较器接口。若我们需要对某个对象集合进行排序,而该对象本身不支持排序(即没有实现Comparable接口);那我们可以创建一个该对象的外比较器来进行排序。这个比较器只需要实现Comparator接口,重写Comparator接口的compare()方法(即指定对象的大小比较规则)。然后通过该比较器对类进行排序。int compare(T o1, T o2)和上面的A.compareTo(B)类似,如果int compare(T o1, T o2)返回小于零的数,则说明o1小于o2;如果int compare(T o1, T o2)返回等于零,则说明o1等于o2;如果int compare(T o1, T o2)返回大于零的数,则说明o1大于o2。

3.Comparable和Comparator本质

  Comparable和Comparator接口本身并不具备排序功能,它只是进行了两个对象按照指定规则的大小比较,Collections.sort()和List.sort()均调用了Arrays.sort(Object[])方法对实现了Comparable接口的对象集合进行排序,如果对象实现的比较规则compareTo()不满足要求,或者需要传入自定义的比较规则时,就可以将外比较器Comparator作为参数传入排序方法中,Collections.sort()和List.sort()均支持可选择的外部排序参数。

4.Comparable排序示例

  创建POJO对象Student类:

public class Student implements Comparable<Student>{
   
    private String name;
    private int age;
    private int score;
    public Student() {
   }
    public Student(String name, int age, int score) {
   
        this.name = name;
        this.age = age;
        this.score = score;
    }
    public String getName() {
   
        return name;
    }
    public void setName(String name) {
   
        this.name = name;
    }
    public int getAge() {
   
        return age;
    }
    public void setAge(int age) {
   
        this.age = age
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

抽离的心

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

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

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

打赏作者

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

抵扣说明:

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

余额充值