Comparator和Comparable

Comparable

  • 实现了 Comparable 接口,重写 compareTo() 方法,就可以按照自己制定的规则将由它创建的对象进行比较
public interface Comparable<T> {
    // 返回值可能为负数,零或者正数,代表的意思是该对象按照排序的规则小于、等于或者大于要比较的对象
    int compareTo(T t);
}
class CSer implements Comparable<CSer> {
    private int mvp;

    public CSer(int mvp) {
        this.mvp = mvp;
    }

    @Override
    public int compareTo(CSer o) {
        return this.mvp - o.mvp;
    }
}

Comparator

public interface Comparator<T> {
    int compare(T o1, T o2);
    // 判断该 Object 是否和 Comparator 保持一致
    boolean equals(Object obj);
    ...
}
class CSer {
    private int mvp;

    public CSer(int mvp) {
        this.mvp = mvp;
    }

    public int getMvp() {
        return mvp;
    }
}

class CSerComparator implements Comparator<CSer> {

    @Override
    public int compare(CSer o1, CSer o2) {
        return o1.getMvp() - o2.getMvp();
    }
}

public class Test {
    public static void main(String[] args) {
        CSer niko = new CSer(3);
        CSer s1mple = new CSer(5);
        CSer dev1ce = new CSer(4);

        List<CSer> list = new ArrayList<>();
        list.add(niko);
        list.add(s1mple);
        list.add(dev1ce);

        list.sort(new CSerComparator());
        for (CSer cSer : list) {
            System.out.println(cSer.getMvp());
        }
    }
}
  • ArrayList的sort源码
public void sort(Comparator<? super E> c) {
    // 保存当前队列的 modCount 值,用于检测 sort 操作是否非法
    final int expectedModCount = modCount;
    // 调用 Arrays.sort 对 elementData 数组进行排序,使用传入的比较器 c
    Arrays.sort((E[]) elementData, 0, size, c);
    // 检查操作期间 modCount 是否被修改,如果被修改则抛出并发修改异常
    if (modCount != expectedModCount) {
        throw new ConcurrentModificationException();
    }
    // 增加 modCount 值,表示队列已经被修改过
    modCount++;
}

使用选择

  • 一个类实现了 Comparable 接口,意味着该类的对象可以直接进行比较(排序),但比较(排序)的方式只有一种,很单一。

  • 一个类如果想要保持原样,又需要进行不同方式的比较(排序),就可以定制比较器(实现 Comparator 接口)。

  • 如果对象的排序需要基于自然顺序,选择 Comparable,如果需要按照对象的不同属性进行排序,选择 Comparator

posted @ 2024-07-13 23:16  n1ce2cv  阅读(7)  评论(0编辑  收藏  举报