3

I'm implementing a set of data structures and decided to try an implementation of a maxheap through an array, since it is one of the common implementations for maxheaps. To do that, I have an interface called MaxHeap<T> which accepts Comparable types T and the following class signature:

 public class ArrayMaxHeap<T extends Comparable<T>> implements MaxHeap<T> {

T has to be Comparable, or else I won't be able to compare the elements with one another when doing additions and removals from the heap. The problem lies with the constructor of the class:

public class ArrayMaxHeap<T extends Comparable<T>> implements MaxHeap<T> {

    private T[] data;
    private int last;
    private static final int INIT_CAPACITY = 10;

    /**
     * Creates an empty ArrayMaxHeap with the default capacity.
     */
    public ArrayMaxHeap(){
        data = (T[])(new Object[INIT_CAPACITY]);
        last = 0;
    }

The type casting of data is throwing a ClassCastException, because the downcasting from Object, which is not Comparable, is unsafe. I've hit a wall with this and am not sure how I would go about implementing the constructor. Any help would be appreciated.

Jason
  • 1,568
  • 2
  • 18
  • 28
  • 1
    What happens with `data = (T[])(new Comparable[INIT_CAPACITY]);`? This compiles for me (with a warning), and I can call the constructor without a `ClassCastException`, but I don't know if this would cause problems later on. – ajb Oct 09 '13 at 21:08
  • I've written another class which calls the constructor for an ArrayMaxHeap as such: `private MaxHeap intHeap = new ArrayMaxHeap();` and I'm receiving the exception mentioned. I'm currently reading through the link Sotirios mentioned in order to understand what's going on. – Jason Oct 09 '13 at 21:11
  • @ajb That will also not work. If you create instance like `ArrayMaxHeap();`, that will fail at runtime. Casting `Comparable[]` to `String[]`. – Rohit Jain Oct 09 '13 at 21:13
  • 1
    @RohitJain I tried a test program with `ArrayMaxHeap x = new ArrayMaxHeap();`, and didn't get an exception. (But I didn't try doing anything else with the array.) – ajb Oct 09 '13 at 21:17
  • @ajb Try adding a getter for the array, and fetch it as - `String[] arr = x.getData();` – Rohit Jain Oct 09 '13 at 21:19
  • @RohitJain OK, I see it now. Thanks. – ajb Oct 09 '13 at 21:24
  • @RohitJain: But no well-designed data structure would ever expose an internal data variable to the outside. The OP's question does not indicate that his class will ever do that. – newacct Oct 10 '13 at 01:35

2 Answers2

2

This is kind of a limitation of generics. Instead just declare your array as Object[] and cast the element you try to return. Something similar to what ArrayList does.

public E get(int index) {
    rangeCheck(index);

    return elementData(index);
}

E elementData(int index) {
    return (E) elementData[index];
}

where elementData is

private transient Object[] elementData;

If you control what is going in, there's no problem.

I'm going to link the question and answer in Rohit's comment because it's brilliant.

Community
  • 1
  • 1
Sotirios Delimanolis
  • 252,278
  • 54
  • 635
  • 683
0

Just change it to

data = (T[])new Comparable[INIT_CAPACITY];
newacct
  • 110,405
  • 27
  • 152
  • 217