Search code examples
javacomparatorpriority-queuecompareto

Overriden compareTo() not recognised in priority queue


Ive implemented compareTo() in a Disk class and even though it works fine when i use it in main, it gives me the following error when i try to compile the priority queue which is using the same method:

MaxPQ.java:113: error: bad operand types for binary operator '>=' if ((Disk)heap[i].compareTo((Disk)heap[max]) >= 0)

Any idea why?

Here's the code:


public class Disk implements Comparable <Disk>{

    public static int count = 0;
    public int id;
    //public Node folders;
    public int freeSpace;

    public Disk(){
        count++;
        id = count;
    }

    public int getFreeSpace(){
        return freeSpace;
    }

    @Override
    public int compareTo(Disk d){
         return Integer.compare(this.getFreeSpace(), d.getFreeSpace());
    }


}

And:

public class MaxPQ<Disk> {


    private Disk[] heap; // the heap to store data in
    private int size; // current size of the queue
    //private Comparator comparator; // the comparator to use between the objects

    private static final int DEFAULT_CAPACITY = 4; // default capacity
    private static final int AUTOGROW_SIZE = 4; // default auto grow


    //public MaxPQ(Comparator comparator) {
    public MaxPQ() {
        this.heap = (Disk[])new Object[DEFAULT_CAPACITY + 1];
        this.size = 0;
        //this.comparator = comparator;
    }

    private void sink(int i) {
        // determine left, right child
        int left = 2 * i;
        int right = left + 1;

        // if 2*i > size, node i is a leaf return
        if (left > size)
            return;

        // while haven't reached the leafs
        while (left <= size) {
            // Determine the largest child of node i
            int max = left;
            if (right <= size) {
                if (heap[left].compareTo(heap[right]) < 0)
                    max = right;
            }

            // If the heap condition holds, stop. Else swap and go on.
            // child smaller than parent
            if ((Disk)heap[i].compareTo((Disk)heap[max]) >= 0)
                return;
            else {
                swap(i, max);
                i = max;
                left = i * 2;
                right = left + 1;
            }
        }
    }

Solution

  • The problem is that you're using Disk as a generic type parameter, then trying to use it like a class.

    It doesn't look like MapPQ should be a generic class. It uses Disk specifically. So I'd:

    1. Change the declaration so it's not generic;
    2. Use new Disk[DEFAULT_CAPACITY + 1] to create heap;
    3. and remove all of those casts

    If you did want Disk to be generic (convention is to use a single letter, not a word; I'll use T which is overwhelmingly the letter used for the first generic type argument), when instantiating MapPQ you'd have to have the caller pass in the Class instance it should use for the array. See this question's answers for how you do that, but roughly:

    public MapPQ(Class<T> cls) {
        ths.heap = (T[])Array.newInstance(cls, DEFAULT_CAPACITY + 1);
    }
    

    (Or declare heap as Object[] and keep all your casts, but it's error-prone.)