如何编写泛型方法来查找最大元素并调用该方法?

时间:2013-08-23 20:43:40

标签: java list generics

当我试图解决锻炼时from generics tutorial Q&A我的答案略有不同

我的答案

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>,会有什么不同吗?如果是这样?

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

  • 的列表后如何调用class B extends A

  

编写通用方法以查找范围中的最大元素   列表的[开始,结束]。

     

答案:

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

2 个答案:

答案 0 :(得分:8)

  

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

请注意,可比较始终是消费者,即Comparable<T>消费T个实例,因此最好使用Comparable<? super T>代替{{ 1}}(引用 - PECS )。如果您要比较超类实现Comparable<T>的类型,它会有所不同。请考虑以下代码:

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>调用该方法,因为 Child 未实现{{1}但是List<Child>

Comparable<Child>

因此,类型参数边界应为Comparable<Parent>

请注意,您无法将 Child 类更改为:

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

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


  

如果将T extends Comparable<? super T>替换为class Child extends Parent implements Comparable<Child> ,会有什么不同吗?是不是extends Object隐含?

嗯,两个界限之间存在差异。在1 st 界限中,类型参数的擦除为T extends Object & Comparable<? super T>,而在2 nd 界限中,擦除为T extends Comparable<? super T>。< / p>

因此,如果没有绑定Object,您的代码将编译为:

Comparable

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

答案 1 :(得分: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)

即。 T必须具有与本身相当的超类型。例如,T不能是Foo

    class Foo implements Comparable<Object>
无论如何,Foo没有意义; a Comparable只能与其自身类型进行有意义的比较。条款C extends Comparable<C>承认这一事实。