private static void testStringsNaturalOrdering() {
        Queue testStringsPQ = new PriorityQueue<>();
        testStringsPQ.add("abcd");
        testStringsPQ.add("1234");
        testStringsPQ.add("23bc");
        testStringsPQ.add("zzxx");
        testStringsPQ.add("abxy");

        System.out.println("Strings Stored in Natural Ordering in a Priority Queuen");
        while (!testStringsPQ.isEmpty()) {
            System.out.println(testStringsPQ.poll());
        }
    }

A primeira linha nos diz que estamos criando uma fila de prioridade:

Queue testStringsPQ = new PriorityQueue<>();

PriorityQueue está disponível no pacote java.util.

Em seguida, adicionamos 5 strings em ordem aleatória na fila de prioridade. Para isso, usamos o adicionar() função como mostrado abaixo:

testStringsPQ.add("abcd");
testStringsPQ.add("1234");
testStringsPQ.add("23bc");
testStringsPQ.add("zzxx");
testStringsPQ.add("abxy");

Para obter o item mais recente da fila, usamos o votação() função como mostrado abaixo:

testStringsPQ.poll()

votação() nos fornecerá o item mais recente e também o removerão da fila. Se quisermos obter o item mais recente na fila sem removê-lo, podemos usar o olhadinha() função:

testStringsPQ.peek()

Por fim, imprimimos todos os elementos da fila usando a função poll () como mostrado abaixo:

while (!testStringsPQ.isEmpty()) {
   System.out.println(testStringsPQ.poll());
}

Aqui está a saída do programa acima:

1234
23bc
abcd
abxy
zzxx

Como não dissemos à fila de prioridade como priorizar seu conteúdo, ela utilizou uma ordem natural padrão. Nesse caso, ele retornou os dados na ordem crescente das strings. Essa não é a mesma ordem em que os itens foram adicionados à fila.

Que tal ter um pedido personalizado?

Isso também é possível, e podemos fazê-lo com a ajuda de um comparador.

Vamos criar uma fila de prioridade inteira agora. Mas desta vez vamos obter o resultado em ordem decrescente de valor.

Para conseguir isso, primeiro precisamos criar um comparador inteiro:

 static class CustomIntegerComparator implements Comparator {

        @Override
        public int compare(Integer o1, Integer o2) {
            return o1 < o2 ? 1 : -1;
        }
    }

Para criar um comparador, implementamos o comparador interface e substitua o comparar método.

Usando o1 obteremos o resultado em ordem decrescente. Se tivéssemos usado o1> o2? 1: -1, então teríamos obtido o resultado em ordem crescente

Agora que temos o comparador, precisamos adicioná-lo à fila de prioridade. Podemos fazer isso assim:

Queue testIntegersPQ = new PriorityQueue<>(new CustomIntegerComparator());

Aqui está o restante do código que adiciona elementos à fila de prioridade e os imprime:

   testIntegersPQ.add(11);
        testIntegersPQ.add(5);
        testIntegersPQ.add(-1);
        testIntegersPQ.add(12);
        testIntegersPQ.add(6);

        System.out.println("Integers stored in reverse order of priority in a Priority Queuen");
        while (!testIntegersPQ.isEmpty()) {
            System.out.println(testIntegersPQ.poll());
        }

A saída do programa acima é fornecida abaixo:

12
11
6
5
-1

Podemos ver que o comparador fez seu trabalho bem. Agora a fila de prioridade está nos fornecendo os números inteiros em ordem decrescente.

Fila prioritária com objetos Java

Até o momento, vimos como podemos usar strings e números inteiros com filas de prioridade.

Em aplicativos da vida real, geralmente estaríamos usando filas de prioridade com objetos Java personalizados.

Vamos primeiro criar uma classe chamada CustomerOrder que é usada para armazenar detalhes do pedido do cliente:

public class CustomerOrder implements Comparable {
    private int orderId;
    private double orderAmount;
    private String customerName;

    public CustomerOrder(int orderId, double orderAmount, String customerName) {
        this.orderId = orderId;
        this.orderAmount = orderAmount;
        this.customerName = customerName;
    }

    @Override
    public int compareTo(CustomerOrder o) {
        return o.orderId > this.orderId ? 1 : -1;
    }

    @Override
    public String toString() {
        return "orderId:" + this.orderId + ", orderAmount:" + this.orderAmount + ", customerName:" + customerName;
    }

