<Textended Comparable <T >>是什么意思?

时间:2019-11-05 05:43:47

标签: java generics comparable

我正在查看Java的TheAlgorithms存储库,并来到了第一个https://github.com/TheAlgorithms/Java/blob/master/Searches/SearchAlgorithm.java。我看到了<T extends Comparable<T>>,但我不知道这意味着什么。我对泛型只有一点点了解,而且我知道语法与参数类型范围有关,但是如果有人可以弄清楚它与Comparable<T>的关系以及Comparable<T>的作用,那将是很好的。是。

这个论坛上还有其他一些问题,类似于我的关于实施<T extends Comparable<T>>的问题,但是答案并没有真正阐明Comparable<T>是什么。

3 个答案:

答案 0 :(得分:3)

首先,您拥有一个Comparable界面,大致类似于:

public interface Comparable<T> {

    int compareTo(T other);
}

如您所见,Comparable的类型参数用作compareTo方法的参数。通常,T的type参数是与实现Comparable接口相同的类。这种通用设置有助于将相同类型的实例彼此进行比较。这是一个示例:

public class Name implements Comparable<Name> {

    @Override
    public int compareTo(Name other) {
        // compute & return result
    }
}

现在让我们说您有一个方法,该方法应该根据两个对象的自然顺序返回最大值。这种方法如下所示:

public static <U extends Comparable<U>> U max(U left, U right) {
    return left.compareTo(right) >= 0 ? left : right;
}

注意:使用U作为类型变量而不是T,以表明它与{{1 }}界面。

以上是通用方法。类型变量T的上限是Comparable。这意味着,代替U使用的type参数必须可分配给Comparable<U>(即其子类型)。例如,如果我们使用U作为类型参数,它将起作用,因为Comparable<U>可分配给Name。将上限指定为Name的原因是该方法需要调用Comparable<Name>才能正常运行。

Comparable<U>

如上所示,将compareTo作为返回类型还可以将结果分配给与参数类型相同的变量。


请注意,为了获得最大的灵活性,实际上应该像这样声明Name name1 = ...; Name name2 = ...; Name max = max(name1, name2); // U is inferred to be Name 方法:

U

区别在于使用max作为上限而不是public static <U extends Comparable<? super U>> U max(U left, U right) { return left.compareTo(right) >= 0 ? left : right; } 。这两个问答可以帮助解释为什么使用Comparable<? super U>可以提供更大的灵活性:

答案 1 :(得分:1)

为澄清起见,我们可以将这个令人困惑的表达式分解为元素,然后重新组合在一起。

前提

我们有一个方法find(? array[], ? key),它在数组中寻找key。我们想将此方法用于不同类型的输入参数,例如StringInteger等的数组/键。

参数类型<U>

我们将<U>放在方法签名的前面,以表明它是参数方法。这意味着在声明的其余部分,U是一个占位符,将被调用该方法的类型替换。 (出于以下原因,我将使用U而不是T。)

但是,我们不能将U替换为 any 类型,因为为了能够正确实现该方法,我们希望能够将数组中的元素彼此进行比较(例如,对数组进行排序)。用于定义此行为的常用接口是Comparable。它只有一个方法compareTo

类型绑定<U extends Comparable>

要要求U类型参数只能用Comparable的子类型替换(实例化),我们强加 type bound :{{1 }}。这样,我们就可以使用类型安全的方式在extends ComparablecompareTo之类的数组元素上调用key

但是,我们这里没有做完,因为array[0]本身是一个通用类型:Comparable,其中类型参数Comparable<T>控制{{1}的参数类型}。因此,我们在使用T时需要实例化compareTo

实例化T

在实例化Comparable<T>中的Comparable<T>之前,我们的表达式是T。我们需要将Comparable替换为所需的类型。 <U extends Comparable<T>>的参数类型应该是什么?如果我们将T的数组传递给compareTo,我们将比较String,依此类推。在一般情况下,我们将find的数组传递给{{1 }},因此我们想比较Strings类型的对象。因此,在这种情况下,我们用另一种通用类型UfindU中实例化T,与Comparable<T>

相同

答案 2 :(得分:0)

  

这意味着T是一个类类型,它是Comparable的子类型或继承该类,并且也接受一个泛型类型,并且它应该与T所表示的类具有相同的类型。

例如

按Employee类和员工类定义替换T如下。

Employee现在是T,并且Comparable的compareTo方法也必须接受Employee作为参数,因为T现在是每个Comparable的Employee。

class Employee implements Comparable<Employee>{

    @Override
    public int compareTo(Employee o) {
        return 0;
    }
}