簡體   English   中英

java.util.Comparator.naturalOrder 需要一個<T extends Comparable<? super T> &gt; 並返回一個比較器<T> - 為什么?

[英]java.util.Comparator.naturalOrder takes a <T extends Comparable<? super T>> and returns a Comparator<T> - why?

(如果這是重復的,請指出正確的答案!我搜索並閱讀了幾個(> 5)相關問題,但似乎沒有一個問題。還查看了泛型常見問題解答和其他來源...)

當一個集合類采用一個比較器時,它的類型應該是Comparator<? super T> Comparator<? super T>用於您的參數化類型T 你可以看到很多地方,例如, TreeMap 好的。

我的問題是使用Comparator.naturalOrder() ,它在T extends Comparable<? super T> T extends Comparable<? super T>但返回一個Comparator<T> 我試圖在我的集合類中有一個字段,該字段包含用戶指定的比較器或Comparator.naturalOrder器。

我無法讓它工作。 我的所有相關問題是:

  1. Comparator.naturalOrder如何正確使用?
    • 我可以做我想做的事情,它有一個可以存儲用戶提供的比較器或naturalOrder比較器的naturalOrder嗎?
  2. 鑒於大多數集合類(在框架中)在T上參數化,而不是T implements Comparable<? super T> T implements Comparable<? super T> ,這是選擇的設計模式, naturalOrder有什么用,因為它需要后者有界通配符,而不是不受約束的類型參數?

謝謝!

以下是帶有編譯器錯誤的實際示例:

所以:如果我在某個 T 沒有邊界的類中有這樣的代碼(就像在所有現有的集合類中一樣):

class Foo<T> {

    private Comparator<? super T> comparator;

    public void someMethod(Comparator<? super T> comparator)
    {
        this.comparator = comparator;                  // no compile error
        this.comparator = Comparator.naturalOrder();   // incompatible types
    }
}

出現此錯誤:

Error:(331, 50) java: incompatible types: inferred type does not conform to upper bound(s)
    inferred: T
    upper bound(s): java.lang.Comparable<? super T>

那么,如果我決定放棄? super T ? super T然后我有:

class Foo<T> {

    private Comparator<T> comparator;

    public void someMethod(ComparatorT> comparator)
    {
        this.comparator = comparator;                  // no compile error
        this.comparator = Comparator.naturalOrder();   // incompatible types
    }
}

我在哪里

Error:(nnn, 50) java: incompatible types: inference variable T has incompatible bounds
    equality constraints: T
    upper bounds: java.lang.Comparable<? super T>

這編譯:

import java.util.*;

class Foo<T extends Comparable<? super T>> {

    private Comparator<T> comparator;

    public void someMethod(Comparator<T> comparator)
    {
       this.comparator = comparator;                  // no compile error
       this.comparator = Comparator.<T>naturalOrder(); // <T> is optional, compiler can infer
    }
}

考慮它的最簡單方法是:您嘗試將類型 T 與 Comparator 接口一起使用,這對其施加了某些要求(特別是它具有 T 必須實現 Comparable 接口的奇特遞歸要求)。 您在泛化 (?) 類時沒有強加這樣的要求,因此編譯器不滿意。 您對 T 的要求必須與您使用它的類一樣強烈。

您對自然排序方法的作用感到困惑。 它只需要一個實現 Comparable 的類並為其創建默認的 Comparator 。 沒有辦法解決它——你不能為不可比較的東西創建一個比較器。

您希望 TreeMap 需要 Comparable,但您不能,因為只要您提供了 Comparator,就可以使用不可比較的東西。 所以 TreeMap 最終沒有強制執行 Comparable 並且只是在運行時顯式轉換(並拋出異常)。

我想您必須實現 Comparable 才能在示例中的類 Foo 中使用 Comparator.naturalOrder() 。 您必須有一個方法 compareTo(Object o),該方法是實現自然順序的方法,因此您無需將其存儲在變量中。

我認為您可以在至少在 Java 8 中不實現可比較接口的類中使用比較器,因此它們不實現 compareTo(Object o) 但您必須實現它

@FunctionalInterface
public interface Comparator<T>

這是來自 Java 8 API

一個比較函數,它對某些對象集合進行總排序。 比較器可以傳遞給排序方法(例如 Collections.sort 或 Arrays.sort)以允許精確控制排序順序。 比較器還可用於控制某些數據結構(例如排序集或排序映射)的順序,或為沒有自然排序的對象集合提供排序。

一種實現和初始化它的方法:

private  Comparator<Operario> ComparatorOperario =
    (o, p)-> o.getNombre().compareTo(p.getNombre());

那么你可以為這個變量設置 getter 和 setter,這樣你就可以改變排序方式

請注意,類Operario沒有實現Comparable ,它使用Comparator<Operario>比較來自類 Operario 的 2 個屬性,在本例中為兩個字符串。

暫無
暫無

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

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