2010-02-11 70 views
25

我明白收集的get and put principle:如果一個方法需要一個集合,它將寫入一個類型T to,參數必須是Collection<? super T>,而如果它會讀取鍵入T,參數必須是Collection<? extends T>Java的泛型:Collections.max()簽名和比較器

但可能有人請解釋Collections.max()簽名:

public static <T> T max(Collection<? extends T> coll, 
        Comparator<? super T> comp) 

特別是它爲什麼Comparator<? super T>,而不是Comparator<? extends T>

回答

65

喬希布洛赫的助記符佩奇在這裏很有用。它代表:

生產者extends,消費者super

這意味着,當一個參數化類型被傳遞給方法產生的T實例(他們會從它以某種方式檢索),? extends T應被使用,因爲T的子類的任何實例也是T

當一個參數化類型被傳遞給方法消耗T實例(它們將被傳遞給它做的東西),? super T應該使用,因爲T一個實例可以合法地傳遞給一個接受任何方法一些超類型的T。例如,Comparator<Number>可以在Collection<Integer>上使用。 ? extends T將不起作用,因爲Comparator<Integer>無法在Collection<Number>上運行。

編輯: 爲了澄清多一點上獲取/放置(生成/使用):

public T something(); 
    ^

以上是產生T的方法。

public void something(T t); 
        ^

以上是消耗T的方法。

「Producer extends,Consumer super」適用於如何傳遞參數化對象的方法將使用該對象。在Collections.max()的情況下,物品將從Collection中檢索,因此它是生產商。這些項目將作爲參數傳遞給Comparator上的方法,因此它是消費者。

0

比較器需要能夠採取T作爲參數。

+0

我想也許我不完全理解get/put原則然後...? – 2010-02-11 23:09:08

+6

我推薦閱讀那些討論「PECS」的Effective Java章節。 想想這樣:如果我要求你對一個雙精選列表進行排序,並給你一個Comparator 來做這件事,你會怎麼看? – 2010-02-12 17:36:46

+0

你能擴大你的答案嗎?儘管對於高級java程序員來說答案可能很清楚,但它需要重新閱讀這個問題才能完全理解你在說什麼。我知道這可能是您以前的答案之一,但它出現在低質量帖子評論部分。 - [來自評論](https://stackoverflow.com/review/low-quality-posts/11445740) – Ferrybig 2016-02-29 08:53:25

1

比較器消耗一對Ts併產生一個int。該集合產生比較器消耗的Ts。

超級消耗,延伸產生。

關於獲取和放置原則,獲得生產和消費。