Java OCPJP7: differenza tra i metodi element(), peek(), poll() e remove() dell’interfaccia Queue

L’interfaccia Queue definisce alcuni metodi per agire sul primo elemento della lista, che differiscono tra loro per il modo in cui si comportano e per il risultato che forniscono. Ai fini dell’esame di certificazione OCPJP7 è importante conoscere il funzionamento di questi metodi e saper riconoscere con precisione come ciascuno di essi si comporta in alcune situazioni particolari.
I metodi in questione sono:

  • peek()
  • element()
  • poll()
  • remove()
  • Il metodo peek() recupera il valore del primo elemento della coda senza rimuoverlo da essa. Ad ogni invocazione del metodo ottengo sempre lo stesso valore e la sua esecuzione non influisce sulla dimensione della coda. Se la coda è vuota il metodo peek() ritorna null.
  • Il metodo element() si comporta come il metodo peek(), cioè recupera il valore del primo elemento senza rimuoverlo. A differenza di peek() però, se la lista è vuota il metodo element() scatena una NoSuchElementException
  • Il metodo poll() recupera il valore del primo elemento della coda rimuovendolo dalla coda stessa.. Ad ogni invocazione rimuove il primo elemento della lista e se la lista è già vuota ritorna null ma non scatena nessuna eccezione
  • Il metodo remove() si comporta come il metodo poll(), cioè rimuove il primo elemento della lista e nel caso la lista sia vuota scatena una NoSuchElementException

Vediamo alcuni esempi di questi metodi all’opera su una LinkedList che rappresenta una delle implementazioni di Queue.
Nel primo esempio aggiungiamo 3 elementi alla coda e poi invochiamo due volte il metodo peek():

import java.util.LinkedList;
import java.util.Queue;

public class QueueTest {

    public static void main(String[] args) {

        Queue<Integer> qi = new LinkedList<>();
        qi.add(50);
        qi.add(100);
        qi.add(25);

        Integer x = qi.peek();
        System.out.println(x);

        x = qi.peek();
        System.out.println(x);

        System.out.println(qi);
    }
}

Come possiamo vedere dal risultato seguente, peek restituisce sempre il primo valore ed alla fine la coda ancora tutti e 3 gli elementi inseriti.

50
50
[50, 100, 25]

Nel secondo esempio creiamo nuovamente una LinkedList in cui inseriamo gli stessi 3 elementi precedenti e poi invochiamo due volte il metodo poll():

import java.util.LinkedList;
import java.util.Queue;

public class QueueTest {

    public static void main(String[] args) {

        Queue<Integer> qi = new LinkedList<>();
        qi.add(50);
        qi.add(100);
        qi.add(25);

        Integer x = qi.poll();
        System.out.println(x);

        x = qi.poll();
        System.out.println(x);

        System.out.println(qi);
    }
}

Come possiamo vedere dal risultato seguente, la prima poll() estrae e rimuove il valore 50 e la seconda poll() estrae e rimuove il valore 100. Alla fine nella coda rimane soltanto il valore 25.

50
100
[25]

Nel terzo esempio creiamo una coda in cui questa volta inseriamo solo due elementi ed invochiamo poi tre volte il metodo poll():

import java.util.LinkedList;
import java.util.Queue;

public class QueueTest {

    public static void main(String[] args) {

        Queue<Integer> qi = new LinkedList<>();
        qi.add(50);
        qi.add(100);

        Integer x = qi.poll();
        System.out.println(x);

        x = qi.poll();
        System.out.println(x);

        x = qi.poll();
        System.out.println(x);

        System.out.println(qi);
    }
}

Come possiamo vedere dal risultato seguente le prime due invocazioni di poll() rimuovono i due elementi della lista che a questo punto è vuota. La terza chiamata poll() restituisce quindi null senza scatenare nessuna eccezione e la lista alla fine non contiene nessun elemento.

50
100
null
[]

Nel quarto esempio eseguiamo lo stesso scenario dell’esempio precedente, sostituendo però le tre chiamate poll() con tre chiamate remove():

import java.util.LinkedList;
import java.util.Queue;

public class QueueTest {

    public static void main(String[] args) {

        Queue<Integer> qi = new LinkedList<>();
        qi.add(50);
        qi.add(100);

        Integer x = qi.remove();
        System.out.println(x);

        x = qi.remove();
        System.out.println(x);

        x = qi.remove();
        System.out.println(x);

        System.out.println(qi);
    }
}

Come possiamo vedere dal risultato seguente, la terza chiamata remove() scatena una NoSuchElementException perchè eseguita su una coda vuota. Questo comportamento, come abbiamo detto, è quello che la differenzia dal metodo poll().

50
100
Exception in thread "main" java.util.NoSuchElementException
	at java.util.LinkedList.removeFirst(Unknown Source)
	at java.util.LinkedList.remove(Unknown Source)
	at net.davismol.ocpjp7.QueueTest.main(QueueTest.java:20)

Il quinto e sesto esempio illustrano la differenza di comportamento tra il metodo peek() ed element() quando vengono invocati su una coda vuota:

import java.util.LinkedList;
import java.util.Queue;

public class QueueTest {

    public static void main(String[] args) {

        Queue<Integer> qi = new LinkedList<>();
        System.out.println(qi.peek());
    }
}

Il risultato in questo primo caso è che ci viene ritornato il valore null.

null

Eseguiamo ora lo stesso test utilizzando questa volta il metodo element():

import java.util.LinkedList;
import java.util.Queue;

public class QueueTest {

    public static void main(String[] args) {

        Queue<Integer> qi = new LinkedList<>();
        System.out.println(qi.element());
    }
}

Ed ecco il risultato:

Exception in thread "main" java.util.NoSuchElementException
	at java.util.LinkedList.getFirst(Unknown Source)
	at java.util.LinkedList.element(Unknown Source)
	at net.davismol.ocpjp7.QueueTest.main(QueueTest.java:11)

Leave a Reply

Your email address will not be published. Required fields are marked *