-1

I am attempting to create a Priority Queue of tasks in Java, but I have run into a class casting exception in the constructor of the Priority Queue. Here is my task class:

public class Task <E,T extends Integer>
{
    private E job;
    private T priority;

    public Task(E job, T priority)
    {
        this.job = job;
        this.priority = priority;
    }

    public String toString()
    {
        return "Job Name: "+ job + " Priority: "+priority;
    }
}

The error gets thrown on the second line of the Priority Queue's constructor:

public class PriorityQueueCustom <E,T extends Integer>
{
    private Task<E,T>[] heap;
    private int heapSize,capacity;

public PriorityQueueCustom(int capacity)
{
    this.capacity = capacity + 1;                                               
    heap = (Task<E,T>[]) new Object[capacity];
    heapSize = 0;
}

What I don't understand is why I can't cast the Object to a Task since task should extend Object automatically, but I am new to generics so I am not sure if I have set them up correctly?

This is how I created the Priority Queue:

PriorityQueueCustom<String,Integer> queue = new PriorityQueueCustom<String,Integer>(10);

And here is the exception generated:

Exception in thread "main" java.lang.ClassCastException: [Ljava.lang.Object; cannot be cast to [LPriorityQueueCustom$Task;
at PriorityQueueCustom.<init>(PriorityQueueCustom.java:28)
at PriorityQueueTester.main(PriorityQueueTester.java:5) 
  • 4
    You are casting an array of `Object` to an array of `Task`. This can't be done since `Object[]` is not an instance of `Task[]`. Why not create an array of `Task` in the first place? – johnnyaug Aug 14 '16 at 16:47
  • Can you share the exception you're getting? – Mureinik Aug 14 '16 at 16:47
  • 2
    see also http://stackoverflow.com/questions/529085/how-to-create-a-generic-array-in-java –  Aug 14 '16 at 16:52

1 Answers1

2

Object[] does not extend Task[]. I.e. Array of any objects is not an array of tasks (only the opposite is true).

You have to create Task array:

Task<E,T>[] a = new Task[capacity];

Or, to avoid unchecked cast, a list of Tasks:

List<Task<E,T>> tasks = new ArrayList<>(); 
Piotr Praszmo
  • 16,785
  • 1
  • 51
  • 60
  • 1
    Yes, use a List, or even better a LinkedList from which you can take the tail element in O(1) time. Generics and arrays don't play nice together. – Bohemian Aug 14 '16 at 18:54
  • @Bohemian ArrayList beats LinkedList in almost every case. Even things which theoretically should be faster in practice aren't. ArrayList and ArrayDeque should be the default. In this particular case heap implementation will require random access so ArrayList is a clear choice. – Piotr Praszmo Aug 14 '16 at 19:26