0

I am trying to declare and assign an array while using generics and I'm having a little bit of trouble with this. I noticed that it was impossible to assign an array normally using generics. I found this work around, but it doesn't seem to work for me. It outputs a NullPointerException once it gets to the Array.newInstance(c,capacity). I'm just expecting this code to declare the array. Any ideas why this won't function the way it's expected to?

public class MyHeap<T extends Comparable<T>> implements Heap<T> {
Class<T> type;
T[] heap;
int size;
int capacity;


MyHeap(int x){
    capacity = x;
    size = 0;
    arraySet(type, capacity);
}

private void arraySet(Class<T> c, int capacity){
    @SuppressWarnings("unchecked")
    final T[] heap = (T[]) Array.newInstance(c, capacity);
    this.heap = heap;
}

}

Deezer
  • 1
  • 1
  • Because `type` is `null`. You could use a `List`, then you don't need a reference to the component type. – Jorn Vernee Feb 25 '17 at 23:12
  • Oh! I didn't realize that. But how do I set that to anything. Unfortunately I has to be an array. I am doing this as part of a lab for my data structures and algorithms class and it requires this implementation to use an array – Deezer Feb 25 '17 at 23:22
  • 1
    Why not just use a `Comparable[]`? You already know it's component type: `Comparable`. – Jorn Vernee Feb 25 '17 at 23:42
  • For information on creating generic arrays, see: http://stackoverflow.com/questions/529085/how-to-create-a-generic-array-in-java?rq=1 – Jason C Feb 26 '17 at 00:24
  • I used that link to get this far...but I don't understand what Class is? How do I set a value to that? – Deezer Feb 26 '17 at 00:31
  • I've reopened this question and answered your fundamental issue from your comment, but I suggest editing your post to shift the focus to your real question, rather than asking about the NPE. – Jason C Feb 26 '17 at 00:45
  • I'd suggest use a `Comparable[]` like @John suggests, or even piggyback on `ArrayList` to implement a heap. – Kedar Mhaswade Feb 26 '17 at 01:28

1 Answers1

0

Addressing your root problem:

...but I don't understand what Class is? How do I set a value to that?

Your options are:

  1. Pass it as a parameter to your constructor:

    MyHeap (int x, Class<T> type) { this.type = type; ... }
    
    // Usage
    new MyHeap(64, Integer.class);
    
  2. Pass something of that type to the constructor (not appropriate for your case) and use its type information:

    MyHeap (int x, T obj) { this.type = obj.getClass(); ... }
    
    // Usage
    new MyHeap(64, new Integer());
    

    List#toArray(T[]) uses this pattern for this purpose.

  3. Just store an Object array internally (Object[] heap), then you don't have to have the type available when you create the array. ArrayList is implemented this way, and as long as you use T in your function parameter lists, the compiler will verify that everything is cool. For T return types you'll have to cast the objects to a T before returning them (example) but as long as you have the invariant that every one of those Objects is a T, then it will always be a safe cast.

I'd go with option 3 as it leads to the simplest API.

Jason C
  • 38,729
  • 14
  • 126
  • 182