Collection和Collections之間的使用與區別(順帶講解Comparable與Comparator區別)

前言 Collection與Collections的區別一句話歸納就是後者是S曲線.....哎哎哎別打....別打...別打臉QnQjavascript

咳咳...嚴肅點,在以前的文章中已經講過Collection了,它是單列集合類的根接口,用於存儲一系列符合某種規則的元素,它主要的子接口分別是List和Set。java

Collections則是集合工具類,用來對集合進行操做。能夠理解爲服務Collection集合的工具類,主要提供一系列靜態方法實現對各類集合的搜索、排序、線程安全等操做數組

@[toc]安全

1.1 Collections經常使用功能

java.utils.Collections是集合工具類,用來對集合進行操做。部分方法以下:數據結構

  • public static <T> boolean addAll(Collection<T> c, T... elements):往集合中添加一些元素。
  • public static void shuffle(List<?> list) 打亂順序:打亂集合順序。
  • public static <T> void sort(List<T> list):將集合中元素按照默認規則排序。
  • public static <T> void sort(List<T> list,Comparator<? super T> ):將集合中元素按照指定規則排序。

使用代碼以下:ide

public class CollectionsDemo {
    public static void main(String[] args) {
        ArrayList<Integer> list = new ArrayList<Integer>();
        //原來添加寫法
        //list.add(233);
        //list.add(555);
        //list.add(666);
        //list.add(7777);
        
        //採用工具類 完成 往集合中添加元素 
        Collections.addAll(list, 1, 4, 32);
        System.out.println(list);
        //排序方法 
        Collections.sort(list);
        System.out.println(list);
    }
}
結果:
[ 1, 4, 32]
[1, 2, 3,4]
複製代碼

代碼測試以後 ,發現咱們的集合按照順序進行了排列,但是這樣的順序是採用默認的順序,若是想要指定順序那該怎麼辦呢?工具

咱們發現還有這個方法沒有講public static <T> void sort(List<T> list,Comparator<? super T> ):將集合中元素按照指定規則排序。接下來說解一下指定規則的排列。測試

1.2 Comparator比較器的使用

研究這個方法前仍是先研究這個public static <T> void sort(List<T> list)方法先。this

public static <T> void sort(List<T> list):將集合中元素按照默認規則排序。spa

使用這個方法存儲字符串類型代碼以下【注意這裏是字符串類型】:

public class CollectionsDemo {
    public static void main(String[] args) {
        ArrayList<String>  list = new ArrayList<String>();
        list.add("小滷蛋");
        list.add("小短腿");
        list.add("小魯班");
        list.add("小憨包");
        //排序方法
        Collections.sort(list);
        System.out.println(list);
    }
}
運行結果:[小滷蛋, 小憨包, 小短腿, 小魯班]
複製代碼

咱們使用的是默認的規則完成字符串的排序,那麼默認規則是怎麼定義出來的呢?

說到排序了,簡單的說就是兩個對象之間比較大小,那麼在JAVA中提供了兩種比較實現的方式, 一種是比較死板的採用java.lang.Comparable接口去實現, 一種是比較靈活的當我須要作排序的時候在去選擇的java.util.Comparator接口完成。

1.3 分析String源碼

那麼咱們採用的public static <T> void sort(List<T> list)這個方法完成的排序,實際上要求了被排序的類型須要實現Comparable接口完成比較的功能,在String類型上以下:

public final class String implements java.io.Serializable, Comparable<String>, CharSequence {
       ....
}
複製代碼

String類實現了這個Comparable接口(Integer也實現這接口),並完成了比較規則的定義,可是這樣就把這種規則寫死了,那好比我想要字符串按照第一個字符降序排列,那麼這樣就要修改String的源代碼,修改源碼這件事這是不可能的了!除非大家慫恿博主跑去sun公司修改源碼,接着我就刪庫跑路,最後絕壁是挨最毒的打....

那麼這個時候咱們可使用public static <T> void sort(List<T> list,Comparator<? super T> )方法靈活的完成,這個裏面就涉及到了Comparator這個接口,位於位於java.util包下,排序是comparator能實現的功能之一,該接口表明一個比較器,比較器具備可比性!顧名思義就是作排序的,通俗地講須要比較兩個對象誰排在前誰排在後,那麼比較的方法就是compare,以下:

public int compare(String o1, String o2):比較其兩個參數的順序。

兩個對象比較的結果有三種:大於,等於,小於。

若是要按照升序排序, 則o1 小於o2,返回(負數),相等返回0,01大於02返回(正數) 若是要按照降序排序 則o1 小於o2,返回(正數),相等返回0,01大於02返回(負數)

操做以下:

