/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package calculator;

/**
 *
 * @author 15096134
 */
public class Queue<X> implements Cloneable {

    protected Object[] queue;
    protected int first;
    protected int last;
    protected int elementCount;

    public Queue(int maximumSize) throws Exception {
       
        if (maximumSize <= 0) {
            throw new Exception("Invalid size set for queue");
        }
        this.queue = new Object [maximumSize];
        this.first = 0;
        this.last = -1;
        // Esse elementCount deveria começar com 0, dado que isso seria um contador para saber-mos
        // qtos elementos tem na fila.
        //
        // Note que se precisar saber o valor do maximumSize, você deverá usar `this.queue.length`
        this.elementCount = maximumSize;
    }

    public Queue(Queue s) throws Exception {
       
         queue = new Object[s.queue.length];
         this.first = s.first;
         this.last = s.last;
         this.elementCount = s.elementCount;
         // Você tem que fazer na verdade:
         // this.queue = queue
         this.queue = s.queue;
         // e não `s.queue`
         
         // Depois clonar os elementos de `s.queue` para `this.queue`
         // this.queue[0] = s.queue[0].clone()
         // Note que aquilo acima não funciona. Vamos seguir a instrução do Maligno por hora: use o reflect.
    }

    public void enqueue(X elm) throws Exception {
       
        if (elementCount >= queue.length) {
            throw new Exception("Queue is full");
        }
        // last >= queue.length - 1
        if(last == queue.length - 1)
            last = -1;
        this.last++;
        this.elementCount++;
        this.queue[last] = elm;
    }

    public X dequeue() throws Exception {
        X dequeued; 
        // Faça a verificação de fila vazia antes de pegar o objeto do vetor
          dequeued = (X) this.queue[this.first];
          
        // Esse if tem que ir pra cima ^
        if (this.elementCount <= 0) 
            throw new Exception("Queue is empty");
            
        // Isso TEM que ficar depois do this.first++
        if (this.first == queue.length)
            first = 0;
        
        this.first++;
        this.elementCount--;
        return dequeued;
    }

    @Override
    // \o/ Esse está ok!
    public Object clone() throws CloneNotSupportedException {
        Queue clonned = null;

        try {

            clonned = new Queue(this);
        } catch (Exception CloneNotSupportedException) {
        }

        return clonned;
    }

    @Override
    public boolean equals(Object other) {

        if (this == other) {
            return true;
        }

        if (other == null) {
            return false;
        }

        if (other instanceof Queue) {
            return true;
        }

        Queue que = (Queue) other;
        
        if (this.first != que.first){
            return false;
        }
        
        if (this.last != que.last) {
            return false;
        }
        
        // Checar se a capacidade das filas é igual!
        // this.queue.length != que.queue.length
        
        // Checar se o total de elementos é igual.
        // this.elementCount != que.elementCount
        // 
        
        // isso é apenas valido se this.first < this.last
        for (int i = this.first; i <= this.last; i++) {
            if (!this.queue[i].equals(que.queue[i])) {
                return false;
            }
        }
        // se auilo não for verdade....
        //
        // Checar do primeiro ao fim array
        // for (int i = this.first; i < this.queue.length; i++) {
        //    if (!this.queue[i].equals(que.queue[i])) {
        //        return false;
        //    }
        // }
        //
        // Chear do começo até o ultimo
        // for (int i = 0; i <= this.last; i++) {
        //    if (!this.queue[i].equals(que.queue[i])) {
        //        return false;
        //    }
        // }
        return true;
    }

    @Override
    public int hashCode() {
        // comece isso com super.hashCode()
        int hash = 3;
        
        
        return hash;
    }

    @Override
    public String toString() {

        String str = "Queue = {";
        for (int i = this.first; i < this.last; i++) {
            str += this.queue[i] + " , ";
        }
        if (this.last > - 1) {
            str += this.queue[this.last];
        }
        str += "}";
        return str;
    }
}

@@ -4429,34 +4429,618 @@
       %0D%0A        
+// Para cada atributo que voc%C3%AA checou no equals, multiplique o hash e adicione o hash do atributo.%0D%0A        // hash += hash * 3 + this.queue.length;%0D%0A        // hash += hash * 3 + this.elementCount;%0D%0A        // hash += hash * 3 + this.first;%0D%0A        // hash += hash * 3 + this.last;%0D%0A        // %0D%0A        // Lembrando que isso %C3%A9 apenas valido se this.first %3C this.last%0D%0A        // for (int i = this.first; i %3C= this.last; i++) %7B%0D%0A        //    hash += hash * 3 + this.queue%5Bi%5D.hashCode();%0D%0A        // %7D%0D%0A        //%0D%0A        // se auilo n%C3%A3o for verdade fazer o mesmo esquema do equals
 %0D%0A
-
         return h
@@ -5134,24 +5134,90 @@
 ueue = %7B%22;%0D%0A
+        // Fa%C3%A7a o mesmo algoritmo de for do equals e do hashCode%0D%0A
         for 
@@ -5299,24 +5299,24 @@
 %5D + %22 , %22;%0D%0A
-
         %7D%0D%0A 
@@ -5306,32 +5306,67 @@
  %22;%0D%0A        %7D%0D%0A
+        %0D%0A        // hu3r@g3m T0P%0D%0A
         if (this

Update Queue.java