文章目錄
- 前言
- 接口分析
-
- Comparable接口
- Comparator接口
- compareTo和compare方法
- 相關之處
- 程式示例
-
- 調用預設的Comparable接口
- 調用重寫compareTo方法的Comparable接口
-
- 注意事項
- 調用重寫compareTo方法的Comparator接口
- 調用重寫compareTo方法的Comparator接口實作絕對值排序
- 反思總結
前言
- 包裝類Collections的排序方法可以運用到各種集合架構,非常友善
- 分析看不懂請結合程式示例看
- 有問題歡迎評論或者私信!!!
接口分析
Comparable接口
- Comparable接口在 java.lang.Comparable 包下
- Comparable接口的實作方法:public int compareTo(T t);
- Comparable接口是在集合的(類的)内部實作的排序方式,調用的實質 t1.compareTo(t2);
- 在排序對象本身支援互相比較所需要的接口(如Integer、String、Double、Float等)時,可以直接調用 Collections.sort() 方法的Comparable接口(參考程式示例)
- 當數值或ASCII碼值從小到大的預設順序或者排序的根據對象不滿足程式需求時,可以重寫compareTo方法(參考程式示例)
Comparator接口
- Comparator接口在 java.util.Comparator 包下
- Comparator接口的實作方法:public int compare(T t1, T t2);
- Comparator接口是在集合的(類的)外部實作的排序方式,需要用到一個比較容器,調用的實質是 compare(t1 , t2);(參考程式示例)
- 在排序對象本身不支援互相比較所需要的接口,例如對整數采用絕對值大小排序,顯然對象本身的Integer自然排序是不能實作的,同時如果Integer類也不容許你在它的内部重寫compareTo()去改變它的排序行為,是以就可以用到Comparator接口(參考程式示例)
compareTo和compare方法
-
Comparable接口的實作方法:public int compareTo(T t),調用的實質 t1.compareTo(t2);
在方法内部傳回一個運算結果,例如傳回:t1.x - t2.x,則按從小到大的順序排序
若傳回:t2.x - t1.x,則按從大到小的順序排序
-
Comparator接口的實作方法:public int compare(T t1, T t2),調用的實質是 compare(t1 , t2);
在方法内部傳回一個運算結果,例如傳回:t1.x - t2.x,則按從小到大的順序排序
若傳回:t2.x - t1.x,則按從大到小的順序排序
-
compareTo預設的調用可以實作字元串的比較,比較方法:先比較第一個字元,不同則傳回ASCII碼的內插補點,若第一個字元相同,則比較第二個字元,若前面字元相同則比較長度。
例如:
String a = 'abc'; String b = 'cde'; String c = 'abcde'; int d = a.compareTo(b); int e = a.compareTo(c);
傳回d = -2,由a的ASCII碼值減去b的ASCII碼值得來。e = -2,因為前字元相同,a.length() - c.length() = -2.
相關之處
- 對于一個對象的排序,既可以用Comparable接口實作,也能用Comparator接口實作,隻是兩種排序的實作方式不同,
- 在某些情況的排序下,可以用Comparator接口,在接口的compare方法中再次調用compareTo方法進行比較。例如如下情況:
輸入學生的學号、姓名、班級、成績,分别根據這四個資料進行排序。
對學号的排序,可以調用Comparable接口重寫comparaTo方法按學号從小到大排序
對姓名的排序,可以實作一個比較容器,在容器中重寫compare方法,在compare方法中調用compareTo方法實作對字元串的比較,然後傳回對字元串的比較結果。
class NameUPComparator implements java.util.Comparator {
public int compare(Object o1, Object o2) {
Student s1 = (Student)o1;// 轉化成目前類型的對象
Student s2 = (Student)o2;
return s1.getName().compareTo(s2.getName());
}
}
在調用sort方法時,則要通過:
程式示例
調用預設的Comparable接口
import java.util.ArrayList;
import java.util.Collections;
public class CompObj {
public String toString() {
return "[x = " + x + "]";
}
public static void main(String[] args) {
ArrayList<Integer> al = new ArrayList<Integer>();// 單一Integer資料的ArrayList,有本身支援比較的接口Integer
al.add(3);
al.add(1);
al.add(2);
System.out.println("Before sort!");
for (int i = 0; i < al.size(); i++) {
System.out.println(al.get(i));
}
Collections.sort(al); // 調用Collections的sort方法-靜态方法
System.out.println("After sort!");
for (int i = 0; i < al.size(); i++) {
System.out.println(al.get(i));
}
}
}
調用重寫compareTo方法的Comparable接口
根據x值排序
import java.util.ArrayList;
import java.util.Collections;
public class CompObj implements java.lang.Comparable { // 定義要排序的類
int x;
int y;
public CompObj(int n1, int n2) {
x = n1;
y = n2;
}
public String toString() {
return "[x = " + x + ", y = " + y + "]";
}
public int compareTo(Object o) {
CompObj co = (CompObj) o;
if (this.x != co.x) {
return this.x - co.x;
} else {
return this.y - co.y;
}
}
public static void main(String[] args) {
ArrayList<CompObj> al = new ArrayList<CompObj>();
al.add(new CompObj(3, 1));
al.add(new CompObj(1, 3));
al.add(new CompObj(2, 2));
al.add(new CompObj(2, 1));
System.out.println("Before sort!");
for (int i = 0; i < al.size(); i++) {
System.out.println(al.get(i));
}
Collections.sort(al); // 調用Collections的sort方法-靜态方法
System.out.println("After sort!");
for (int i = 0; i < al.size(); i++) {
System.out.println(al.get(i));
}
}
}
注意事項
- compareTo()方法的形參為Object類的對象,在比較之前要進行類型轉換成為CompObj類的對象
- 在重寫的compareTo方法中,若倆對象的x值相同,則比較y值
- 若改為
則按照從大到小的順序排序if (this.x != co.x) { return co.x - this.x; } else { return co.y - this.y; }
調用重寫compareTo方法的Comparator接口
根據y值排序
import java.util.ArrayList;
import java.util.Collections;
class ObjComparator implements java.util.Comparator {
public int compare(Object o1, Object o2) {
CompObj co1 = (CompObj) o1; // 轉化成目前類型的對象
CompObj co2 = (CompObj) o2;
if (co1.y != co2.y) {
return co1.y - co2.y;// 先根據y值排序
} else {
return co1.x - co2.x;
}
}
}
public class CompObj { // 無需實作Comparable接口
int x;
int y;
public CompObj(int n1, int n2) {
x = n1;
y = n2;
}
public String toString() {
return "[x = " + x + ", y = " + y + "]";
}
public static void main(String[] args) {
ArrayList al = new ArrayList();
al.add(new CompObj(3, 2));
al.add(new CompObj(1, 3));
al.add(new CompObj(1, 2));
System.out.println("Before sort!");
for (int i = 0; i < al.size(); i++) {
System.out.println(al.get(i));
}
Collections.sort(al, new ObjComparator());
System.out.println("After sort!");
for (int i = 0; i < al.size(); i++) {
System.out.println(al.get(i));
}
}
}
調用重寫compareTo方法的Comparator接口實作絕對值排序
根據x的絕對值排序
import java.util.ArrayList;
import java.util.Collections;
class AbsComparator implements java.util.Comparator {
public int compare(Object o1, Object o2) {
CompObj co1 = (CompObj) o1;// 轉化成目前類型的對象
CompObj co2 = (CompObj) o2;
int v1 = Math.abs(co1.x);// 把對象co1的x成員轉化成絕對值
int v2 = Math.abs(co2.x);
return v1 - v2;
}
}
public class CompObj { // 無需實作Comparable接口
int x;
int y;
public CompObj(int n1, int n2) {
x = n1;
y = n2;
}
public String toString() {
return "[x = " + x + ", y = " + y + "]";
}
public static void main(String[] args) {
ArrayList al = new ArrayList();
al.add(new CompObj(3, 2));
al.add(new CompObj(-2, 3));
al.add(new CompObj(1, 2));
System.out.println("Before sort!");
for (int i = 0; i < al.size(); i++) {
System.out.println(al.get(i));
}
Collections.sort(al, new AbsComparator());
System.out.println("After sort!");
for (int i = 0; i < al.size(); i++) {
System.out.println(al.get(i));
}
}
}
反思總結
- 起床整到現在,餓的一批
- 覺得有幫助到你就點個贊吧🙏🙏🙏
- 下期出資料結構的約瑟夫問題