Java PriorityQueue Comparator

4

I'm trying to understand why the native java mode is not comparing, I do not know where I'm going wrong.

MAIN

//  EXERCICIO PARA COMPARAR DOIS OBJETOS, USANDO CLASSE NATIVA DE COMPARAÇÃO DO JAVA

public static void main(String[] args) {
    FilaComPrioridade<Paciente> fila = new FilaComPrioridade<>();

    // CLASSE ANONIMA DENTRO DO NOSSO PROJETO.
    Queue<Paciente> filaComPrioridade = new PriorityQueue<>(new Comparator<Paciente>() {
        @Override
        public int compare(Paciente p1, Paciente p2) {
            return Integer.valueOf(p1.getPrioridade()).compareTo(p2.getPrioridade());
        }
    });

    filaComPrioridade.add(new Paciente("A", 2));
    filaComPrioridade.add(new Paciente("B1", 1));
    filaComPrioridade.add(new Paciente("B2", 1));
    filaComPrioridade.add(new Paciente("B3", 1));
    filaComPrioridade.add(new Paciente("B4", 1));
    filaComPrioridade.add(new Paciente("C", 3));

    fila.enfileira(new Paciente("A", 2));
    fila.enfileira(new Paciente("B1", 1));
    fila.enfileira(new Paciente("B2", 1));
    fila.enfileira(new Paciente("B3", 1));
    fila.enfileira(new Paciente("B4", 1));
    fila.enfileira(new Paciente("C", 3));

    System.out.println(filaComPrioridade);
    System.out.println(fila);
}

}

Printing

  

[Patient [name = B1, priority = 1], Patient [name = B3, priority = 1],   Patient [name = B2, priority = 1], Patient [name = A, priority = 2],   Patient [name = B4, priority = 1], Patient [name = C, priority = 3]]

     

[Patient [name = B1, priority = 1], Patient [name = B2, priority = 1],   Patient [name = B3, priority = 1], Patient [name = B4, priority = 1],   Patient [name = A, priority = 2], Patient [name = C, priority = 3]]

Priority Queue Class:

package pt.estruturadedados.base.fila;

public class FilaComPrioridade<T> extends Fila<T> {

    @Override
    public void enfileira(T elemento) {

        Comparable<T> chave = (Comparable<T>) elemento;

        int i;
        for (i = 0; i < this.tamanho; i++) {
            if (chave.compareTo(this.elementos[i]) < 0) {
                break;
            }
        }
        this.adiciona(i, elemento);
    }

}

CompareTo in Patient Class of Manual "NON NATIVE" (Second Printing)

@Override
public int compareTo(Paciente o) {

    return Integer.valueOf(this.getPrioridade()).compareTo(o.getPrioridade()); //Forma mais elegante de fazer.
}
    
asked by anonymous 17.01.2018 / 12:11

1 answer

9

I will not know to go into much detail, but here goes:

The System.out.println() method uses the toString() method of the AbstractCollection class, which in turn uses an Iterator (which is obtained through the iterator() method of the PriorityQueue itself). It turns out that the iterator() method of the PriorityQueue class does not guarantee the order of the elements in the queue.

Method documentation iterator() :

  

Returns an iterator over the elements in this collection. There are no   guarantees regarding the order in which the elements are returned   (unless this collection is an instance of some class that provides   guarantee).

However, if you use the PriorityQueue class's own methods to manipulate the elements, they will be removed in the correct order according to the predefined priority. Example:

Patient Class:

public class Paciente implements Comparable<Paciente> {

    private String nome;
    private int prioridade;

    public Paciente(String nome, int prioridade) {
        super();
        this.nome = nome;
        this.prioridade = prioridade;
    }

get and set methods for attributes ...

    @Override
    public int compareTo(Paciente o) {
        if (this.prioridade > o.getPrioridade()) {
            return 1;
        } else if (this.prioridade < o.getPrioridade()) {
            return -1;
        }

        return 0;
    }

    @Override
    public String toString() {
        return "[" + nome + ", " + prioridade + "]";
    }

}

DuvidaPriorityQueue class:

import java.util.PriorityQueue;
import java.util.Queue;

public class DuvidaPriorityQueue {

    public static void main(String[] args) {

        Queue<Paciente> pqPac = new PriorityQueue<>();

        pqPac.add(new Paciente("A", 9));
        pqPac.add(new Paciente("B", 5));
        pqPac.add(new Paciente("C", 8));
        pqPac.add(new Paciente("D", 1));
        pqPac.add(new Paciente("E", 2));

        System.out.println(pqPac);//O que você fez

        System.out.println();

        //O que deveria ter feito:
        while(!pqPac.isEmpty()) {
            System.out.print(pqPac.poll() + ", ");
        }


    }

}

The output of this last class will be as follows:

  

[[D, 1], [E, 2], [C, 8], [A, 9], [B, 5]      

[D, 1], [E, 2], [B, 5], [C, 8], [A, 9]

Test trying to add elements in another order. If you exit from the console using the methods of the PriorityQueue class itself as an intermediary, the priority you set will be obeyed. If you use the System.out.println() direct method on the PriorityQueue object you created, the result will vary.

Source (do not laugh):

Comment and answers from Ingrid Marçal and DevDojo in this video (and the tests I've done to prove them): [Youtube]

    
10.02.2018 / 21:28