可能是最簡單最通透的Comparable和Comparator介面返回值理解

2023-06-09 12:00:58

先說 Comparator 介面,這個理解了,下一個就理解了

一、Comparator 的用法(暫不考慮0,因為0不處理)

返回-1,1交換不交換位置,如果撇開比較器的兩個引數和jdk預設順序來說,存粹是錯誤的

介面如下:原文連結

public interface Comparator<T> {

    int compare(T o1, T o2);
}

現提出如下標準:

  • 標準1:jdk 預設要升序排列,即程式排序規則是 asc ,升序排列
  • 標準2:Comparator 介面第一個引數 o1 是第二個引數 o2 後面的物件

基於這 2 個標準,假設:

  • 1 = true
  • -1 = false

重點來了,有以下兩種情況和處理方式:

  • 情況1:後面的比前面大,即 o1 > o2 ,是 標準1中的 升序 嗎?是,返回 true,不交換前後位置。
  • 情況2:後面的比前面小,即 o1 < o2 ,是 標準1中的 升序 嗎?不是,返回 false, 交換前後位置。

問:為什麼第二種降序要交換前後位置?
答:因為 標準1 ,預設要對陣列進行升序排列,如果發現降序的序列,自然要交換位置

擴散問題1:如果我想按降序排列呢?
答:那你就在升序時候返回 false,降序時候返回 true 就行

擴散問題2:如果我不比較,直接返回1或者-1呢?
答:因為標準1,返回1(true)代表都是升序,自然不必交換,返回-1(false)代表都不是升序,都要交換,即陣列反轉

總結:

想要升序排列,如果比較器2個引數是升序排列,就返回true,否則返回false即可
想要降序排列,如果比較器2個引數是降序排列,就返回true,否則返回false即可

附測試程式碼:

public class ComparatorDemo {

    private final int local;

    public ComparatorDemo(int local) {
        this.local = local;
    }

    @Override
    public String toString() {
        return "" + local;
    }

    public static void main(String[] args) {
        List<ComparatorDemo> asc = new ArrayList<>();

        asc.add(new ComparatorDemo(13));
        asc.add(new ComparatorDemo(3));
        asc.add(new ComparatorDemo(15));
        asc.add(new ComparatorDemo(18));

        // 我想升序排列
        asc.sort((second,first) -> {
            if(second.local > first.local){
                return 1; //是升序,返回true
            }else if(second.local < first.local){
                return -1; //是降序,返回false
            }else {
                return 0;
            }
        });

        System.out.print("升序陣列:");
        System.out.println(asc);

        List<ComparatorDemo> desc = new ArrayList<>();

        desc.add(new ComparatorDemo(13));
        desc.add(new ComparatorDemo(3));
        desc.add(new ComparatorDemo(15));
        desc.add(new ComparatorDemo(18));

        // 我想降序排列
        desc.sort((o1,o2) -> {
            if(o1.local > o2.local){
                return -1; //不是降序,返回false
            }else if(o1.local < o2.local){
                return 1; //是降序,返回true
            }else {
                return 0;
            }
        });

        System.out.print("降序陣列:");
        System.out.println(desc);
    }

}

二、Comparable 的用法(暫不考慮0,因為0不處理)

規則和 Comparator 一樣,只需把當前 Comparable 範例當成Comparator#compare(T o1, T o2)第一個引數即可

測試程式碼:

public class ComparableImpl implements Comparable<ComparableImpl> {

    private final Integer local;

    public ComparableImpl(Integer num) {
        this.local = num;
    }

    @Override
    public String toString() {
        return "" + local;
    }

    @Override
    public int compareTo(ComparableImpl before) {
        if (local > before.local) {
            return 1; //是升序
        } else if (local < before.local) {
            return -1; //是降序
        }
        return 0;
    }

    public static void main(String[] args) {
        ComparableImpl[] ables = new ComparableImpl[]{
                new ComparableImpl(1),
                new ComparableImpl(13),
                new ComparableImpl(25),
                new ComparableImpl(4),
        };

        Arrays.sort(ables);

        System.out.println(Arrays.toString(ables));
    }

}