Java朝花夕拾の實現Comparable接口 – JAVA編程語言程序開發技術文章

Java.lang.Comparable接口中唯一的方法是compareTo(),在該方法中可以進行簡單的相等比較以及執行順序比較,接口實現框架如下:

[java]
public class ComparableImpl implements Comparable<ComparableImpl> { 
 
    @Override 
    public int compareTo(ComparableImpl o) { 
        // TODO Auto-generated method stub  
        return 0; 
    } 
 

public class ComparableImpl implements Comparable<ComparableImpl> {

 @Override
 public int compareTo(ComparableImpl o) {
  // TODO Auto-generated method stub
  return 0;
 }

}

一個類實現瞭Comparable接口,則說明它的實例具有內在的排序關系,就可以跟多種泛型算法以及依賴於該接口的集合實現進行協作。依賴於比較關系的類包括有序集合類TreeSet和TreeMap,以及工具類Collections和Arrays。

若一個數組中的元素實現瞭Comparable接口,則可以直接使用Arrays類的sort方法對這個數組進行排序。Java平臺庫中的所有值類(value classes)都實現瞭Comparable接口。

Comparable的規范說明如下:將當前這個對象與指定對象進行順序比較。當該對象小於、等於或大於指定對象時,分別返回一個負整數、零或者正整數。如果由於指定對象的類型而使得無法進行比較,則拋出ClassCastException異常。www.aiwalls.com

compareTo方法的實現必須滿足如下幾個限制條件:自反性、對稱性、傳遞性和非空性。

一般來說,comparaTo方法的相等測試應該返回與equals方法相同的結果。如果相同,則由compareTo方法施加的順序關系被稱為“與equals一致”;如果不同,則順序關系被稱為“與equals不一致”。如果一個類的compareTo方法與equals方法的順序關系不一致,那麼它仍然能正常工作,隻是,如果一個有序集合包含瞭該類的實例,則這個集合可能無法遵循某些集合接口的通用約定。因為集合接口的通用約定是按照equals方法定義的,而有序集合使用瞭由compareTo施加的相等測試。下面是實現瞭Comparable接口的類,同時,該類還重寫瞭equals和hashCode等方法:

[java]
public abstract class ZLTextPosition implements Comparable<ZLTextPosition> { 
     
    public abstract int getParagraphIndex(); 
    public abstract int getElementIndex(); 
    public abstract int getCharIndex(); 
     
    public boolean samePositionAs(ZLTextPosition position) { 
        return 
            getParagraphIndex() == position.getParagraphIndex() && 
            getElementIndex() == position.getElementIndex() && 
            getCharIndex() == position.getCharIndex(); 
    } 
     
    @Override 
    public int compareTo(ZLTextPosition position) { 
        final int p0 = getParagraphIndex(); 
        final int p1 = position.getParagraphIndex(); 
        if (p0 != p1) { 
            return p0 < p1 ? -1 : 1; 
        } 
         
        final int e0 = getElementIndex(); 
        final int e1 = position.getElementIndex(); 
        if (e0 != e1) { 
            return e0 < e1 ? -1 : 1; 
        } 
         
        final int c0 = getCharIndex(); 
        final int c1 = position.getCharIndex(); 
        if (c0 != c1) { 
            return c0 < c1 ? -1 : 1; 
        } 
        return 0; 
    } 
     
    @Override 
    public boolean equals(Object obj) { 
        if (this == obj) { 
            return true; 
        } 
        if (!(obj instanceof ZLTextPosition)) { 
            return false; 
        } 
         
        final ZLTextPosition position = (ZLTextPosition)obj; 
        return samePositionAs(position); 
    } 
     
    @Override 
    public int hashCode() { 
        return (getParagraphIndex() << 16) + (getElementIndex() << 8) + getCharIndex(); 
    } 
     
    @Override 
    public String toString() { 
        return getClass().getName() + " " + getParagraphIndex() + " " + getElementIndex() + " " + getCharIndex(); 
    } 
     

public abstract class ZLTextPosition implements Comparable<ZLTextPosition> {
 
 public abstract int getParagraphIndex();
 public abstract int getElementIndex();
 public abstract int getCharIndex();
 
 public boolean samePositionAs(ZLTextPosition position) {
  return
   getParagraphIndex() == position.getParagraphIndex() &&
   getElementIndex() == position.getElementIndex() &&
   getCharIndex() == position.getCharIndex();
 }
 
 @Override
 public int compareTo(ZLTextPosition position) {
  final int p0 = getParagraphIndex();
  final int p1 = position.getParagraphIndex();
  if (p0 != p1) {
   return p0 < p1 ? -1 : 1;
  }
  
  final int e0 = getElementIndex();
  final int e1 = position.getElementIndex();
  if (e0 != e1) {
   return e0 < e1 ? -1 : 1;
  }
  
  final int c0 = getCharIndex();
  final int c1 = position.getCharIndex();
  if (c0 != c1) {
   return c0 < c1 ? -1 : 1;
  }
  return 0;
 }
 
 @Override
 public boolean equals(Object obj) {
  if (this == obj) {
   return true;
  }
  if (!(obj instanceof ZLTextPosition)) {
   return false;
  }
  
  final ZLTextPosition position = (ZLTextPosition)obj;
  return samePositionAs(position);
 }
 
 @Override
 public int hashCode() {
  return (getParagraphIndex() << 16) + (getElementIndex() << 8) + getCharIndex();
 }
 
 @Override
 public String toString() {
  return getClass().getName() + " " + getParagraphIndex() + " " + getElementIndex() + " " + getCharIndex();
 }
 
}

摘自 ASCE1885

發佈留言