):Comparable介面和Comparator介面
目錄
1 介紹
2 Comparable介面
3 Comparator介面
4 總結
1 介紹
有這樣2個人,一個人光頭,一個人有黑色頭髮,現在不允許染髮,只允許光頭的帶假髮,理由是有頭髮的人沒有必要再帶假髮,那麼誰可以有多種顏色的頭髮?在這種情況下,有頭髮的人,因為他的頭髮和自身繫結在一起,是無法在換頭髮的;而光頭的頭髮(假髮套)和其自身是不繫結的,可以根據自己喜歡換不同顏色的髮套。有頭髮的人叫Comparable,光頭不是孟飛,也不是樂嘉,叫Comparator。
Comparable和Comparator是java中2個比較介面。Comparable是和具體類繫結的,我們稱為“靜態繫結”(如上圖中有頭髮的人,頭髮是Comparable,頭是具體的類)。而對於Comparator,具體的類在需要是可選擇不同的Comparator繫結,是“動態繫結”(
2 Comparable介面
java.lang. Comparable介面定義類的自然順序,實現該介面的類就可以按這種方式排序。Comparable只包含一個方法:
- publicinterface Comparable<T> {
- publicint compareTo(T o);
- }
-
import
- /**
- * @version 1.0
- * @date 2012-11-15 下午2:25:27
- * @fuction 實現Comparable介面 (先按序號比較,序號相等在比較姓名) */
- publicclass Student implements Comparable
- {
- //學號
- int num;
- //姓名
- String name;
- //constructor
-
public Student(int num,String name)
- {
- this.num=num;
- this.name=name;
- }
- //重寫java.lang中的介面Comparable的方法compareTo,定製比較的規則.但必須遵守比較規則(比較結果大返回正數,相等返回0,小返回負數)
- publicint compareTo(Object o) {
- Student s=(Student)o;
- int result=num>s.num ? 1:(num==s.num ? 0: -1);
- //學號相等時,按名字排序
- if(0==result)
- {
- //利用String的compareTo方法進行字元的比較
- result=name.compareTo(s.name);
- }
- return result;
- }
- @Override
- public String toString() {
- return"Student [num=" + num + ", name=" + name + "]";
- }
- /**
- * @param args
- */
- publicstaticvoid main(String[] args) {
- Student[] test=new Student[]{new Student(2, "wangwu"),
- new Student(1, "lisi"),
- new Student(1, "goudan") };
- //排序
- Arrays.sort(test);
- //列印
- for(int i=0;i<test.length;i++)
- {
- System.out.println(test[i]);
- }
- //搜尋姓名為“wangwu”的學生
- int index=Arrays.binarySearch(test,new Student(2,"wangwu"));
- System.out.println("查詢的學生在陣列中的位置:"+index);
- }
- }
3 Comparator介面
java.util.Comparator介面只包含2個方法
- int compare(T o1, T o2);
- boolean equals(Object obj);
int compare(T o1, T o2);比較用來排序的兩個引數。
boolean equals(Object obj);指示是否其他物件“等於”此 Comparator。
實現了compare介面的類具體的實現是在compare方法中自定義比較演算法,然後將Comparator物件(實現了java.util.Comparator介面的物件)作為一個引數傳遞給欲比較或排序物件collection的某些排序方法。某些排序方法指的是能夠接受java.util.Comparator引數的方法,比如:java.util. Arrays的public static void sort(Object[] a, Comparator c)和Collections的sort方法。
例子
- import java.util.Arrays;
- import java.util.Comparator;
- /**
- * @version 1.0
- * @date 2012-11-15 下午11:21:09
- * @fuction 實現Comparator介面的比較演算法
- *按學號排序 先按學號排序,學號相等時,按姓名排序 o1>o2返回1,o1=o2返回0,o1>o2返回-1
- */
- publicclass ByNumComparator implements Comparator {
- publicint compare(Object o1, Object o2) {
- Student s1 = (Student) o1;
- Student s2 = (Student) o2;
- // 按學號排序
- int result = s1.num > s2.num ? 1 : (s1.num == s2.num ? 0 : -1);
- // 學號相等時,按名字排序
- if (result == 0) {
- int copmpareName=s1.name.compareTo(s2.name);
- //利用String的compareTo方法進行字元的比較
- if(copmpareName>0)
- result=1;
- elseif (copmpareName==0)
- result=0;
- else
- result=-1;
- }
- return result;
- }
- publicstaticvoid main(String[] args) {
- Student[] test = new Student[] { new Student(2, "wangwu"),
- new Student(1, "lisi"), new Student(1, "goudan") };
- // 排序
- Arrays.sort(test, new ByNumComparator());
- // 列印
- System.out.println("排序之後");
- for (int i = 0; i < test.length; i++) {
- System.out.println(test[i]);
- }
- }
- }
輸出結果:
排序之後
Student [num=1, name=goudan]
Student [num=1, name=lisi]
Student [num=2, name=wangwu]
4 總結
一般在對物件進行比較或排序時,需要物件實現Comparable介面或者在使用排序方法(比如Arrays的sort)方法時,傳入實現了Comparator介面的類的物件。
分類: J2SE2009-01-21 17:32 1655人閱讀 評論(4) 收藏 舉報
Comparable & Comparator 都是用來實現集合中元素的比較、排序的,只是 Comparable 是在集合內部定義的方法實現的排序,Comparator 是在集合外部實現的排序,所以,如想實現排序,就需要在集合外定義 Comparator 介面的方法或在集合內實現 Comparable 介面的方法。
Comparator位於包java.util下,而Comparable位於包 java.lang下
Comparable 是一個物件本身就已經支援自比較所需要實現的介面(如 String、Integer 自己就可以完成比較大小操作,已經實現了Comparable介面)
自定義的類要在加入list容器中後能夠排序,可以實現Comparable介面,在用Collections類的sort方法排序時,如果不指定Comparator,那麼就以自然順序排序,如API所說:
Sorts the specified list into ascending order, according to the natural ordering of its elements. All elements in the list must implement the Comparable interface
這裡的自然順序就是實現Comparable介面設定的排序方式。
而 Comparator 是一個專用的比較器,當這個物件不支援自比較或者自比較函式不能滿足你的要求時,你可以寫一個比較器來完成兩個物件之間大小的比較。
可以說一個是自已完成比較,一個是外部程式實現比較的差別而已。
用 Comparator 是策略模式(strategy design pattern),就是不改變物件自身,而用一個策略物件(strategy object)來改變它的行為。
比如:你想對整數採用絕對值大小來排序,Integer 是不符合要求的,你不需要去修改 Integer 類(實際上你也不能這麼做)去改變它的排序行為,只要使用一個實現了 Comparator 介面的物件來實現控制它的排序就行了。
// AbsComparator.java
import java.util.*;
public class AbsComparator implements Comparator {
public int compare(Object o1, Object o2) {
int v1 = Math.abs(((Integer)o1).intValue());
int v2 = Math.abs(((Integer)o2).intValue());
return v1 > v2 ? 1 : (v1 == v2 ? 0 : -1);
}
}
可以用下面這個類測試 AbsComparator:
// Test.java
import java.util.*;
public class Test {
public static void main(String[] args) {
//產生一個20個隨機整數的陣列(有正有負)
Random rnd = new Random();
Integer[] integers = new Integer[20];
for(int i = 0; i < integers.length; i++)
integers[i] = new Integer(rnd.nextInt(100) * (rnd.nextBoolean() ? 1 : -1));
System.out.println("用Integer內建方法排序:");
Arrays.sort(integers);
System.out.println(Arrays.asList(integers));
System.out.println("用AbsComparator排序:");
Arrays.sort(integers, new AbsComparator());
System.out.println(Arrays.asList(integers));
}
}
Collections.sort((List<T> list, Comparator<? super T> c)是用來對list排序的。
如果不是呼叫sort方法,相要直接比較兩個物件的大小,如下:
Comparator定義了倆個方法,分別是 int compare(T o1, T o2)和 boolean equals(Object obj),
用於比較兩個Comparator是否相等
true only if the specified object is also a comparator and it imposes the same ordering as this comparator.
有時在實現Comparator介面時,並沒有實現equals方法,可程式並沒有報錯,原因是實現該介面的類也是Object類的子類,而Object類已經實現了equals方法
Comparable介面只提供了 int compareTo(T o)方法,也就是說假如我定義了一個Person類,這個類實現了 Comparable介面,那麼當我例項化Person類的person1後,我想比較person1和一個現有的Person物件person2的大小時,我就可以這樣來呼叫:person1.comparTo(person2),通過返回值就可以判斷了;而此時如果你定義了一個 PersonComparator(實現了Comparator介面)的話,那你就可以這樣:PersonComparator
comparator= new PersonComparator();
comparator.compare(person1,person2);。