2010-01-15 26 views
13

假設您編寫Java中的靜態函數來對數組進行排序,很像Arrays.sort()Arrays.sort()的問題在於它收到一個Object數組,如果其元素沒有實現Comparable,則拋出ClassCastExceptionJava中的泛型和排序

所以,你想你的函數接受作爲參數的Comparable亞型的數組。類似的東西可以工作:

static <T extends Comparable> void sort(T[] array); 

與簽名的問題是,你還可以通過比較公司的陣列整數和字符串,例如,這將導致RuntimeException

那麼,你怎麼可以創建將只接收一個數組,其元素實現可比性,並具有所有相同類型(例如整數,字符串,等等?)

+0

簽名的另一個問題是它在通用綁定中使用原始類型。 – 2010-01-15 15:31:01

回答

23

使用

static <T extends Comparable<? super T>> sort(T[] array); 

一個函數是完成任務的最一般的規範。基本上,它斷言,T是一種可以與自己比較的類型。

+0

艾哈......終於有效地使用了「超級」.. :) – falstro 2010-01-15 13:57:38

+4

+1。這是Collections.sort使用的相同簽名。 – Thilo 2010-01-15 13:58:47

13

德克的回答是,你可以得到最好的,但谷歌集合使用完全按照你寫的,以避免錯誤中的javac:

你爲什麼在不同的API使用類型<E extends Comparable>,這 不是「完全泛型「?它不應該是<E extends Comparable<?>><E extends Comparable<E>><E extends Comparable<? super E>>

最後的建議是正確的,因爲在有效 Java的解釋。但是,我們將使用<E extends Comparable<E>>的 無參數方法來解決可怕的javac錯誤。 當您使用非常不尋常的類型,如 java.sql.Timestamp這與超類型相當時,這會導致您的問題。 (需要更多的解釋。)

來源:http://code.google.com/p/google-collections/wiki/Faq

現在就看你......

+1

Wiki格式吃了尖括號...... – Thilo 2010-01-15 14:00:11

+0

yuppy,現在我用它代碼:( – nanda 2010-01-15 14:02:24

2

在後1.5 Java世界中,參考陣列都只是低層次的實現細節。首選,收藏。

如果您有興趣參考陣列,對於一些特殊的原因,你知道他們真的不與仿製藥獲得。你不能(合理地)有一個通用類型的數組,例如Comparable<String>。這意味着如果Arrays.sort以與Collections.sort類似的方式被通用化,則會受到限制。

因爲數組類型的特殊性,如果你確實想過度約束類型,我覺得sort能夠比Collections.sort更簡單地寫在不犧牲任何顯著。

public static <T extends Comparable<T>> sort(T[] array) 

如果你想預仿製藥的二進制兼容性,那麼你將需要一個輕微的黑客要回了Object[]簽名,以類似的方式向Collections.min喜歡。

public static <T extends Object & Comparable<T>> sort(T[] array)