<T extends Comparable<T>> 是什么意思?
What does <T extends Comparable<T>> mean?
我正在查看 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>
是什么。
It means that T is a class type which is subtype of or inheriting Comparable which also accepts a generic type and it should be of same type as the class which is represented by T here.
例如
将 T 替换为 Employee class 和 Employee class 定义如下。
Employee 现在是 T,Comparable 的 compareTo 方法也必须接受 Employee 作为参数,因为 T 现在是每个 Comparable 的 Employee。
class Employee implements Comparable<Employee>{
@Override
public int compareTo(Employee o) {
return 0;
}
}
为了澄清,我们可以将这个看起来令人费解的表达式分解成它的元素,然后将它们放回一起。
前提
我们有一个方法 find(? array[], ? key)
可以在数组中查找 key
。我们想将此方法用于不同类型的输入参数,例如 String
、Integer
的 array/key,等等。
参数类型<U>
我们在方法签名前加上<U>
表示它是一个参数化方法。这意味着在声明的其余部分,U
是一个占位符,它将被调用该方法的类型替换。 (我使用 U
而不是 T
,原因在下面会变得很明显。)
但是,我们不能将 U
替换为 any 类型,因为为了能够正确实现该方法,我们希望能够比较数组彼此(例如对数组进行排序)。用于定义此行为的通用接口是 Comparable。它只有一个方法,compareTo
。
类型绑定<U extends Comparable>
为了要求 U
类型参数只能被 Comparable
的子类型替换(可实例化),我们强加了 type bound:extends Comparable
。这允许我们以类型安全的方式在 key
或 array[0]
等数组元素上调用 compareTo
。
然而,我们到这里还没有完成,因为 Comparable
本身就是一个泛型类型:Comparable<T>
,其中类型参数 T
控制 [= 的参数类型20=]。因此,我们需要在使用 Comparable<T>
时实例化 T
。
实例化Comparable<T>
在Comparable
中实例化T
之前,我们的表达式是<U extends Comparable<T>>
。我们需要将 T
替换为所需的类型。 compareTo
的参数类型应该是什么?如果我们将 String
的数组传递给 find
,我们将比较 Strings
,等等。在一般情况下,我们将 U
的数组传递给 [=41] =],所以我们想比较类型 U
的对象。所以在这种情况下我们在Comparable<T>
中用另一个泛型实例化T
,U
:<U extends Comparable<U>>
,这与<T extends Comparable<T>>
相同
首先,您有 Comparable
界面,大致如下所示:
public interface Comparable<T> {
int compareTo(T other);
}
可以看到,Comparable
的类型参数作为compareTo
方法的参数。通常,T
的类型参数与实现 Comparable
接口的 class 相同。这种通用设置有助于将相同类型的实例相互比较。这是一个例子:
public class Name implements Comparable<Name> {
@Override
public int compareTo(Name other) {
// compute & return result
}
}
现在假设您有一个方法应该return 两个对象的最大值按照它们的自然顺序。这样的方法可能如下所示:
public static <U extends Comparable<U>> U max(U left, U right) {
return left.compareTo(right) >= 0 ? left : right;
}
注意: 使用 U
作为类型变量而不是 T
以表明它与 [=18= 分开]用于Comparable
界面。
以上是通用方法。类型变量 U
的上限为 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
作为 return 类型还允许将结果分配给与参数类型相同的变量。
请注意,为了获得最大的灵活性,max
方法实际上应该这样声明:
public static <U extends Comparable<? super U>> U max(U left, U right) {
return left.compareTo(right) >= 0 ? left : right;
}
不同之处在于使用 Comparable<? super U>
而不是 Comparable<U>
作为上限。这两个问答应该有助于解释为什么使用 ? super U
提供更大的灵活性:
- What is PECS (Producer Extends Consumer Super)?
- Explanation of generic
<T extends Comparable<? super T>>
in collection.sort/ comparable code?
我正在查看 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>
是什么。
It means that T is a class type which is subtype of or inheriting Comparable which also accepts a generic type and it should be of same type as the class which is represented by T here.
例如
将 T 替换为 Employee class 和 Employee class 定义如下。
Employee 现在是 T,Comparable 的 compareTo 方法也必须接受 Employee 作为参数,因为 T 现在是每个 Comparable 的 Employee。
class Employee implements Comparable<Employee>{
@Override
public int compareTo(Employee o) {
return 0;
}
}
为了澄清,我们可以将这个看起来令人费解的表达式分解成它的元素,然后将它们放回一起。
前提
我们有一个方法 find(? array[], ? key)
可以在数组中查找 key
。我们想将此方法用于不同类型的输入参数,例如 String
、Integer
的 array/key,等等。
参数类型<U>
我们在方法签名前加上<U>
表示它是一个参数化方法。这意味着在声明的其余部分,U
是一个占位符,它将被调用该方法的类型替换。 (我使用 U
而不是 T
,原因在下面会变得很明显。)
但是,我们不能将 U
替换为 any 类型,因为为了能够正确实现该方法,我们希望能够比较数组彼此(例如对数组进行排序)。用于定义此行为的通用接口是 Comparable。它只有一个方法,compareTo
。
类型绑定<U extends Comparable>
为了要求 U
类型参数只能被 Comparable
的子类型替换(可实例化),我们强加了 type bound:extends Comparable
。这允许我们以类型安全的方式在 key
或 array[0]
等数组元素上调用 compareTo
。
然而,我们到这里还没有完成,因为 Comparable
本身就是一个泛型类型:Comparable<T>
,其中类型参数 T
控制 [= 的参数类型20=]。因此,我们需要在使用 Comparable<T>
时实例化 T
。
实例化Comparable<T>
在Comparable
中实例化T
之前,我们的表达式是<U extends Comparable<T>>
。我们需要将 T
替换为所需的类型。 compareTo
的参数类型应该是什么?如果我们将 String
的数组传递给 find
,我们将比较 Strings
,等等。在一般情况下,我们将 U
的数组传递给 [=41] =],所以我们想比较类型 U
的对象。所以在这种情况下我们在Comparable<T>
中用另一个泛型实例化T
,U
:<U extends Comparable<U>>
,这与<T extends Comparable<T>>
首先,您有 Comparable
界面,大致如下所示:
public interface Comparable<T> {
int compareTo(T other);
}
可以看到,Comparable
的类型参数作为compareTo
方法的参数。通常,T
的类型参数与实现 Comparable
接口的 class 相同。这种通用设置有助于将相同类型的实例相互比较。这是一个例子:
public class Name implements Comparable<Name> {
@Override
public int compareTo(Name other) {
// compute & return result
}
}
现在假设您有一个方法应该return 两个对象的最大值按照它们的自然顺序。这样的方法可能如下所示:
public static <U extends Comparable<U>> U max(U left, U right) {
return left.compareTo(right) >= 0 ? left : right;
}
注意: 使用 U
作为类型变量而不是 T
以表明它与 [=18= 分开]用于Comparable
界面。
以上是通用方法。类型变量 U
的上限为 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
作为 return 类型还允许将结果分配给与参数类型相同的变量。
请注意,为了获得最大的灵活性,max
方法实际上应该这样声明:
public static <U extends Comparable<? super U>> U max(U left, U right) {
return left.compareTo(right) >= 0 ? left : right;
}
不同之处在于使用 Comparable<? super U>
而不是 Comparable<U>
作为上限。这两个问答应该有助于解释为什么使用 ? super U
提供更大的灵活性:
- What is PECS (Producer Extends Consumer Super)?
- Explanation of generic
<T extends Comparable<? super T>>
in collection.sort/ comparable code?