    public double getOrderAmount() {
        return orderAmount;
    }
}

Esta é uma classe Java simples para armazenar pedidos de clientes. Esta classe implementa interface comparável, para que possamos decidir com que base esse objeto precisa ser pedido na fila de prioridade.

A encomenda é decidida pelo comparado a função no código acima. A linha o.orderId> this.orderId? 1: -1 instrui que os pedidos devem ser classificados com base na ordem decrescente do orderId campo

Abaixo está o código que cria uma fila de prioridade para o objeto CustomerOrder:

CustomerOrder c1 = new CustomerOrder(1, 100.0, "customer1");
CustomerOrder c2 = new CustomerOrder(3, 50.0, "customer3");
CustomerOrder c3 = new CustomerOrder(2, 300.0, "customer2");

Queue customerOrders = new PriorityQueue<>();
customerOrders.add(c1);
customerOrders.add(c2);
customerOrders.add(c3);
while (!customerOrders.isEmpty()) {
	System.out.println(customerOrders.poll());
}

No código acima, três pedidos de clientes foram criados e adicionados à fila de prioridade.

Quando executamos esse código, obtemos a seguinte saída:

orderId:3, orderAmount:50.0, customerName:customer3
orderId:2, orderAmount:300.0, customerName:customer2
orderId:1, orderAmount:100.0, customerName:customer1

Como esperado, o resultado vem em ordem decrescente do orderId.

E se quisermos priorizar com base em orderAmount?

Este é novamente um cenário da vida real. Digamos que, por padrão, o objeto CustomerOrder seja priorizado pelo orderId. Mas precisamos de uma maneira pela qual possamos priorizar com base no orderAmount.

Você pode pensar imediatamente que podemos modificar o comparado a função no CustomerOrder cpara encomendar com base em orderAmount.

Mas o CustomerOrder cA moça pode ser usada em vários locais do aplicativo e interferiria com o restante do aplicativo se modificarmos o comparado a função diretamente.

A solução para isso é bastante simples: podemos criar um novo comparador personalizado para a classe CustomerOrder e usá-lo junto com a fila de prioridade

Abaixo está o código para o comparador personalizado:

 static class CustomerOrderComparator implements Comparator {

        @Override
        public int compare(CustomerOrder o1, CustomerOrder o2)
        {
            return o1.getOrderAmount() < o2.getOrderAmount() ? 1 : -1;
        }
    }

Isso é muito semelhante ao comparador inteiro personalizado que vimos anteriormente.

A linha o1.getOrderAmount() < o2.getOrderAmount() ? 1 : -1; indica que precisamos priorizar com base na ordem decrescente de Valor do pedido.

Abaixo está o código que cria a fila de prioridade:

  CustomerOrder c1 = new CustomerOrder(1, 100.0, "customer1");
        CustomerOrder c2 = new CustomerOrder(3, 50.0, "customer3");
        CustomerOrder c3 = new CustomerOrder(2, 300.0, "customer2");
        Queue customerOrders = new PriorityQueue<>(new CustomerOrderComparator());
        customerOrders.add(c1);
        customerOrders.add(c2);
        customerOrders.add(c3);
        while (!customerOrders.isEmpty()) {
            System.out.println(customerOrders.poll());
        }

No código acima, estamos passando o comparador para a fila de prioridade na seguinte linha de código:

Queue customerOrders = new PriorityQueue<>(new CustomerOrderComparator());

Abaixo está o resultado quando executamos este código:

orderId:2, orderAmount:300.0, customerName:customer2
orderId:1, orderAmount:100.0, customerName:customer1
orderId:3, orderAmount:50.0, customerName:customer3

Podemos ver que os dados vêm em ordem decrescente do orderAmount.

Código

Todo o código discutido neste artigo pode ser encontrado em este repositório GitHub.

Parabéns 😊

Agora você sabe como usar filas prioritárias em Java.

Sobre o autor

Adoro tecnologia e acompanho os avanços no campo. Também gosto de ajudar outras pessoas com meu conhecimento em tecnologia.

Sinta-se à vontade para se conectar comigo na minha conta do LinkedIn https://www.linkedin.com/in/aditya1811/

Você pode também me seguir no Twitter https://twitter.com/adityasridhar18

Sinta-se livre para ler mais dos meus artigos no meu blog em adityasridhar.com.