[英]T extends Comparable<T>
我有以下課程。
class MyClass<T>
它使用以下構造函數。
MyClass(Comparator<T> comparator, Collection<? extends T> data)
它有一個在構造函數中設置的字段,如下所示:
this.data = Collections.unmodifiableCollection(data);
在T實現Comparable的特殊情況下,我不想要傳入比較器,因為我可以使用自然順序。 所以我認為我應該能夠使用這個構造函數:
public <T extends Comparable<T>> MyClass(Collection<T> data)
但顯然存在類型不匹配:無法從Collection<T> to Collection<? extends T>
轉換Collection<T> to Collection<? extends T>
在上面的賦值語句中Collection<T> to Collection<? extends T>
。 我嘗試了各種各樣的事情:添加更多通用參數,等等,但都沒有工作。 我似乎無法指定一個綁定說:如果你有一個實現Comparable的類型T,那就做一些簡單的事情吧。
有任何想法嗎?
謝謝。
不幸的是,我不認為這種“如果可比較做其他事情那樣”邏輯是可能的Java類型系統。
您可以將Comparable和Non-Comparable案例拆分為單獨的類並將它們隱藏在接口后面,如下所示:
interface Interface<T> {
public void processData();
}
class MyClass<T> implements Interface<T> {
private final Collection<? extends T> data;
MyClass(Comparator<T> comparator, Collection<? extends T> data) {
this.data = data;
}
public void processData() {
// ...
}
}
class MyCompClass<T extends Comparable<T>> implements Interface<T> {
private final Collection<? extends T> data;
MyCompClass(Collection<? extends T> data) {
this.data = data;
}
public void processData() {
// ...
}
}
class Factory {
static <T extends Comparable<T>> Interface<T> create(Collection<? extends T> data) {
return new MyCompClass<T>(data);
}
static <T> Interface<T> create(Comparator<T> comparator, Collection<? extends T> data) {
return new MyClass<T>(comparator, data);
}
}
但這可能會導致大量重復的代碼。 另一種選擇是讓MyClass在其構造函數中需要Comparator,並在工廠中構建該比較器:
class MyClass<T> {
private final Collection<? extends T> data;
MyClass(Comparator<T> comparator, Collection<? extends T> data) {
this.data = data;
}
public void processData() {
// ...
}
}
class Factory {
static <T extends Comparable<T>> MyClass<T> create(Collection<? extends T> data) {
return new MyClass<T>(new Comparator<T>() {
public int compare(T o1, T o2) {
return o1.compareTo(o2);
}
}, data);
}
static <T> MyClass<T> create(Comparator<T> comparator, Collection<? extends T> data) {
return new MyClass<T>(comparator, data);
}
}
我同意這似乎是不可能的,因為直截了當的解決方案
class MyClass<T> {
Collection<? extends T> data;
public MyClass(Comparator<T> comparator, Collection<? extends T> data) {
this.data = data;
}
public <E extends T & Comparable<T>> MyClass(Collection<E> data) {
this.data = data;
}
}
被編譯器拒絕
當第一個綁定是類型參數時,無法指定任何其他綁定的
Comparable<T>
另請參見為什么我不能在具有多個邊界的類型參數中使用類型參數? (特別是Chris Povirk的回答)。
至於解決方案,我同意Chris B.
您可以將常規構造函數用於第一種情況,將工廠方法用於第二種情況:
class MyClass<T> {
Collection<? extends T> data;
Comparator<? super T> comparator;
public MyClass(Comparator<? super T> comparator, Collection<? extends T> data) {
this.data = data;
this.comparator = comparator;
}
public static <T extends Comparable<? super T>> MyClass<T> fromComparable(Collection<T> data) {
return new MyClass<T>(Collections.reverseOrder(Collections.reverseOrder()), data);
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.