Search code examples
javaqueuestructureimmutablelistimmutables-library

Adding an element to a Java immutable queue


I hope that someone can help me with my little problem. I defined my EmptyQueue and my NotEmptyQueue in this way, following my interface Immutable queue. The main problem it's that the method enQueue, that should add an element to myQueue is not working. Pls help me:

Interface:

public interface ImmutableQueue<E> extends Iterable<E> {
    boolean isEmpty();
    int size();
    ImmutableQueue<E> enQueue(E e);
    ImmutableQueue<E> deQueue();
    E getTop();
}

EmptyQueue:

import java.util.Iterator;
import java.util.NoSuchElementException;

public class EmptyQueue<E> implements ImmutableQueue <E>, Iterable <E> {

    @Override
    public boolean isEmpty() {
        return true;
    }

    @Override
    public int size() {
        return 0;
    }

    @Override
    public ImmutableQueue<E> enQueue(E e) {
        NotEmptyQueue<E> q= new NotEmptyQueue <>(e,this);
        return q;
    }

    @Override
    public ImmutableQueue<E> deQueue() {
        throw new NoSuchElementException();
    }

    @Override
    public E getTop() {
        throw new NoSuchElementException();
    }

    @Override
    public Iterator<E> iterator() {
        return new Iterator<E>(){

            @Override
            public boolean hasNext() {
                return false;
            }

            @Override
            public E next() {
                throw new NoSuchElementException();
            }

        };
    }
}

NotEmptyQueue:

import java.util.Iterator;

public class NotEmptyQueue<E> implements ImmutableQueue<E>, Iterable <E>{

    public E e;
    public ImmutableQueue<E> tail;

    public NotEmptyQueue(E e, ImmutableQueue<E> tail){
        this.e = e;
        this.tail = tail;
    }


    @Override
    public boolean isEmpty() {
        return false;
    }

    @Override
    public int size() {
        return tail.size() + 1;
    }

    @Override
    public ImmutableQueue<E> enQueue(E e) {
        return new NotEmptyQueue<>(e,this);
    }

    @Override
    public ImmutableQueue<E> deQueue() {
        return tail;
    }
    @Override
    public E getTop(){
        return e;
    }

    public static void main (String [] args){
        NotEmptyQueue<Integer> myQueue= new NotEmptyQueue<>(new Integer(1),null);
        myQueue.enQueue(9);
        myQueue.enQueue(7);
        System.out.println(myQueue.size());
        System.out.println(myQueue.getTop());
        for(Integer i : myQueue){
            System.out.println(i);
        }

    }



    @Override
    public Iterator<E> iterator() {
        return new Iterator<E>(){
            ImmutableQueue<E> queue;
            @Override
            public boolean hasNext() {
                return (!tail.isEmpty());
            }

            @Override
            public E next() {
                E res = queue.getTop();
                queue = queue.deQueue();
                return res;
            }

            Iterator<E> setQueue(ImmutableQueue<E> queue){
                this.queue = queue;
                return this;
            }

        }.setQueue(this);
    }

}

Solution

  • myQueue.enQueue(9);
    

    should be

    myQueue = myQueue.enQueue(9);
    

    That's the usual way to deal with a persistent queue like you have.