Comparable和Comparator都是用於比較數據的大小的,實現Comparable接口須要重寫compareTo方法,實現Comparator接口須要重寫compare方法,這兩個方法的返回值都是int,用int類型的值來肯定比較結果,在Collections工具類中有一個排序方法sort,此方法能夠之傳一個集合,另外一個重載版本是傳入集合和比較器,前者默認使用的就是Comparable中的compareTo方法,後者使用的即是咱們傳入的比較器Comparator,java的不少類已經實現了Comparable接口,好比說String,Integer等類,而咱們其實也是基於這些實現了Comparator或者Comparab接口的原生類來比較咱們本身的類,好比說自定義一個類User,屬性有name和age,倆個user之間的比較無非就是比較name和age的大小。java
Comparable接口中只有一個方法:ide
public int compareTo(T o);
調用此方法的對象,也就是this和o進行比較,若返回值大於0則this大於o,返回值等於0則是this等於o,返回值小於0則是this<o,而這個Comparable是直接在咱們的自定義類User上實現,由於this是須要一個明確的比較對象的,也就是通常狀況下咱們會在定義User類的時候有排序的需求,就要實現此接口。工具
import java.util.ArrayList; import java.util.Collections; import java.util.List; public class UserComparable implements Comparable<UserComparable> { private String name; private int age; public UserComparable(String name, int age) { this.name = name; this.age = age; } @Override public String toString() { return "UserComparable{" + "name='" + name + '\'' + ", age=" + age + '}'; } @Override public int compareTo(UserComparable o) { if (this.name.compareTo(o.name)==0){ if (this.age == o.age){ return 0; }else if (this.age >o.age){ return 1; }else { return -1; } }else if (this.name.compareTo(o.name)>0){ return 1; }else { return -1; } } public static void main(String[] args) { List<UserComparable> list = new ArrayList<UserComparable>(); list.add(new UserComparable("gol",21)); list.add(new UserComparable("gol",19)); list.add(new UserComparable("xiao",21)); list.add(new UserComparable("long",21)); System.out.println("排序前:"+list); //排序規則:先按name排序,若name相等則再比較age Collections.sort(list); System.out.println("排序後:"+list); } }
輸出結果爲:this
排序前:[UserComparable{name='gol', age=21}, UserComparable{name='gol', age=19}, UserComparable{name='xiao', age=21}, UserComparable{name='long', age=21}]
排序後:[UserComparable{name='gol', age=19}, UserComparable{name='gol', age=21}, UserComparable{name='long', age=21}, UserComparable{name='xiao', age=21}]spa
Comparator接口中方法不少,可是咱們只須要實現一個,也是最重要的一個compare,也許有的人會好奇爲何接口中的方法能夠不用實現,由於這是JDK8之後的新特性,在接口中用default修飾的方法能夠有方法體,在實現接口的時候能夠不用重寫,能夠類比抽象類。設計
int compare(T o1, T o2);
compare比較的o1和o2,返回值大於0則o1大於o2,依次類推,對於compare;來講this是誰不重要,所比較的兩個對象都已經傳入到方法中,全部Comparator就是有個外部比較器,在咱們設計User初時,並不須要它有比較功能,在後期擴展業務是,Comparator的存在可使咱們在不修改源代碼的狀況下來完成需求,只須要新定義一個比較器來實現Comparator,重寫compare方法並將User對象傳進去。code
import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.List; public class User { private String name; private int age; public User(String name, int age) { this.name = name; this.age = age; } @Override public String toString() { return "User{" + "name='" + name + '\'' + ", age=" + age + '}'; } public static void main(String[] args) { List<User> list = new ArrayList<User>(); list.add(new User("gol", 21)); list.add(new User("gol", 19)); list.add(new User("xiao", 21)); list.add(new User("long", 21)); System.out.println("排序前:" + list); //排序規則:先按name排序,若name相等則再比較age //建立比較器對象 Comparator comparator = new UserComparator(); Collections.sort(list,comparator); System.out.println("排序後:" + list); } static class UserComparator implements Comparator<User> { @Override public int compare(User o1, User o2) { if (o1.name.compareTo(o2.name) == 0) { if (o1.age == o2.age) { return 0; } else if (o1.age > o2.age) { return 1; } else { return -1; } } else if (o1.name.compareTo(o2.name) > 0) { return 1; } else { return -1; } } } }
輸出結果爲: 對象
排序前:[User{name='gol', age=21}, User{name='gol', age=19}, User{name='xiao', age=21}, User{name='long', age=21}]
排序後:[User{name='gol', age=19}, User{name='gol', age=21}, User{name='long', age=21}, User{name='xiao', age=21}]blog
java中大部分咱們經常使用的數據類型的類都實現了Comparable接口,而僅僅只有一個抽象類RuleBasedCollator實現了Comparator接口 ,仍是咱們不經常使用的類,這並非要用Comparab而不要使用Comparator,在設計初時有需求就選擇Comparable,若後期須要擴展或增長排序需求是,再增長一個比較器Comparator,畢竟能寫Collections.sort(arg1),沒人樂意寫Collections.sort(arg1,arg2)。排序