理解了这个泛型?

现在让我们看一个更现实的例子。一个 java.util.TreeSet <E> 代表一个有序的元素是E类型的树。创建一个TreeSet的一个方法是传递一个 Comparator 对象给构造函数。这个 Comparator将会用来按照需要对TreeSet进行排序。

TreeSet(Comparator <E> c)

Comparator 接口是核心:

interface Comparator <T> {   int compare(T fst, T snd);   }

假定我们要创建一个 TreeSet <String> 并传递一个合适的 Comparator,我们需要传一个能比较String的Comparator。这可以是一个  Comparator <String>,也可以是一个 Comparator <Object>。然而我们不能用Comparator <Object>来调用上面的构造函数TreeSet(Comparator <E> c)。我们可以使用一个有下限的通配符来得到我们需要的灵活性:

TreeSet(Comparator <? super E> c)

这允许任何可用的Comparator被传递进去。

作为使用下限通配符最终的例子,让我们来看看方法 Collections.max(),它返回一个集合中的最大的元素。

现在,为了让max()能工作,传进来的集合中的所有元素必须实现 Comparatable接口。而且,他们必须都能够被彼此比较(all be comparable to each other)。第一个尝试是:

public static  <T extends Comparable <T>>  T max(Collection <T> coll)

就是说,方法的参数是某一个能和自己进行比较的T的集合。这限制太严格了。

为什么?考虑一个能和任何对象进行比较的类型:

class Foo implements Comparable <Object> {...} ...

Collection <Foo> cf = ...;

Collections.max(cf); // 应该能工作

cf 中的每个元素都可以和每个cf中的其他元素进行比较,因为每个这样的元素都是一个Foo,它可以和任意的对象进行比较,也可以和另一个Foo进行比较。

但是,使用上面的方法签名,我们发现这个调用被拒绝。推断出来的类型必须是Foo,但是Foo没有实现接口 Comparable <Foo>。

T 精确的(exactly)和自己能比较是不需要的。所需要的是 T能够和它的父类中的一个进行比较,这导出:(注:Collections.max()的实际方法签名更复杂,我们在第10部分再讨论。)

public static  <T extends Comparable <? super T>> T max(Collection <T> coll)

这个推论对大多数想让 Comparable 对任意类型生效的用法中都有效:你总是应该使用 Comparable <? super T>。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值