簡體   English   中英

T擴展了Comparable <T>

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

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