views:

278

answers:

3

How do you go about comparing two generic classes?

class Entry<K,V>
{
 protected K key;
 protected V value;

 public K getKey() { return key; }
 public V getValue() { return value; }

 public static Comparator KeyComparator = new Comparator()
 {
  public int compare(Object o1, Object o2)
  {
   int key1 = ( (Entry) o1 ).getKey();
   int key2 = ( (Entry) o2 ).getKey();

   if (key1 > key2)
   {
    return 1;
   }
   else if (key1 < key2)
   {
    return -1;
   }
   else
   {
    return 0;
   }
  }
 };
}

I get the following compile error:

int key1 = ( (Entry) o1 ).getKey();
                                ^
int key2 = ( (Entry) o2 ).getKey();
                                ^
incompatible types
found   : java.lang.Object
required: int

K and V will be Integers used within a circular arraylist implementation. Is there a simpler way (or at least one that works) to compare like I normally would with int?

+1  A: 

Your key in Entry class is not of type int but of type K. And because you do not parametrize the Comparator, it defaults to Object.

If your sure to use Integer for K and V, then you don't need generics in this case. Use a Comparator<Integer> in that case.

Hint: and in this case you can rely on the inherited Integer#compareTo(Integer i) method because Integers are comparable (other then java primitives like int)

Andreas_D
+1  A: 

You need to define your comparator generically as well:

public static <T extends Comparable<? super T>> Comparator<T> naturalOrder()
{
  return new Comparator<T> {
    public int compare(T o1, T o2) { return o1.compareTo(o2); }
  }
}
Visage
A: 

Change your comparator code to:

public static Comparator<Entry<Integer,?>> KeyComparator = new Comparator<Entry<Integer,?>>()
  {
     public int compare(Entry<Integer,?> o1, Entry<Integer,?> o2)
       {
         Integer key1 = o1.getKey();
         Integer key2 = o2.getKey();
         return key1.compareTo(key2);
       }
  }

This will have the side effect of enforcing the generics, and ensuring you don't use it against Entries that are not keyed with an Integer.

However, you may find that you should just make getKey() return Integer without generics. Keep <K> though...

Stephen