9

当我试图从泛型教程问答中解决练习时,我的答案略有不同

我的答案

public static <T extends Comparable<? super T>>
    T max(List<? extends T> list, int begin, int end) //Option1

public static <T extends Comparable<T>>
    T max(List<? extends T> list, int begin, int end) //Option2

从下面引用的答案

所以我的问题是

  • 选项1:如果T extends Object & Comparable<? super T>替换为T extends Comparable<? super T>.会有什么不同吗?不是extends Object隐含的吗?

  • 选项2:如果Comparable<? super T>替换为会有什么不同Comparable<T>吗?如果是这样怎么办?

  • List<? extends Comparable<? super Comparable<? super T>>> list;Eclipse 代码完成在 Ctrl+1 上创建局部变量,max(list, 1, 10);这有点冗长。如何定义扩展Comparable<? super T>、创建列表并将实例添加到列表并调用以下方法的类(层次结构)?基本上我想知道max()在将类实例添加A or B 到列表后如何调用class B extends A


编写一个通用方法来查找列表的 [begin, end) 范围内的最大元素。

回答:

import java.util.*;

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;
    }
}
4

2 回答 2

8

如果Comparable<? super T>替换为会有什么不同Comparable<T>吗?如果是这样怎么办?

请记住,Comparables始终是消费者,即 aComparable<T>消费T实例,因此应该始终优先使用它Comparable<? super T>而不是Comparable<T>(Quoting - PECS )。如果您正在比较其超类实现 a 的类型,这将有所不同Comparable<SuperType>。考虑以下代码:

class Parent implements Comparable<Parent> {
    protected String name;

    @Override
    public int compareTo(Parent o) {
        return this.name.compareTo(o.name);
    }
}

class Child extends Parent {
    public Child(String name) {
        this.name = name;
    }
}

现在,如果您将类型参数指定为T extends Comparable<T>,您将无法为 调用该方法List<Child>,因为Child没有实现Comparable<Child>但是Comparable<Parent>

public static <T extends Comparable<T>> T max(List<? extends T> list, int begin, int end) {
    ...
}

public static void main(String[] args) {
    List<Child> list = new ArrayList<Child>();
    max(list, 0, 2);  // Error with current method. Child does not implement Comparable<Child>
}

因此类型参数边界应该是T extends Comparable<? super T>.

请注意,您不能将Child类更改为:

class Child extends Parent implements Comparable<Child>

因为在这种情况下,类将从相同泛型类型的不同实例扩展,这是不允许的。


T extends Object & Comparable<? super T>如果换成T extends Comparable<? super T>.会有什么不同吗?扩展对象不是隐式的吗?

嗯,这两个界限是有区别的。在第一个界限中,类型参数的擦除是Object,而在第二个界限中,擦除是Comparable

因此,没有Object限制,您的代码将编译为:

public static Comparable max(List list, int begin, int end)

当您生成遗留的非通用代码时,问题可能会出现。有必要也给出Object上限以避免破坏字节码的兼容性。您可以在此链接上阅读有关它的更多信息:Angelika Langer - Programming Idioms

于 2013-08-23T20:52:21.247 回答
0

看起来通配符比必要的多。我可能会去

public static <T extends Comparable<? super T>>
    T max(List<T> list, int begin, int end)

一个更受限制的版本:

public static <T extends C, C extends Comparable<C>>
    T max(List<T> list, int begin, int end)

ie必须有一个与自身T相当的超类型。例如不能TFoo

    class Foo implements Comparable<Object>

Foo 无论如何都没有意义;Comparable 只能与它自己的同类进行有意义的比较。该条款C extends Comparable<C>承认这一事实。

于 2013-08-23T21:45:03.613 回答