Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Implementing Comparable with a generic class

Tags:

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 to T. 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?

like image 814
frank.liu Avatar asked Feb 04 '14 05:02

frank.liu


2 Answers

Item (without any type argument) is a raw type, so:

  1. We could pass any kind of Item to Item.compareTo. For example, this would compile:

    new Item<String>().compareTo(new Item<Integer>()) 
  2. The method o.getT() returns Comparable instead of T, which causes the compilation error.

    In the example under the 1st point, after passing Item<Integer> to Item.compareTo, we would then erroneously pass an Integer to String.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());     } } 
like image 98
Radiodef Avatar answered Sep 20 '22 18:09

Radiodef


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()); } 
like image 41
Njol Avatar answered Sep 21 '22 18:09

Njol