Java中的Collections工具類及Comparator和Comparable的區(qū)別

Collections類的常見方法

為了處理Collection類的實例對象,java提供了Collections工具類來進(jìn)行操作。該類為工具類,內(nèi)部都為static方法。來看常見的幾種使用:

Collections.sort()

對一個有序的List做排序??梢宰远x排序規(guī)則。
來看最基本的一個使用:

import java.util.ArrayList;
import java.util.Collections;

public class Main {
    public static void main(String[] args) {
        ArrayList<Integer> arr = new ArrayList<>();
        arr.add(3);
        arr.add(1);
        arr.add(4);
        arr.add(2);

        System.out.println(arr); // [3, 1, 4, 2]
        Collections.sort(arr);
        System.out.println(arr); // [1, 2, 3, 4]
    }
}

如果不指定排序規(guī)則會按照默認(rèn)排序進(jìn)行排列。再來看自定義規(guī)則的一個例子:

public class Main {
    public static void main(String[] args) {
        ArrayList<Integer> arr = new ArrayList<>();
        arr.add(3);
        arr.add(1);
        arr.add(4);
        arr.add(2);

        System.out.println(arr); // [3, 1, 4, 2]
        Collections.sort(arr, new Comparator<Integer>() {
            @Override
            public int compare(Integer o1, Integer o2) {
                return o2 - o1;
            }
        });
        System.out.println(arr); // [4, 3, 2, 1]
    }
}

Comparator是一個接口,實現(xiàn)其內(nèi)部的compare方法即可按照給定規(guī)則排序。

上述排序例子中new Comparator<Integer>() {}是Java的內(nèi)部匿名類,本身接口是不能直接new的,這個就表示實際上現(xiàn)在new的是這個接口的實現(xiàn)類。

Comparator和Comparable的區(qū)別

上述例子中使用了Comparator,和前者一樣,Comparable也是一個接口,二者表示的不同的地方在于:

  • Comparable是排序接口。若一個類實現(xiàn)了Comparable接口,就意味著該類支持排序
  • Comparator是比較接口,我們?nèi)绻枰刂颇硞€類的次序,而該類本身不支持排序(即沒有實現(xiàn)Comparable接口),那么我們就可以建立一個“該類的比較器”來進(jìn)行排序,這個“比較器”只需要實現(xiàn)Comparator接口即可。

舉個例子來說,我們這次創(chuàng)建一個自定義的可以排序的類。

package com.DeeJay;

import java.util.ArrayList;
import java.util.Collections;

public class Main {
    public static void main(String[] args) {
        ArrayList<SortDemo> arr = new ArrayList<>();
        arr.add(new SortDemo(3));
        arr.add(new SortDemo(1));
        arr.add(new SortDemo(2));
        arr.add(new SortDemo(4));

        System.out.println(arr); // [sortDemo_3, sortDemo_1, sortDemo_2, sortDemo_4]

        Collections.sort(arr);

        System.out.println(arr); // [sortDemo_1, sortDemo_2, sortDemo_3, sortDemo_4]
    }
}
class SortDemo implements Comparable {
    int num;

    public SortDemo(int num) {
        this.num = num;
    }

    @Override
    public int compareTo(Object o) {
        SortDemo s = (SortDemo) o;
        if(this.num < s.num) {
            return -1;
        }else if(this.num > s.num) {
            return 1;
        }
        return 0;
          // 這塊不能直接寫 return this.num - s.num; 因為會存在溢出的情況
        // return this.num - s.num;
    }

    @Override
    public String toString() {
        return "sortDemo_" + this.num;
    }
}

上述例子中,SortDemo類實現(xiàn)了Comparable接口1,重寫了compareTo方法,從而使得SortDemo類的實例對象可以相互比較排序,直接調(diào)用Collections.sort()即可按照實現(xiàn)的compareTo方法進(jìn)行排序,不需要傳入額外的比較邏輯。

對于上述情況,不能直接寫 return this.num - s.num;,舉個例子來講:byte a = -128; byte b = 1; System.out.println((byte) a - b); // 127 發(fā)生了溢出

再來看使用Comparator的例子,這次我們的SortDemo類并不支持排序,調(diào)用Collections.sort()傳入一個實現(xiàn)Comparator的內(nèi)部匿名類來指定排序規(guī)則。

package com.DeeJay;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;

public class Main {
    public static void main(String[] args) {
        ArrayList<SortDemo> arr = new ArrayList<>();
        arr.add(new SortDemo(3));
        arr.add(new SortDemo(1));
        arr.add(new SortDemo(2));
        arr.add(new SortDemo(4));

        System.out.println(arr); // [sortDemo_3, sortDemo_1, sortDemo_2, sortDemo_4]

        Collections.sort(arr, new Comparator<SortDemo>() {  // 此處為內(nèi)部匿名類
            @Override
            public int compare(SortDemo o1, SortDemo o2) {
                return o1.num - o2.num;
            }
        });

        System.out.println(arr); // [sortDemo_1, sortDemo_2, sortDemo_3, sortDemo_4]
    }
}
class SortDemo{
    int num;

    public SortDemo(int num) {
        this.num = num;
    }

    @Override
    public String toString() {
        return "sortDemo_" + this.num;
    }
}

Collections.binarySearch

返回指定List和key的index。關(guān)于這個方法有地方需要注意:

要進(jìn)行查找,要先調(diào)用Collections.sort()進(jìn)行自然順序排序,不然返回的結(jié)果會有問題
要調(diào)用Collections.sort(),那要保證List內(nèi)部的類型是實現(xiàn)了Comparable接口的

對于Integer這種Java已經(jīng)實現(xiàn)了Comparable的類是可以不做處理的,但是我們自定義的類要進(jìn)行實現(xiàn)Comparable。

package com.DeeJay;

import java.util.ArrayList;
import java.util.Collections;

public class Main {
    public static void main(String[] args) {
        ArrayList<Integer> arr = new ArrayList<>();
        arr.add(3);
        arr.add(1);
        arr.add(2);
        arr.add(4);

        Collections.sort(arr); // 調(diào)用binarySearch之前要先進(jìn)行sort
        System.out.println(Collections.binarySearch(arr, 3));
    }
}

Collections.copy(destList, targetList)

這個方法需要注意的地方是,目的List的長度要保證不短于要被克隆的targetList

package com.DeeJay;

import java.util.ArrayList;
import java.util.Collections;

public class Main {
    public static void main(String[] args) {
        ArrayList<Integer> arr = new ArrayList<>();
        arr.add(3);
        arr.add(1);
        arr.add(2);
        arr.add(4);
        ArrayList<Integer> arr2 = new ArrayList<>();
        arr2.add(null);
        arr2.add(null);
        arr2.add(null);
        arr2.add(null);
        Collections.copy(arr2, arr);
        System.out.println(arr2); // [3, 1, 2, 4]
    }
}

Collections.fill() Collections.reverse() Collections.shuffle()

package com.DeeJay;

import java.util.ArrayList;
import java.util.Collections;

public class Main {
    public static void main(String[] args) {
        ArrayList<Integer> arr = new ArrayList<>();
        arr.add(3);
        arr.add(1);
        arr.add(2);
        arr.add(4);
        Collections.sort(arr);
        System.out.println(arr);// [1, 2, 3, 4]
        Collections.reverse(arr);
        System.out.println(arr); // [4, 3, 2, 1]
        Collections.shuffle(arr);
        System.out.println(arr); // [1, 3, 2, 4] 隨機打亂次序
        Collections.fill(arr, null);
        System.out.println(arr); // [null, null, null, null]
    }
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容