简体   繁体   中英

Java Generics - Comparable interface

In the code below Comparable interface is used to ensure x and y should be of same reference type but as V is extending T so V should be of the same type as T or subclass of T then what is the point of using Comparable interface. Also if I am not using Comparable interface then the last call to isIf method is getting compile despite x and y are of different types. Can anyone explain the use Comparable interface regarding this program?

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");
        */
    }
}

The current use of generics doesn't really makes sense, because no method from Comparable is ever used, which means that you could simply remove the extends declaration.

Also the Type V is also not used, as you can simply replace it by T and not break your logic. so the final result would look like this:

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
}

But now that we have the Stream API in java-8 you can use the following snippet to achieve the same thing:

static <T> boolean isIn(T x, T[] y) {
    return Arrays.stream(y).anyMatch(i -> i.equals(x));
}

The comparable here in your scenario is optional.

T extends Comparable<T>

What this means is that whatever value you are passing should implement the interface comparable. which basically means that the type parameter can be compared with other instances of the same type.

Now you might be wondering that since you are passing primitive data types, then how does the code not throw an error? The reason for this is that the primitives are autoboxed to wrapper objects which implement Comparable. So your ints become Integer and String is already an object both of which implement Comparable.

PS : your code will also work for objects provided that the class implements comparable

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM