简体   繁体   English

Java中的泛型和排序

[英]Generics and sorting in Java

Suppose you write a static function in Java to sort an array, much like Arrays.sort() . 假设您用Java编写了一个静态函数来对数组进行排序,就像Arrays.sort() The problem with Arrays.sort() is that it receives an array of Object, and throws a ClassCastException if its elements don't implement Comparable . Arrays.sort()的问题在于,它接收一个Object数组,如果其元素未实现Comparable ,则抛出ClassCastException

So you want your function to receive as an argument an array of a subtype of Comparable . 因此,您希望您的函数将Comparable子类型的数组作为参数接收。 Something like that could work: 这样的事情可能会起作用:

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

The problem with that signature is that you can still pass an array of Comparables with Integers and Strings for instance, which would cause a RuntimeException . 该签名的问题在于,例如,您仍然可以传递带有Integers和Strings的Comparables数组,这将导致RuntimeException

So, how can you create a function that will receive only an array whose elements implement Comparable and have all the same type (eg Integer, String, etc?) 因此,如何创建一个仅接收其元素实现Comparable并具有相同类型(例如Integer,String等)的数组的函数?

Use 采用

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

which is the most general specification to accomplish the task. 这是完成任务的最一般的规范。 Basically, it asserts, that T is a type which can be compared to itself. 它断言,基本上T是可以与自身进行比较的类型。

Dirk's answer is the best you can get, but Google Collections used exactly as you wrote to avoid bug in javac: Dirk的答案是您能得到的最好的答案,但是Google Collections的用法与您写的完全一样,以避免javac中的错误:

Why do you use the type <E extends Comparable> in various APIs, which is not "fully generified"? 为什么在各种API中使用类型<E extends Comparable> extended <E extends Comparable>而不被“完全泛化”? Shouldn't it be <E extends Comparable<?>> , <E extends Comparable<E>> or <E extends Comparable<? super E>> 不是<E extends Comparable<?>><E extends Comparable<E>>还是<E extends Comparable<? super E>> <E extends Comparable<? super E>> ? <E extends Comparable<? super E>>

The last suggestion is the correct one, as explained in Effective Java. 最后的建议是正确的,如有效Java中所述。 However, we will be using <E extends Comparable<E>> on parameterless methods in order to work around a hideous javac bug. 但是,我们将在无参数方法上使用<E extends Comparable<E>> ,以解决一个可怕的javac错误。 This will cause you problems when you use a very unusual type like java.sql.Timestamp which is comparable to a supertype. 当您使用类似java.sql.Timestamp的非常不同的类型(与超类可比)时,这将给您带来问题。 (Needs more explanation.) (需要更多说明。)

From: http://code.google.com/p/google-collections/wiki/Faq 发件人: http : //code.google.com/p/google-collections/wiki/常见问题解答

Now it's up to you... 现在由您决定...

In the post-1.5 Java world, reference arrays are just low-level implementation details. 在Java 1.5以后的世界中,引用数组只是底层实现细节。 Prefer, collections. 更喜欢收藏。

If you are interested in reference arrays, for some peculiar reason, you will be aware they really don't get on with generics. 如果您对引用数组感兴趣,则出于某些特殊原因,您将意识到它们确实与泛型无关。 You can't (reasonably) have an array of a generic type, such as Comparable<String> . 您不能(合理地)使用通用类型的数组,例如Comparable<String> That means that if Arrays.sort was genericised in a similar way to Collections.sort it would be over constrained. 这意味着,如果以与Collections.sort类似的方式来泛化Arrays.sort ,它将受到过度约束。

Because of the peculiarity of array typing, if you did want to over-constrain types, I think sort can be written more simply than Collections.sort without sacrificing anything significant. 由于数组类型的特殊性,如果您确实想过分约束类型, 我认为 sort可以比Collections.sort更简单地编写,而不会牺牲任何重要的信息。

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

If you want binary compatibility with pre-generics, then you will need a slight hack to get back to the Object[] signature, in a similar way to the likes of Collections.min . 如果要与前泛型二进制兼容,则需要采取一些技巧以类似于Collections.min方式返回到Object[]签名。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM