[英]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.