4

我是泛型(以及 Java 和 Stack Overflow)的新手,我正在学习的教科书中有一点讨论了泛型二叉搜索树的实现(摘录如下)。

Comparable 接口是通用的,所以让我们考虑在搜索树中存储以下类型的元素:

<T 扩展可比性<T>>

这仍然会导致问题。假设 Dog 和 Cat 都是 Mammal 类的子类,并且 Mammal 类实现了 Comparable 接口。现在,如果我们创建一个存储 Mammal 对象的二叉搜索树,那么可以添加 Dog 和 Cat,但实际上并不能相互比较。因此,如果以这种特定方式使用此解决方案,则与使用 Comparable 的非泛型版本存在相同的问题。一个更全面的解决方案,虽然在智力上不那么令人满意,但是将泛型类型编写为:

< T 扩展可比性< ? 超级T>>

该声明将元素的可比性限制为 T 的任何超类。

所以我明白为什么类型参数需要是Comparable< T>,但是这本书声称如果Mammals 的树包含尝试相互调用该compareTo()方法的不同子类型,这可能会带来问题。好吧,如果树中Catand对象的引用类型是,那么它们不会调用's方法(being ),使其成为有效比较(仅在级别上)吗?DogMammalMammalcompareTo()Comparable< Mammal>Mammal

我不明白有什么区别Comparable< ? super T>,因为那不是一回事,除非如果Mammals 不是Comparable,那么它会退回到Comparable像 class 或其他东西这样的超Animal类?

我可能遗漏了一些东西,比如一些令人讨厌的类型擦除后果或一些会导致比较无法像我想的那样工作的东西。

4

3 回答 3

3

好的,所以你明白这<T extends Comparable<T>>适用于这样的类:

class Mammal extends Comparable<Mammal>

现在你有一个子类Mammal, Cat: class Cat extends Mammal。由于继承Cat也实现了 ,并且正如您所说,由于它继承自Comparable<Mammal>的方法,它可以与所有哺乳动物(当然包括猫)进行比较。compareTo(Mammal)Mammal

但现在的问题是,Cat绑定不工作<T extends Comparable<T>>,因为Cat不实现Comparable<Cat>。您无法通过Cat实现来解决此问题Comparable<Cat>,因为您只能实现具有一个类型参数的接口。

但是从概念上讲,对 的列表进行排序是没有问题的Cat,因为Cats 可以与其他Cats 进行比较(它们可以与所有哺乳动物进行比较,这更普遍;但重点是它们可以与猫进行比较)。所以问题是我们的界限太严格了。

<T extends Comparable<? super T>>解决了这个问题,并允许Cat使用。回想一下 PECS 规则——生产者extends消费者super。好吧,Comparable 是消费者而不是生产者,因为您将类型 T 的参数传递给它的compareTo方法(消费),但没有方法需要返回类型 T(生产)。因此,super通配符是合适的。

于 2012-07-15T21:45:02.607 回答
2

对不起,重写这个让我更清楚

考虑接口

< T extends Comparable<T> >

然后考虑你的子类 Cat

Cat extends Comparable<Cat>

如果有像 Dog 这样的其他类,这会破坏二叉搜索树中的很多东西,因为 Comparable 需要两个相同类型的。猫应该看起来像这样

Cat extends Comparable<Animal>

作者将其更改为

< T extends Comparable<? super T> >

所以现在我们可以添加对象

Cat extends Comparable<Animal>

因为进入 Comparable 的参数必须是超类而不是类本身。所以它可以是哺乳动物 -> 动物 -> 对象,但不能是字符串

于 2012-07-15T15:35:31.210 回答
0

重点是这个。 您选择的类应该实现一个 Comparable 接口,其参数为It Self,或者它可以是任何其他将 Base 类作为可比较参数的超类。

于 2012-07-15T16:31:44.760 回答