简体   繁体   中英

Issue with creating Immutable Queue

I am using the following code to make an immutable queue.

import java.util.NoSuchElementException;
import java.util.Queue;

public class ImmutableQueue<E> {

    //Two stacks are used. One is to add items to the queue(enqueue) and 
    //other is to remove them(dequeue)


    private ImmutableQueue(ReversableStack<E> order, ReversableStack<E> reverse) {
        this.order = order;
        this.reverse = reverse;
    }

    //initially both stacks are empty
    public ImmutableQueue() {
        this.order = ReversableStack.emptyStack();
        this.reverse = ReversableStack.emptyStack();
    }

    public ImmutableQueue<E> enqueue(E e) {
        if (null == e)
            throw new IllegalArgumentException();
        return new ImmutableQueue<E>(this.order.push(e), this.reverse);
    }

    public ImmutableQueue<E> dequeue() {
        if (this.isEmpty())
            throw new NoSuchElementException();
        if (!this.reverse.isEmpty()) {
            return new ImmutableQueue<E>(this.order, this.reverse.tail);
        } else {

            return new ImmutableQueue<E>(ReversableStack.emptyStack(),
                    this.order.getReverseStack().tail);
        }
    }




    private static class ReversableStack<E> {
        private E head; //top of original stack
        private ReversableStack<E> tail; //top of reversed stack
        private int size;

        //initializing stack parameters
        private ReversableStack(E obj, ReversableStack<E> tail) {
            this.head = obj;
            this.tail = tail;
            this.size = tail.size + 1;
        }

        //returns a new empty stack
        public static ReversableStack emptyStack() {
            return new ReversableStack();
        }

        private ReversableStack() {
            this.head = null;
            this.tail = null;
            this.size = 0;
        }

        //Reverses the original stack
        public ReversableStack<E> getReverseStack() {
            ReversableStack<E> stack = new ReversableStack<E>();
            ReversableStack<E> tail = this;
            while (!tail.isEmpty()) {
                stack = stack.push(tail.head);
                tail = tail.tail;
            }
            return stack;
        }

        public boolean isEmpty() {
            return this.size == 0;
        }

        public ReversableStack<E> push(E obj) {
            return new ReversableStack<E>(obj, this);
        }
    }

    private ReversableStack<E> order;

    private ReversableStack<E> reverse;



    private void normaliseQueue() {
        this.reverse = this.order.getReverseStack();
        this.order = ReversableStack.emptyStack();
    }

    public E peek() {
        if (this.isEmpty())
            throw new NoSuchElementException();
        if (this.reverse.isEmpty())
            normaliseQueue();
        return this.reverse.head;
    }

    public boolean isEmpty() {
        return size() == 0;
    }

    //returns the number of items currently in the queue
    public int size() {
        return this.order.size + this.reverse.size;
    }

    public static void main(String[] args)
    {
        ImmutableQueue<Integer> newQueue = new ImmutableQueue<Integer>();
        newQueue.enqueue(5);
        newQueue.enqueue(10);
        newQueue.enqueue(15);
        int x = newQueue.size();
        //ImmutableQueue<Integer> x = newQueue.dequeue();
        System.out.println(x);

    }

}

But whenever I try to do a dequeue, I get a NoSuchElementException. Also, the newQueue.size function also returns 0. What am I doing wrong ? Thanks

You are missing the new ImmutableQueue reference..

since enqueue() method returns a new instance of ImmutableQueue

public ImmutableQueue<E> enqueue(E e) {
    if (null == e)
        throw new IllegalArgumentException();
    return new ImmutableQueue<E>(this.order.push(e), this.reverse);
}

But on your main method you are discarding that object

public static void main(String[] args)
{
    ImmutableQueue<Integer> newQueue = new ImmutableQueue<Integer>();
    newQueue.enqueue(5);
    newQueue.enqueue(10);
    newQueue.enqueue(15);
    int x = newQueue.size();
    //ImmutableQueue<Integer> x = newQueue.dequeue();
    System.out.println(x);

}

change your call to:

newQueue = newQueue.enqueue(5);
int x = newQueue.size();
System.out.println(x);

and you will see the size will change

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM