PriorityQueue în Java

Coadă cu priorități: poll() scoate mereu cel mai mic element (sau primul după un Comparator), nu pe cel adăugat primul.

Sintaxă
new PriorityQueue<>()
new PriorityQueue<>(Comparator<? super E> comparator)
new PriorityQueue<>(Collection<? extends E> c)

Ce face PriorityQueue

PriorityQueue ține elementele într-un heap (o structură parțial ordonată). offer și poll sunt rapide (timp logaritmic), iar peek dă instantaneu elementul cu cea mai mare prioritate: implicit cel mai mic.

Pentru altă ordine dai un Comparator: new PriorityQueue<>(Comparator.reverseOrder()) scoate întâi cel mai mare. Pentru obiecte proprii, comparatorul spune cine are prioritate (de exemplu urgența unui pacient).

Atenție: doar poll și peek respectă ordinea. Afișarea cu println sau parcurgerea cu for-each arată ordinea internă a heap-ului, care nu este sortată. Ca să le vezi în ordine, scoate-le pe rând cu poll.

Parametri

Parametru Descriere
comparator Regula de prioritate; fără el, elementele trebuie să fie Comparable.
c Elementele inițiale.

Ce returnează

O coadă cu priorități, modificabilă.

Exemple

Exemplul 1: Pacienți la urgențe

Pacientul cu codul de urgență cel mai mic intră primul, indiferent când a sosit. La cod egal (Ana și Mihai), PriorityQueue nu garantează ordinea sosirii: aici Mihai intră înaintea Anei. Dacă ordinea contează, adaugă un criteriu secundar (de exemplu ora sosirii) cu thenComparing.

import java.util.Comparator;
import java.util.PriorityQueue;

public class Main {
    record Pacient(String nume, int urgenta) {}

    public static void main(String[] args) {
        PriorityQueue<Pacient> sala = new PriorityQueue<>(Comparator.comparingInt(Pacient::urgenta));
        sala.offer(new Pacient("Ana", 3));
        sala.offer(new Pacient("Radu", 1));
        sala.offer(new Pacient("Elena", 2));
        sala.offer(new Pacient("Mihai", 3));
        while (!sala.isEmpty()) {
            Pacient p = sala.poll();
            System.out.println("Intră " + p.nume() + " (cod " + p.urgenta() + ")");
        }
    }
}

Rezultat

Intră Radu (cod 1)
Intră Elena (cod 2)
Intră Mihai (cod 3)
Intră Ana (cod 3)

Exemplul 2: Primele 3 cele mai mari note

import java.util.Comparator;
import java.util.List;
import java.util.PriorityQueue;

public class Main {
    public static void main(String[] args) {
        PriorityQueue<Integer> note = new PriorityQueue<>(Comparator.reverseOrder());
        note.addAll(List.of(7, 10, 5, 9, 8, 10, 6));
        System.out.println("Cea mai mare: " + note.peek());
        for (int i = 0; i < 3; i++) {
            System.out.print(note.poll() + " ");
        }
        System.out.println();
        System.out.println("Au rămas " + note.size() + " note");
    }
}

Rezultat

Cea mai mare: 10
10 10 9 
Au rămas 4 note

Exemplul 3: Afișarea directă nu este sortată

import java.util.List;
import java.util.PriorityQueue;

public class Main {
    public static void main(String[] args) {
        PriorityQueue<Integer> pq = new PriorityQueue<>(List.of(5, 1, 4, 2, 3));
        System.out.println("println: " + pq);
        StringBuilder ordine = new StringBuilder();
        while (!pq.isEmpty()) {
            ordine.append(pq.poll()).append(' ');
        }
        System.out.println("poll pe rând: " + ordine);
    }
}

Rezultat

println: [1, 2, 4, 5, 3]
poll pe rând: 1 2 3 4 5

Greșeli frecvente

  • Afișezi sau parcurgi coada și aștepți ordinea sortată. Doar poll/peek respectă prioritatea.
  • Uiți că implicit iese cel mai mic element. Pentru „cel mai mare primul” dă Comparator.reverseOrder().
  • Modifici câmpul după care se ordonează un obiect aflat deja în coadă. Heap-ul nu se reorganizează; scoate obiectul, modifică-l și pune-l la loc.

Comenzi înrudite

  • Queue: Interfața pentru cozi: elementele intră la coadă și ies din față, în ordinea sosirii (FIFO), ca la ghișeu.
  • Queue.offer: offer pune un element la coada cozii, poll îl scoate pe primul (sau dă null), peek îl arată pe primul fără să-l scoată.
  • Comparator: Interfața care spune cum se ordonează două obiecte: compare(a, b) returnează un număr negativ, zero sau pozitiv.
  • TreeSet: Mulțime care ține elementele mereu sortate (crescător sau după un Comparator) și oferă căutări de tip „cel mai mic”, „cel mai apropiat”.
  • Collections.sort: Sortează o listă pe loc: crescător după ordinea naturală sau după un Comparator dat. Echivalent cu lista.sort(…).