Implementing Comparable with a generic class
Solution 1
Item
(without any type argument) is a raw type, so:
-
We could pass any kind of
Item
toItem.compareTo
. For example, this would compile:new Item<String>().compareTo(new Item<Integer>())
-
The method
o.getT()
returnsComparable
instead ofT
, which causes the compilation error.In the example under the 1st point, after passing
Item<Integer>
toItem.compareTo
, we would then erroneously pass anInteger
toString.compareTo
. The compilation error prevents us from writing the code which does that.
I think you just need to remove the raw types:
public class Item<T extends Comparable<T>>
implements Comparable<Item<T>> {
...
@Override
public int compareTo(Item<T> o) {
return getT().compareTo(o.getT());
}
}
Solution 2
You're using raw types in your class definition (Item<T>
is generic, but you're omitting the type parameter <T>
), change it to:
class Item<T extends Comparable<T>> implements Comparable<Item<T>>
(Note the last <T>
)
The compareTo
method will then have to be changed as well:
public int compareTo(Item<T> o) { // again, use generics
return getT().compareTo(o.getT());
}
Solution 3
I think, this makes more sense. I have compiled and tested the following :
class Item<E extends Comparable<E>> implements Comparable<E> {
private int s;
private E t;
public E getE() {
return t;
}
@Override
public int compareTo(E e) {
return getE().compareTo(e);
}
public int compareTo(Item<E> other)
{
return getE().compareTo(other.getE());
}
}
Notice that you now need to have two compareTo methods.
Related videos on Youtube
frank.liu
Updated on November 06, 2021Comments
-
frank.liu over 2 years
I want to define a class that implements the generic Comparable interface. While in my class I also defined a generic type element
T
. In order to implement the interface, I delegate the comparison toT
. Here is my code:public class Item<T extends Comparable<T>> implements Comparable<Item> { private int s; private T t; public T getT() { return t; } @Override public int compareTo(Item o) { return getT().compareTo(o.getT()); } }
When I try to compile it, I get the following error information:
Item.java:11: error: method compareTo in interface Comparable<T#2> cannot be applied to given types; return getT().compareTo(o.getT()); ^ required: T#1 found: Comparable reason: actual argument Comparable cannot be converted to T#1 by method invocation conversion where T#1,T#2 are type-variables: T#1 extends Comparable<T#1> declared in class Item T#2 extends Object declared in interface Comparable 1 error
Can anybody tell me why and how to fix it?
-
npinti about 10 yearsNot 100% sure, but should this:
compareTo(Item o)
becompareTo(Item<T> o)
? -
newacct about 10 yearsfor best results use
<T extends Comparable<? super T>>
-
-
Njol about 10 yearsThe asker wants items to be comparable (by comparing their values).
-
Njol about 10 yearsIt's possible if T implements Comparable, which is the case here.
-
aditya about 10 yearsYa, please have a look at the other solution that I have given now.
-
Njol about 10 yearsYour answer doesn't make much sense at all. "we are extending comparable and not implementing it." - one implements interfaces and extends classes.
extends
is used in generics for both cases though. "because we are using a generic type T, we must not override compareTo method" - generic types don't prevent us from implementing interfaces, e.g.ArrayList<T>
implementsList<T>
. "T can be anything [...] Specifically, it has to be something that is Comparable" - T already isComparable
, in both the OP's code and your code, in particular it is comparable to itself. -
aditya about 10 yearsPLease have a look at the current answer, have changed it completely.
-
Njol about 10 yearsThat's certainly better.