سؤال

I am struggling with creating generic data types that require that its element to be comparable.

I have attempted to construct what I think is the most basic implementation of this, and it still is not working.

public class GenericPair<T> {
    T thing1;
    T thing2;

    public GenericPair(T thing1, T thing2){
        this.thing1 = thing1;
        this.thing2 = thing2;
    }   


    public <T extends Comparable<T>> int isSorted(){ 
        return thing1.compareTo(thing2);
    }   

    public static void main(String[] args){
        GenericPair<Integer> onetwo = new GenericPair<Integer>(1, 2); 
        System.out.println(onetwo.isSorted());
    }   
}

My understanding is that > requires that whatever type T ends up, it must implement comparable and therefore must have a compareTo() function. In this case Integers should have this functionality right?

I am getting the error:

GenericPair.java:15: error: cannot find symbol
    return thing1.compareTo(thing2);
                 ^
    symbol:   method compareTo(T)
    location: variable thing1 of type T
    where T is a type-variable:
    T extends Object declared in class GenericPair

What is going on here?

هل كانت مفيدة؟

المحلول

public <T extends Comparable<T>> int isSorted(){ 
    return thing1.compareTo(thing2);
}  

This new T is hiding the type parameter of your class (also called T). They are two different types! And thing1 and thing2 are instances of your class's generic type, which aren't necessarily comparable.

So, you should declare your class's type parameter to be comparable instead:

class GenericPair<T extends Comparable<T>>

And now:

public int isSorted(){ 
    return thing1.compareTo(thing2);  // thing1 and thing2 are comparable now
}   

نصائح أخرى

The problem is that generic T for the whole class doesn't know a compareTo method. Even if you declare <T extends Comparable<T>> for this single method, you're just creating a new T that hides the definition of the generic T from the class.

A solution may be declaring T extends Comparable<T> in the class itself:

class GenericPair<T extends Comparable<T>> {
    public int isSorted() {
        return thing1.compareTo(thing2);
    }
}
public <T extends Comparable<T>> int isSorted(){ 
    return thing1.compareTo(thing2);
}

You can't have a method that imposes new constraints on the generic type parameter defined by the class. You would have to declare

public class GenericPair<T extends Comparable<T>> {
   public int isSorted() {
     return thing1.compareTo(thing2);
   }
}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top