java用泛型搜索数组中的最大元素
任务:
Write a generic method to find the maximal element in the range [begin, end) of a list.
答复:
public final class Algorithm {
public static <T extends Object & Comparable<? super T>>
T max(List<? extends T> list, int begin, int end) {
T maxElem = list.get(begin);
for (++begin; begin < end; ++begin)
if (maxElem.compareTo(list.get(begin)) < 0)
maxElem = list.get(begin);
return maxElem;
}
}
你能解释一下如何使用这个方法吗?以下签名的区别是什么:
public static <T extends Comparable<T>>
T max(List<? extends T> ar, int begin, int end) { ... }
# 1 楼答案
我想这里有两个问题:
Object
Comparable<? super T>
而不是Comparable<T>
李>对于第一个问题,实际上并不需要给出显式的
Object
边界,但这可能取决于您希望删除方法的方式。使用显式Object
绑定,您的类型参数将被擦除为Object
,没有该绑定,它将被擦除为Comparable
。大多数情况下,您不需要给出显式绑定,但这可能是API兼容性所必需的,如this post中所述至于第二个问题,如果您想将列表传递给
List<T>
,其中T
是可比较的,那么使用Comparable<? super T>
通常是一个好主意。为什么?假设您有一个类:和一个子类:
你想把一个
List<PartTimeEmployee>
传递给一个List<T>
。在你意识到你的PartTimeEmployee
并没有真正实现一个Comparable<PartTimeEmployee>
而是一个Comparable<Employee>
之前,这看起来很简单,很简单。因此,您要做的是将T
的边界更改为:。。然后你可以传递一个
List<PartTimeEmployee>
,因为它现在满足这个界限您必须这样做的原因是与,擦除(再次?)有关。对第一次看到这个错误时,您可能会从椅子上跳下来,并通过这样做快速使
PartTimeEmployee
具有可比性:。。。但是,嘿,你做错了。Java泛型不允许实现或扩展相同泛型类型的两个不同参数化实例化。您的意思是,
PartTimeEmployee
同时实现Comparable<Employee>
和Comparable<PartTimeEmployee>
。这样,在PartTimeEmployee
中就有两种方法:擦除后,它们都将成为:
现在你有了重复的方法。这就是为什么它是非法的
然而,在本例中,由于您有一个
List<? extends T>
作为参数类型,我认为您最好使用Comparable<T>
,因为当您传递一个List<PartTimeEmployee>
时,T
将被推断为Employee
,因此将满足边界# 2 楼答案
问题
public static <T extends Object & Comparable<? super T>>
和public static <T extends Comparable<T>>
之间的区别第一部分:为什么
正如在this answer中很好地解释的那样,这是为了与1.5API之前的API向后兼容。所以,如果你没有这个问题,你可以删除它
第二部分:为什么{}而不是{}
让我们看两个类
A
和B
,其中B
继承A
。您使这两个函数都实现了Comparable
,但自然排序的逻辑在A
和B
中是相同的。因此,您将编写类定义,如下所示:因此,
B
实现了Comparable<A>
,而不是Comparable<B>
。如果是后者,您将无法对List<A>
进行排序,其中列表的元素都是B
和A
类型。因此super
来自JDK的示例:
java.util.Date
和java.sql.Date
。后者继承前者。您将看到java.sql.Date
实现了Comparable<**java.util.Date**>