2010-01-15 25 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)