public class CollectionsDemo {
    public static void main(String[] args) {
        ArrayList<String> list = new ArrayList<String>();
        list.add("cba");
        list.add("aba");
        list.add("sba");
        list.add("nba");
        //排序方法 按照第一個單詞的降序
        Collections.sort(list, new Comparator<String>() {
            @Override
            public int compare(String o1, String o2) {
                return o2.charAt(0) - o1.charAt(0);
            }
        });
        System.out.println(list);
    }
}
結果:[sba, nba, cba, aba]

複製代碼

1.4Comparable接口和Comparator接口區別

Comparable:強行對實現它的每一個類的對象進行總體排序。這種排序被稱爲類的天然排序,類的compareTo方法被稱爲它的天然比較方法。只能在類中實現compareTo()一次,不能常常修改類的代碼實現本身想要的排序。實現此接口的對象列表(和數組)能夠經過Collections.sort(和Arrays.sort)進行自動排序,對象能夠用做有序映射中的鍵或有序集合中的元素,無需指定比較器。

Comparator強行對某個對象進行總體排序。能夠將Comparator 傳遞給sort方法(如Collections.sortArrays.sort),從而容許在排序順序上實現精確控制。還可使用Comparator來控制某些數據結構(若有序set或有序映射)的順序,或者爲那些沒有天然順序的對象collection提供排序。

總而言之,言而總之 comparable是須要比較的對象來實現接口。這樣對象調用實現的方法來比較。對對象的耦合度高(須要改變對象的內部結構,破壞性大)。comparator至關於一通用的比較工具類接口。須要定製一個比較類去實現它,重寫裏面的compare方法,方法的參數便是須要比較的對象。對象不用作任何改變。解耦。

1.5 歡迎來到王者龍耀排序戰場

建立一個學生類,存儲到ArrayList集合中完成指定排序操做。

Student 初始類

public class Student{
    private String name;
    private int age;

    public Student() {
    }

    public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }

    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;
    }

    @Override
    public String toString() {
        return "Student{" +
               "name='" + name + '\'' +
               ", age=" + age +
               '}';
    }
}
複製代碼

測試類:

public class Demo {

    public static void main(String[] args) {
        // 建立四學生刺客對象 存儲到集合中
        ArrayList<Student> list = new ArrayList<Student>();

        list.add(new Student("r滷蛋七號",18));
        list.add(new Student("j安琪拉屎",16));
        list.add(new Student("a劉備胎",16));
        list.add(new Student("a東皇太二",17));
        list.add(new Student("m夏侯惇坑",16));


        /* 讓學生 按照年齡排序 升序 */
// Collections.sort(list);//要求 該list中元素類型 必須實現比較器Comparable接口


        for (Student student : list) {
            System.out.println(student);
        }


    }
}
複製代碼

發現,當咱們調用Collections.sort()方法的時候 程序報錯了。

緣由:若是想要集合中的元素完成排序,那麼必需要實現比較器Comparable接口。

因而咱們就完成了Student類的一個實現,以下:

public class Student implements Comparable<Student>{
    ....
    @Override
    public int compareTo(Student o) {
        return this.age-o.age;//升序
    }
}
複製代碼

再次測試,代碼就OK 了效果以下:

Student{name='j安琪拉屎', age=16}
Student{name='a劉備胎', age=16}
Student{name='m夏侯惇坑', age=16}
Student{name='a東皇太二', age=17}
Student{name='r滷蛋七號', age=18}
複製代碼

1.6 排序加餐不加價

若是在使用的時候,想要獨立的定義規則去使用 能夠採用Collections.sort(List list,Comparetor<T> c)方式,本身定義規則:

Collections.sort(list, new Comparator<Student>() {
    @Override
    public int compare(Student o1, Student o2) {
        return o2.getAge()-o1.getAge();//以學生的年齡降序
    }
});
複製代碼

效果:

Student{name='r滷蛋七號', age=18}
Student{name='a東皇太二', age=17}
Student{name='j安琪拉屎', age=16}
Student{name='a劉備胎', age=16}
Student{name='m夏侯惇坑', age=16}
複製代碼

若是想要規則更多一些,能夠參考下面代碼:

Collections.sort(list, new Comparator<Student>() {
            @Override
            public int compare(Student o1, Student o2) {
                // 年齡降序
                int result = o2.getAge()-o1.getAge();//年齡降序

                if(result==0){//第一個規則判斷完了 下一個規則 姓名的首字母 升序
                    result = o1.getName().charAt(0)-o2.getName().charAt(0);
                }

                return result;
            }
        });
複製代碼

效果以下:

Student{name='r滷蛋七號', age=18}
Student{name='a東皇太二', age=17}
Student{name='a劉備胎', age=16}
Student{name='j安琪拉屎', age=16}
Student{name='m夏侯惇坑', age=16}
複製代碼

水晶你就是個混子,說好不帶掉血的呢?哦豁完了...

最後歡迎各位關注個人公衆號,一塊兒探討技術,嚮往技術,追求技術,來了就是盆友喔...

在這裏插入圖片描述
相關文章
相關標籤/搜索