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

,您的代码也适用于对象