15

假设您在 Java 中编写了一个静态函数来对数组进行排序,就像Arrays.sort(). 问题Arrays.sort()在于它接收一个对象数组,ClassCastException如果它的元素没有实现则抛出一个Comparable

所以你希望你的函数接收一个子类型的数组作为参数Comparable。像这样的东西可以工作:

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

该签名的问题在于,您仍然可以传递带有整数和字符串的 Comparables 数组,这将导致RuntimeException.

那么,如何创建一个只接收其元素实现 Comparable 并且具有所有相同类型(例如 Integer、String 等)的数组的函数?

4

3 回答 3

24

利用

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

这是完成任务的最通用规范。基本上,它断言,这T是一种可以与自身进行比较的类型。

于 2010-01-15T13:53:26.063 回答
15

Dirk 的答案是你能得到的最好的答案,但谷歌收藏完全按照你写的那样使用,以避免 javac 中的错误:

为什么<E extends Comparable>在各种 API 中都使用类型,而不是“完全泛化”?不应该是<E extends Comparable<?>><E extends Comparable<E>>还是<E extends Comparable<? super E>>

最后一个建议是正确的,如 Effective Java 中所述。但是,我们将使用无<E extends Comparable<E>>参数方法来解决一个可怕的 javac 错误。当您使用与超类型相当的非常不寻常的类型时,这会给您带来问题 java.sql.Timestamp。(需要更多解释。)

来自:http ://code.google.com/p/google-collections/wiki/Faq

现在就看你了...

于 2010-01-15T13:58:24.103 回答
2

在 1.5 后的 Java 世界中,引用数组只是低级的实现细节。喜欢,收藏。

如果您对引用数组感兴趣,出于某种特殊原因,您会意识到它们确实无法使用泛型。您不能(合理地)拥有泛型类型的数组,例如Comparable<String>. 这意味着 if以与它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)
于 2010-01-15T15:30:05.747 回答