簡體   English   中英

如何為接口的所有實現實現compareTo?

[英]How to implement compareTo for all implementations of an interface?

在Java中,為接口的所有實現提供自然順序的最佳方法是什么?

我有一個接口,我想通過擴展Comparable接口來確保/提供所有實現之間的自然順序:

public interface MyInterface extends Comparable<MyInterface> {

}

該接口將有多種實現,每種實現都可以為其自己的實例定義自然排序,但是可能不知道如何針對其他實現來進行排序。

我使用的一種方法是引入遞歸泛型,並按實現和實例划分自然順序比較:

public interface MyInterface<X extends MyInterface<X>> extends Comparable<MyInterface> {

  @Override
  default int compareTo(MyInterface o) {
    // the interface defines how to compare between implementations, say...
    int comp = this.getClass().getSimpleName().compareTo(o.getClass().getSimpleName());
    if (comp == 0) {
      // but delegates to compare between instances of the same implementation
      comp = compare((X) o);
    }
    return comp;
  }

  int compare(X other);
}

這意味着MyInterface的實現只需在自己的實例之間進行比較:

public class MyClass implements MyInterface<MyClass> {

  public int compare(MyClass other) {
    return 0; // ... or something more useful... 
  }
}

但是,遞歸泛型可能變得很難維護。

有沒有更好的辦法?

您可以移動此強制轉換compare((X) o); 從接口的默認方法到實現,因此您根本不需要泛型<X extends MyInterface<X>>

public interface MyInterface extends Comparable<MyInterface> {
    @Override
    default int compareTo(MyInterface o) {
        ...
        comp = compare(o);
        ...
    }
    int compare(MyInterface other);
}

在這種情況下,實現可能如下所示:

public class MyClass implements MyInterface {
    private Integer property;
    public int compare(MyInterface other) {
        return Integer.compare(this.property, ((MyClass) other).property);
    }
}

因此,這是到目前為止我能想到的最好的方法,將我的原始方法與Ruslan的答案相結合,並試圖權衡取舍:

我們定義的接口沒有遞歸泛型:

public interface MyInterface extends Comparable<MyInterface> {

  @Override // as per the Comparable interface (not needed, but included here for clarity)
  int compareTo(MyInterface o);
}

然后,我們創建一個抽象類,該類定義實現之間的比較,並委托給實現以在該實現的實例之間進行比較。 由於我們將compare()方法的范圍限制為protected ,因此這改善了在接口中具有此功能的能力。

public abstract class MyAbstractClass implements MyInterface {

  @Override
  public int compareTo(MyInterface o) {
    // the interface defines how to compare between implementations, say...
    int comp = this.getClass().getSimpleName().compareTo(o.getClass().getSimpleName());
    if (comp == 0) {
      // but delegates to compare between instances of the same implementation
      comp = compare(o);
    }
    return comp;
  }

  protected abstract int compare(MyInterface other);
}

然后在每個實現中,我們檢查/廣播到該實現。 切勿使用自身以外的其他實現來調用此方法,但是為了安全起見,如果發生這種情況,我們將拋出IllegalArgumentException

public class MyClass implements MyInterface {

  public int compare(MyClass o) {
    if (o instanceof MyClass) {
      return 0; // ... or something more useful... 
    } else {
      throw new IllegalArgumentException("Cannot compare " + this.getClass() + " with " + o.getClass());
    }
  }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM