在實際應用中,我們往往有需要比較兩個自定義對象大小的地方。而這些自定義對象的比較,就不像簡單的整型數據那么簡單,它們往往包含有許多的屬性,我們一般都是根據這些屬性對自定義對象進行比較的。所以JAVA中要比較對象的大小或者要對對象的集合進行排序,需要通過比較這些對象的某些屬性的大小來確定它們之間的大小關系。
一般,Java中通過接口實現兩個對象的比較,比較常用就是Comparable接口和Comparator接口。首先類要實現接口,并且使用泛型規定要進行比較的對象所屬的類,然后類實現了接口后,還需要實現接口定義的比較方法(compareTo方法或者compare方法),在這些方法中傳入需要比較大小的另一個對象,通過選定的成員變量與之比較,如果大于則返回1,小于返回-1,相等返回0。
一:Comparable接口
1、什么是Comparable接口
此接口強行對實現它的每個類的對象進行整體排序。此排序被稱為該類的自然排序 ,類的 compareTo方法被稱為它的自然比較方法 。實現此接口的對象列表(和數組)可以通過 Collections.sort(和 Arrays.sort )進行自動排序。實現此接口的對象可以用作有序映射表中的鍵或有序集合中的元素,無需指定比較器。
2、實現什么方法
int compareTo(T o)
比較此對象與指定對象的順序。如果該對象小于、等于或大于指定對象,則分別返回負整數、零或正整數。
參數: o - 要比較的對象。
返回:負整數、零或正整數,根據此對象是小于、等于還是大于指定對象。
拋出:ClassCastException - 如果指定對象的類型不允許它與此對象進行比較。
3、實例
public class UserInfo implements Comparable<UserInfo> {
private int id;
private String name;
private int age;
public UserInfo(int id, String name, int age) {
this.id = id;
this.name = name;
this.age = age;
}
@Override
public int compareTo(@NonNull UserInfo o) {
return age > o.age ? 1 : (age == o.age ? 0 : -1);
}
@Override
public String toString() {
return "UserInfo[id=" + id + " name=" + name + " age=" + age + "]";
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
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;
}
}
測試類
public class InterTest {
public static void main(String[] args) {
List<UserInfo> userInfoList = new ArrayList<>();
userInfoList.add(new UserInfo(0, "大強", 12));
userInfoList.add(new UserInfo(1, "大黃", 18));
userInfoList.add(new UserInfo(2, "大黑", 16));
userInfoList.add(new UserInfo(0, "大白", 52));
userInfoList.add(new UserInfo(0, "大紅", 8));
userInfoList.add(new UserInfo(0, "大花", 16));
userInfoList.add(new UserInfo(0, "大菜", 36));
System.out.println("排序前");
for (UserInfo userInfo : userInfoList) {
System.out.println(userInfo);
}
Collections.sort(userInfoList);
System.out.println("排序后");
for (UserInfo userInfo : userInfoList) {
System.out.println(userInfo);
}
}
}
輸出
排序前
UserInfo[id=0 name=大強 age=12]
UserInfo[id=1 name=大黃 age=18]
UserInfo[id=2 name=大黑 age=16]
UserInfo[id=0 name=大白 age=52]
UserInfo[id=0 name=大紅 age=8]
UserInfo[id=0 name=大花 age=16]
UserInfo[id=0 name=大菜 age=36]
排序后
UserInfo[id=0 name=大紅 age=8]
UserInfo[id=0 name=大強 age=12]
UserInfo[id=2 name=大黑 age=16]
UserInfo[id=0 name=大花 age=16]
UserInfo[id=1 name=大黃 age=18]
UserInfo[id=0 name=大菜 age=36]
UserInfo[id=0 name=大白 age=52]
二、Comparator接口
與上面的Comparable接口不同的是:
Comparator位于包java.util下,而Comparable位于包java.lang下。
Comparable接口將比較代碼嵌入需要進行比較的類的自身代碼中,而Comparator接口在一個獨立的類中實現比較。
如果前期類的設計沒有考慮到類的Compare問題而沒有實現Comparable接口,后期可以通過Comparator接口來實現比較算法進行排序,并且為了使用不同的排序標準做準備,比如:升序、降序。
Comparable接口強制進行自然排序,而Comparator接口不強制進行自然排序,可以指定排序順序。
實例:
public class UserInfo {
private int id;
private String name;
private int age;
public UserInfo(int id, String name, int age) {
this.id = id;
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "UserInfo[id=" + id + " name=" + name + " age=" + age + "]";
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
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;
}
}
public class InterTest {
public static void main(String[] args) {
List<UserInfo> userInfoList = new ArrayList<>();
userInfoList.add(new UserInfo(0, "大強", 12));
userInfoList.add(new UserInfo(1, "大黃", 18));
userInfoList.add(new UserInfo(2, "大黑", 16));
userInfoList.add(new UserInfo(0, "大白", 52));
userInfoList.add(new UserInfo(0, "紅紅", 8));
userInfoList.add(new UserInfo(0, "翠花", 16));
userInfoList.add(new UserInfo(0, "芹菜", 36));
System.out.println("排序前");
for (UserInfo userInfo : userInfoList) {
System.out.println(userInfo);
}
Collections.sort(userInfoList, new Comparator<UserInfo>() {
@Override
public int compare(UserInfo o1, UserInfo o2) {
return o1.getAge() > o2.getAge() ? 1 : (o1.getAge() == o2.getAge() ? 0 : -1);
}
});
System.out.println("排序后");
for (UserInfo userInfo : userInfoList) {
System.out.println(userInfo);
}
}
}
輸出:
排序前
UserInfo[id=0 name=大強 age=12]
UserInfo[id=1 name=大黃 age=18]
UserInfo[id=2 name=大黑 age=16]
UserInfo[id=0 name=大白 age=52]
UserInfo[id=0 name=紅紅 age=8]
UserInfo[id=0 name=翠花 age=16]
UserInfo[id=0 name=芹菜 age=36]
排序后
UserInfo[id=0 name=大紅 age=8]
UserInfo[id=0 name=大強 age=12]
UserInfo[id=2 name=大黑 age=16]
UserInfo[id=0 name=翠花 age=16]
UserInfo[id=1 name=大黃 age=18]
UserInfo[id=0 name=芹菜 age=36]
UserInfo[id=0 name=大白 age=52]