Java Generic Comparator

Viewed 2406
public class arr<T>
{
    class comp <T extends Comparable<T>> implements Comparator<T>
    {
        public int compare(T lObj,T rObj)
        {
              return lObj.compareTo(rObj);
        }
    }

    ArrayList<T> list;
    Comparator<T> comparator;
    public arr()
    {
        list = new ArrayList<T>();
        comparator = new comp();
    }
    public void add(T data)
    {
        list.add(data);         
    }
    public int getLength()
    {
        return list.size();
    }
    public T get(int index)
    {
        return list.get(index);
    }
    public void sort()
    {
        list.sort(comparator);
    }
}

Hello, I am trying to make the sort function work but have a problem. In the arr constructor, if I write

comparator = new comp<T>();

it gives me an error saying

"type argument T#1 is not within bounds of type-variable T#2 comparator = 
new comp<T>();                            ^
where T#1,T#2 are type-variables:
T#1 extends Object declared in class arr
T#2 extends Comparable<T#2> declared in class arr.comp"

And if I take out the type and write like this

comparator = new comp;

then it does work but gives me a warning that says

warning: [rawtypes] found raw type: arr.comp
comparator = new comp();

I can see what it means by raw types. I am not specifying the type, but somehow it works and if I try to fix the warning by specifying the type then, it throws an error. Could you please help me figure it out? I know... I am a noob my code must be a pain in your eyes. I am playing with generic comparators and trying many things to get familiar. Thank you.

1 Answers

Your code is confusing you, because the T defined by comp is hiding the T defined by arr. For the explanation below, I'll call them Tcomp and Tarr.

Tcomp is required to extend Comparable, but Tarr isn't required to do so, which means that Tarr cannot be "mapped" to Tcomp.

To fix, change Tarr so it is also required to extend Comparable:

public class arr<T extends Comparable<T>>

On a side note:
You comp class is an inner class, but it doesn't use anything from the outer class, so it should be a static nested class:

static class comp<T extends Comparable<T>> implements Comparator<T>

Alternatively, leave comp as an inner class, and let it reuse the T from the outer class:

class arr<T extends Comparable<T>>
{
    class comp implements Comparator<T>

But, since Java (8 or higher) comes with an implementation of Comparator for comparing Comparable objects, you should use it:

public class arr<T extends Comparable<T>>
{
    ArrayList<T> list;
    Comparator<T> comparator;
    public arr()
    {
        list = new ArrayList<T>();
        comparator = Comparator.naturalOrder();
    }
    // rest of code
}
Related