可比较<t>与原始可比较

时间:2015-06-28 02:08:58

标签: java sorting generics comparable

我最近写了一个简单的通用选择排序方法来获得它的乐趣,当我对某些东西感到有些困惑时。这是我的代码:

public static <T extends Comparable<T>> void sort(List<T> list) {
    for (int i = 0; i < list.size(); i++) {
        int minIndex = i; // Assume that the first element is the minimum for now.

        // Find smallest element in unsorted sub-list.
        for (int k = i + 1; k < list.size(); k++) {
            if (list.get(k).compareTo(list.get(minIndex)) < 0) {
                minIndex = k;
            }
        }

        // Swap smallest element with the first element in unsorted sub-list.
        T temp = list.get(i);
        list.set(i, list.get(minIndex));
        list.set(minIndex, temp);
    }
}

函数本身工作正常,但我对泛型有点困惑。我用:

<T extends Comparable<T>>

确保给定的List具有可比较的类型。但是,如果我使用原始的Comparable呢?那就是:

<T extends Comparable>

究竟会产生什么后果?

谢谢!

2 个答案:

答案 0 :(得分:7)

基本上,你失去了某种类型的安全性。

当您拥有T temp = list.get(i)时,您可以使用temp.compareTo做什么?

  • T extends Comparable<T>tempComparable<T>,这意味着您只能将T传递给compareTo
  • T extends ComparabletempComparable,这意味着您可以将任何内容传递到compareTo

第一个几乎肯定是你想要的,因为可比类型只能处理相同类型的对象。例如,String.compareTo只能处理String输入 - 如果你传入一个Integer,你将得到一个ClassCastException。

鉴于temp.compareTo的唯一安全输入是T类型的引用,通常没有充分理由使用原始类型。它偶尔有利于绕过类型系统,但在大多数情况下,它会消除类型安全,而不会给你任何回报。

答案 1 :(得分:1)

<T extends Comparable>适用于混合类型的可比较对象。例如,Integer个实例和String个实例都会满足这一要求,而<T extends Comparable<T>>则确保类型可以相互比较。

一个例子,下面的代码会编译,但由于类转换异常会引发运行时异常:

public static void main(String[] args)
{
    List<? extends Comparable> l = createList(Integer.valueOf(1), "Man");
    Collections.sort(l);
}

protected static <T extends Comparable<?>> List<T> createList(T ... args)
{
    return Arrays.asList(args);
}

通过限制为<T extends Comparable<T>,这将成为运行时检查,因为将方法更改为此可防止先前的代码编译。