Soluzione 8.4

Abbiamo scritto la classe StackByQueue e la corrispondente classe di collaudo in un unico file.
Per quanto riguarda la realizzazione della classe StackByQueue Per quanto riguarda l'analisi delle prestazioni dei metodi di StackByQueue Per quanto riguarda la classe StackByQueueTester, la difficolta` principale sta nello scrivere il metodo compareStacks; la soluzione proposta realizza il seguente algoritmo:
public class StackByQueueTester
{   public static void main(String[] args)
    {   //creo due pile (gli oggetti appartengono a classi diverse,
        //ma i riferimenti s1 ed s2 sono entrambi di tipo Stack) 
        Stack s1 = new ArrayStack();
        Stack s2 = new StackByQueue();
        //operazioni sulla prima pila
        s1.push(new Integer(2));
        s1.push("pippo");
        s1.top();
        s1.pop();
        s1.push("pluto");
        s1.top();
        //operazioni (identiche) sulla seconda pila
        s2.push(new Integer(2));
        s2.push("pippo");
        s2.top();
        s2.pop();
        s2.push("pluto");
        s2.top();
        
        if (compareStacks(s1, s2)) System.out.println("Collaudo riuscito");
        else                       System.out.println("Collaudo non riuscito");
    }

    //metodo statico ausiliario: confronta il contenuto delle pile s1 ed s2
    public static boolean compareStacks(Stack s1, Stack s2)
    {   Stack temp1 = new ArrayStack();
        Stack temp2 = new ArrayStack();
        boolean areEquals = true;
        while (!s1.isEmpty() && !s2.isEmpty() && areEquals)
        {   Object obj1 = s1.pop();
	        temp1.push(obj1);
	        Object obj2 = s2.pop();
	        temp2.push(obj2);
            // controllo che obj1 e obj2 siano o entrambi null o riferimenti 
            // ad oggetti uguali
            areEquals = (obj1 == null && obj2 == null) || 
                        (obj1 != null && obj1.equals(obj2) );
        }
        if (!s1.isEmpty() || !s2.isEmpty()) //le due pile non contengono
            areEquals = false;              // lo stesso numero di elementi

        while (!temp1.isEmpty())  // ri-travasiamo i contenuti di temp1 e temp2
            s1.push(temp1.pop());   // nelle due pile iniziali
        while (!temp2.isEmpty())
            s2.push(temp2.pop());

        return areEquals;
    }
}

//la classe StackByQueue: usa code per realizzare una pila
class StackByQueue implements Stack
{  
    public StackByQueue()
    {   q = new ArrayQueue();
    }
  
    public void makeEmpty()
    {   q.makeEmpty();
    }
  
    public boolean isEmpty()
    {   return q.isEmpty();
    }
  
    public void push(Object obj)
    {   Queue temp = new ArrayQueue();
        while (!q.isEmpty())
            temp.enqueue(q.dequeue());  // svuotiamo temporaneamente la coda
        q.enqueue(obj);                 // inseriamo il nuovo oggetto
        while (!temp.isEmpty())         // riaccodiamo gli elementi
            q.enqueue(temp.dequeue());  // il nuovo oggetto e' all'inizio della 
    }                                   // coda, ovvero in cima alla pila
  
    public Object top()
    {   try
        {	return q.getFront(); }
        catch (EmptyQueueException e)            // se la coda e' vuota...
        { throw new EmptyStackException(); }   // ... allora la pila e' vuota
    }
   
    public Object pop()
    {   try
        {	return q.dequeue(); }
        catch (EmptyQueueException e)            // se la coda e' vuota...
        {	throw new EmptyStackException(); }   // ... allora la pila e' vuota
    }

    private Queue q;
}