java裡Comparable和Comparator的相同和不同
阿新 • • 發佈:2021-02-13
一:Comparable
排序介面,相當於實現了該類介面就可賦予類一個排序屬性。
可以看出,該介面的型別為泛型,也就是說T的位置既可以有自定義型別,又可以有原有的型別。
裡面只有一個函式,因此繼承該介面的類都必須重寫這個函式compareTo()
示例:學生類,先根據年齡排序,再根據name排序。
package day_10; public class student implements Comparable<student> { int age; String name; student(int age,String name){ this.age=age; this.name=name; } //compareTo函式重寫 @Override public int compareTo(student s){ int num=this.age-s.age; //這是降序,升序的話就改成s.age-this.age return num==0?this.name.compareTo(s.name):num; } @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; student student = (student) o; if (age != student.age) return false; return name != null ? name.equals(student.name) : student.name == null; } @Override public int hashCode() { int result = age; result = 31 * result + (name != null ? name.hashCode() : 0); return result; } @Override public String toString(){ return "student{age="+age+",name='"+name+"'};"; } }
二:Comparator
比較器介面,相當於實現了該介面之後就能實現一個比較器。比較器是實實在在存在的,可以類似於引數一樣進行傳遞。
package day_10; //必須導包 import java.util.Comparator; //下面就是一個自定義的排序類 public class comparator implements Comparator<student> { @Override public int compare(student s1, student s2){ int num=s1.age-s2.age; return num==0?s1.name.compareTo(s2.name):num; } } //在主類中呼叫 TreeSet<student> treeSet = new TreeSet<student>(new comparator());//匿名物件 或 comparator c1=new comparator(); TreeSet<student> treeSet = new TreeSet<student>(c1);
寫成匿名類的形式:
TreeSet<student> treeSet = new TreeSet<student>(new Comparator<student>() { @Override public int compare(student s1, student s2) { int num = s1.age - s2.age; return num == 0 ? s1.name.compareTo(s2.name) : num; } });
這個一看就能發現這個可以省去好多重複操作,比如有多個類排序操作一樣,就沒必要在每個類中都實現一次Comparable介面,只需要寫一個比較器,然後像傳引數一樣傳遞其即可。
例二:
ArrayList<student>arrayList=new ArrayList<student>();
arrayList.add(stu1);
Collections.sort(arrayList,c1);
三:優劣相比
一些場景下二者可以混合使用。並且二者都是介面。
用Comparable簡單, 只要實現Comparable介面的物件直接就成為一個可以比較的物件,但是使用Comparable的話還得破開類的程式碼,這就違反了開閉原則。
用Comparator的好處是不需要修改原始碼, 而是另外實現一個比較器, 當某個自定義的物件需要作比較的時候,把比較器和物件一起傳遞過去就可以比大小了, 並且在Comparator裡面使用者可以自己實現複雜的可以通用的邏輯(因為這個接口裡有很多函式功能),使其可以匹配一些比較簡單的物件,那樣就可以節省很多重複勞動了。