程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> 關於JAVA >> 檢查Comparator接口的契約義務

檢查Comparator接口的契約義務

編輯:關於JAVA

java.util.Comparator接口容易被實現並使用,但是在Comparator的API文檔裡有些部分還是應當仔細閱讀一下的。

實現了Comparator接口的類可以傳給例如Collections.sort這樣的排序方法。它們也可以被Map或者Set類使用,用來保證Map或者Set裡的元素始終是按某種順序排列的。TreeSet和TreeMap就是這樣的類。

在Comparator接口裡,只有一個方法是需要實現的:

int compare(Object o1,Object o2);

如果o1小於o2,返回一個負數;如果o1大於o2,返回一個正數;如果他們相等,則返回0;

這些就是通常為了完成比較所要做的一切,但是在Comparator接口的契約裡還有別的義務。

首先,compare方法一定要是對稱的,意思是compare(a,b)返回的結果要跟compare(b,a)相反。相反的結果意味著,要麼返回的值帶有不同的正負號,要麼都是0。注意,象compare(a,b)返回4而compare(b,a)返回-2這樣的情況是合法的。方法裡常常可能拋出異常,在這個方法裡拋出異常也要是對稱的。如果調用compare(a,b)時拋出了一個ClassCastException異常,那麼調用compare(b,a)時也必須拋出一個ClassCastException異常。

考慮下面的代碼片斷:

public int compareTo(Object o1, Object o2) {
if(o1 instanceof Long) {
Long ln = (Long)o1;
return ln.compareTo(o2);
} else {
return 0;
}
}

如果a是new Long(5),b是”Text”,那麼執行compare(o1,o2)將在java.lang.Long的compareTo方法裡拋出一個ClassCastException,而執行compare(o2,o1)時將返回0(譯者注:原文這裡是compare(o1,o2),根據上下文,應該是compare(o2,o1))。

其次,任何你准備重用的Comparator都必須是可序列化的。TreeSet和TreeMap類存儲Comparator以便進行比較,因此為了這兩個類能被序列化,它們使用的Comparator也必須能被序列化。

第三,如果進行比較操作時,有多種比較方法,那麼Comparator應當實現equals方法。開發者創建有多種比較形式的Comparator是很常見的,例如:

import java.util.Comparator;
public class ExampleComparator {
private int type;
public ExampleComparator(int i) {
this.type = i;
}
public int compareTo(Object o1, Object o2) {
if(type == 1) {
// one type of comparison
....
} else
if(type == 2) {
// another form of comparison
....
}
}
}

Comparator接口,通常被Collections.sort方法使用,它是JAVA中需要了解的一個很重要的部分,因為它有一些重要的契約義務,而它們經常被忽略了。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved