I am having trouble understanding the nuances of generics, interfaces, and arrays and how to use them together. I have an assignment for an intermediate Java class. The assignment is as follows:

  • Create a generic class SimpleQueue that implements Queue
  • Use a constructor to initialize an array with 5 slots.
  • Use of ArrayList not allowed
  • We must be able to increase the size of the array if it gets filled

The problem I'm having is the with the initialization of the array. Here's the code I have:

import java.util.Collection;
import java.util.Iterator;
import java.util.Queue;

public class SimpleQueue<E> implements Queue<E>{

    private E myQueue[];

    //Constructor with no arguments.
    public SimpleQueue() {
        myQueue = new [5];
        System.out.println("A queue with length " + myQueue.length + " was created.");
    }
}

Eclipse complains by saying that we can't create a generic array. I've managed to get it to work by doing this:

private Object myQueue[] = Object[5];

...but I feel like this defeats the purpose of using generics. Am I misunderstanding the use of generics? Pointers would be greatly appreciated!

This is the code I'm using to test my generic class as I'm working:

public class SimpleQueueTester {

    public static void main(String [] args) {
        SimpleQueue<String> myStringQueue = new SimpleQueue<>();
        SimpleQueue<Integer> myIntegerQueue = new SimpleQueue<>();
    }
}

Disclaimer: Please don't think I want my homework done for me. I'm just stuck at this point and I figured this would be the best place to ask. Thanks!

Edit: I took some of your suggestions and now my code looks like this:

public class SimpleQueue<E> implements Queue<E>{

    private E[] myQueue;

    @SuppressWarnings("unchecked")
    //Constructor with no arguments.
    public SimpleQueue() {

        //This was changed. What does (E[]) do exactly?            
        this.myQueue = (E[]) new Object[5];
        System.out.println("A queue with length " + this.myQueue.length + " was created.");
    }
}

Thank you for you suggestions! You guys are awesome.

有帮助吗?

解决方案

You could create an Object array Object[] myQueue; and cast the contents of it to E whenever you need to fetch values.

Here's an example:

public class MyQueue<E> implements Queue<E> {
    private Object[] elements;
    private int startOfQueueIndex;
    private int numberOfElements;

    public MyQueue(int initialCapacity) {
        elements = new Object[initialCapacity);
        startOfQueueIndex = 0;
        numberOfElements = 0;
    }

    public boolean add(E e) {
        if (numberOfElements == elements.length)
            increaseElementArraySize();

        elements[(startOfQueueIndex + numberOfElements++) % elements.length] = e;
    }

    public E remove() {
        if (numberOfElements == 0)
            throw new NoSuchElementException();

        E element = (E)elements[startOfQueueIndex];

        startOfQueueIndex = (startOfQueueIndex + 1) % elements.length;

        return element;
    }

    // The rest of the methods go here ...
}

其他提示

For a learning reference you may want to check out how LinkedList impelements the Queue<E> interface: Here's a grepcode link to the openjdk implementation.

LinkedList doesn't have an underlying array, instead it uses Node objects. This allows for easy allocation of new objects as you add them to the list.

For a reference how to cope with underlying array (ensure enough space etc.), you may want to see ArrayList.

The code is well commented, I hope it helps you.

You can't create new E instance, or an array of E, because E is an unknown type at compile time. but you could create a list of E.

private java.util.List<E> myQueue;

is the right way.

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top