Java 泛型 - 可比较的接口
Java Generics - Comparable interface
在下面的代码中 Comparable
接口用于确保 x 和 y 应该是相同的引用类型但是因为 V 是扩展 T 所以 V 应该是与 T 或 T 的子类相同的类型那么什么是使用Comparable
接口的要点。
另外,如果我没有使用 Comparable
接口,那么尽管 x 和 y 的类型不同,但对 isIf
方法的最后一次调用正在编译。
谁能解释一下这个程序的使用 Comparable
界面?
public class Generics_13 {
static <T extends Comparable<T>, V extends T> boolean isIn(T x, V[] y) {
for(int i = 0;i < y.length;i++)
if(x.equals(y[i])) return true;
return false;
}
public static void main(String[] args) {
Integer nums[] = {10, 20, 30};
if(isIn(10, nums))
System.out.println("10 belongs to the array");
if(!isIn(60, nums))
System.out.println("70 doesnt belong to the array");
String arr[] = {"Neeraj", "Parth", "Ritum"};
if(!isIn("abc", arr))
System.out.println("abc doesnt belongs to the array");
/*if(isIn("String", nums)) // illegal
System.out.println("This wont compile");
*/
}
}
目前使用泛型没有任何意义,因为从未使用过 Comparable
中的任何方法,这意味着您可以简单地删除 extends
声明。
此外,类型 V
也未使用,因为您可以简单地将其替换为 T
而不会破坏您的逻辑。所以最终结果将如下所示:
public class Generics_13 {
static <T> boolean isIn(T x, T[] y) {
for(int i = 0;i < y.length;i++)
if(x.equals(y[i])) return true;
return false;
}
// main() etc follow here
}
但是现在我们在 java-8
中有了 Stream API
,您可以使用以下代码片段来实现相同的目的:
static <T> boolean isIn(T x, T[] y) {
return Arrays.stream(y).anyMatch(i -> i.equals(x));
}
您的场景中此处的可比项是可选的。
T extends Comparable<T>
这意味着您传递的任何值都应该实现可比较的接口。
这基本上意味着类型参数可以与相同类型的其他实例进行比较。
现在您可能想知道,既然您传递的是原始数据类型,那么代码如何不抛出错误呢?
这样做的原因是原语被自动装箱到实现 Comparable 的包装器对象。
所以你的整数变成 Integer 并且 String 已经是一个对象,它们都实现了 Comparable。
PS :只要 class 实现了 comparable
,您的代码也适用于对象
在下面的代码中 Comparable
接口用于确保 x 和 y 应该是相同的引用类型但是因为 V 是扩展 T 所以 V 应该是与 T 或 T 的子类相同的类型那么什么是使用Comparable
接口的要点。
另外,如果我没有使用 Comparable
接口,那么尽管 x 和 y 的类型不同,但对 isIf
方法的最后一次调用正在编译。
谁能解释一下这个程序的使用 Comparable
界面?
public class Generics_13 {
static <T extends Comparable<T>, V extends T> boolean isIn(T x, V[] y) {
for(int i = 0;i < y.length;i++)
if(x.equals(y[i])) return true;
return false;
}
public static void main(String[] args) {
Integer nums[] = {10, 20, 30};
if(isIn(10, nums))
System.out.println("10 belongs to the array");
if(!isIn(60, nums))
System.out.println("70 doesnt belong to the array");
String arr[] = {"Neeraj", "Parth", "Ritum"};
if(!isIn("abc", arr))
System.out.println("abc doesnt belongs to the array");
/*if(isIn("String", nums)) // illegal
System.out.println("This wont compile");
*/
}
}
目前使用泛型没有任何意义,因为从未使用过 Comparable
中的任何方法,这意味着您可以简单地删除 extends
声明。
此外,类型 V
也未使用,因为您可以简单地将其替换为 T
而不会破坏您的逻辑。所以最终结果将如下所示:
public class Generics_13 {
static <T> boolean isIn(T x, T[] y) {
for(int i = 0;i < y.length;i++)
if(x.equals(y[i])) return true;
return false;
}
// main() etc follow here
}
但是现在我们在 java-8
中有了 Stream API
,您可以使用以下代码片段来实现相同的目的:
static <T> boolean isIn(T x, T[] y) {
return Arrays.stream(y).anyMatch(i -> i.equals(x));
}
您的场景中此处的可比项是可选的。
T extends Comparable<T>
这意味着您传递的任何值都应该实现可比较的接口。 这基本上意味着类型参数可以与相同类型的其他实例进行比较。
现在您可能想知道,既然您传递的是原始数据类型,那么代码如何不抛出错误呢? 这样做的原因是原语被自动装箱到实现 Comparable 的包装器对象。 所以你的整数变成 Integer 并且 String 已经是一个对象,它们都实现了 Comparable。
PS :只要 class 实现了 comparable
,您的代码也适用于对象