1

visualization of the queue

Above is a diagram from the assignment page

For a homework assignment I have to implement a circular queue using arrays. I have all conditions working except for the case in which the strings "I", "J", "K", "L" are to be appended. As a result of this action, some of the new values in the array are supposed to loop back around to the beginning. However, I get the ArrayIndexOutOfBoundsException when appending the 2nd letter.

The debugger further traces the issue to the toString method, but I can't understand what the problem is.

Any advice?

public class CircularArrayQueueApp {
    public static void main(String[] args) {

        CircularArrayQueue queue = new CircularArrayQueue(10);

        String[] data1 = {"A", "B", "C", "D", "E", "F", "G", "H"};
        String[] data2 = {"I", "J", "K", "L"};

        for (String aData1 : data1) queue.enqueue(aData1);

        System.out.println(queue.first());
        System.out.println(queue);

        for (int i = 0; i < 4; i++) {
            int index = queue.getRead();
            System.out.println("\"" + queue.dequeue() + "\" has been dequeued at index " + index);
        }

        System.out.println(queue.first());
        System.out.println(queue);

        for (int i = 0; i < 4; i++) {
            queue.enqueue(data2[i]);
        }

        System.out.println(queue.first());
        System.out.println(queue);    

    }

    static class CircularArrayQueue {
        private final int length;
        private int read;
        private int write;
        private final Object[] data;

        public CircularArrayQueue(int size) {
            data = new Object[size];
            length = data.length;
            read = 0;
            write = 0;
        }

        Object read() {
            Object o;
            o = data[read];
            read = (read + 1) % length;

            return o;
        }

        Object first() {
            if (isEmpty()) {
                System.out.println("**Empty queue**");
                return null;
            }
            return data[read];
        }

        void write(Object o) {
            data[write] = o;
            write = (write + 1) % length;
        }

        boolean enqueue(Object o) {
            if (isFull()) {
                System.out.println("**Full queue**");
                return false;
            }
            write(o);
            return true;
        }

        public Object[] getData() {
            return data;
        }

        Object dequeue() {
            if (isEmpty()) {
                System.out.println("**Empty queue**");
                return null;
            }
            return read();
        }

        boolean isFull() {
            return read == (write + 1) % length;
        }

        boolean isEmpty() {
            return read == length;
        }

        public String toString() {
            String output = "[";

            for (int i = read; ((i) % length) != write; i++)
                output += data[i] + " ";

            return output.substring(0, output.length() - 1) + "]";
        }

        public int getRead() {
            return read;
        }

        public int getSize() {
            return length;
        }

        public int getWrite() {
            return write;
        }
    }
}
4
  • 3
    You should probably use data[i % length] and not data[i] in your toString() method. Commented Sep 7, 2016 at 17:44
  • Thanks for the help. My reply to flkes's answer applies the same way to yours, in that the elements don't wrap around as they should. You did solve the exception issue though. thanks for that! Commented Sep 7, 2016 at 18:12
  • Your code produces [E F G H I J K L] at the end (after the fix in toStrig()). Seems correct to me. While the physical location of K and L is in the beginning of the backing array, their logical position is at the end of the queue. Commented Sep 7, 2016 at 18:24
  • I see what you're saying. I think this is the right way to go; thanks again for your help! Commented Sep 7, 2016 at 21:49

1 Answer 1

1

You aren't modding the value of you're array lookup. Also try using a string joiner to simplify things

StringJoiner sj = new StringJoiner(" ", "[", "]");
for (int i = read; i % length != write; i++) {
    sj.add(data[i % length].toString());
}
return sj.toString();

or alternatively do the mod at the same time as you increment

for (int i = read; i != write; i = (i + 1) % length) {
    sj.add(data[i].toString());
}
Sign up to request clarification or add additional context in comments.

1 Comment

Thank you for replying, This does avoid the exception, but now the new values are all added to the end of the queue, instead of the last two strings being wrapped around to the beginning. I'll update my post with a picture to provide some clarification.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.