Prioritetni redovi u Javi objašnjeni primjerima

Redovi s prioritetom vrlo se često koriste u stvarnim aplikacijama. U ovom ćemo članku naučiti što su prioritetni redovi i kako ih možemo koristiti u Javi.

Prije nego što razgovaramo što je prioritetni red, pogledajmo što je redoviti red.

Redovni red slijedi strukturu prvi ulaz-izlaz (FIFO). To znači da ako 3 poruke - m1, m2 i m3 - idu u red istim redoslijedom, tada izlaze iz reda potpuno istim redoslijedom.

Zašto su nam potrebni redovi?

Recimo da imamo proizvođače podataka (na primjer, kada korisnik klikne na web stranicu) koji su izuzetno brzi. Ali tada kasnije želimo te podatke trošiti sporije.

U ovom slučaju, proizvođač će sve poruke gurnuti u red čekanja, a potrošač će ih sporije trošiti kasnije iz reda čekanja.

Što je prioritetni red?

Kao što je ranije spomenuto, redoviti red ima strukturu prvi u prvom izlazu. No, u nekim scenarijima želimo obrađivati ​​poruke u redu na temelju njihova prioriteta, a ne na temelju toga kada je poruka ušla u red.

Prioritetni redovi pomažu potrošačima da prvo potroše poruke višeg prioriteta, a zatim poruke nižeg prioriteta.

Prioritetni redovi u Javi

Sada ćemo vidjeti stvarni Java kôd koji će nam pokazati kako koristiti prioritetne redove.

Prioritetni redovi s prirodnim redoslijedom

Evo nekoliko kodova koji pokazuju kako stvoriti jednostavan red prioriteta za nizove

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 Queue\n"); while (!testStringsPQ.isEmpty()) { System.out.println(testStringsPQ.poll()); } }

Prvi redak govori nam da stvaramo prioritetni red:

Queue testStringsPQ = new PriorityQueue();

PriorityQueue dostupan je u paketu java.util.

Dalje dodajemo 5 nizova nasumičnim redoslijedom u red prioriteta. Za to koristimo funkciju add () kako je prikazano dolje:

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

Da bismo dobili najnoviju stavku iz reda, koristimo funkciju poll () kao što je prikazano dolje:

testStringsPQ.poll()

anketa () dat će nam najnoviju stavku i također će je ukloniti iz reda čekanja. Ako želimo dobiti najnoviju stavku u redu bez uklanjanja, možemo koristiti funkciju peek () :

testStringsPQ.peek()

Na kraju, ispisujemo sve elemente iz reda pomoću funkcije poll () kako je prikazano u nastavku:

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

Evo rezultata gornjeg programa:

1234 23bc abcd abxy zzxx

Budući da prioritetnom redu nismo rekli kako odrediti njegov sadržaj kao prioritet, koristio je zadani prirodni poredak. U ovom nam je slučaju vratio podatke prema rastućem nizu nizova. Ovo nije isti redoslijed kojim su stavke dodane u red.

Što je s prilagođenim naručivanjem?

To je također moguće, a to možemo učiniti uz pomoć usporedbe.

Stvorimo sada red s cjelobrojnim prioritetom. Ali ovaj put neka rezultat dobijemo silaznim redoslijedom vrijednosti.

Da bismo to postigli, prvo moramo stvoriti usporednicu cijelih brojeva:

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

Da bismo stvorili komparator, implementiramo sučelje komparatora i nadjačavamo metodu usporedbe .

Korištenjem o1 <o2? 1: -1 dobit ćemo rezultat u opadajućem redoslijedu. Da smo koristili o1> o2? 1: -1, tada bismo rezultat dobili uzlaznim redoslijedom

Sad kad imamo usporednik, trebamo ga dodati u prioritetni red. To možemo učiniti ovako:

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

Evo ostatka koda koji dodaje elemente u red prioriteta i ispisuje ih:

 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 Queue\n"); while (!testIntegersPQ.isEmpty()) { System.out.println(testIntegersPQ.poll()); }

Rezultat gornjeg programa dat je u nastavku:

12 11 6 5 -1

Vidimo da je usporednik dobro obavio svoj posao. Sada nam prioritetni red daje cijele brojeve u opadajućem redoslijedu.

Prioritetni red s Java objektima

Do ovog trenutka vidjeli smo kako možemo koristiti nizove i cijele brojeve s prioritetnim redovima.

U aplikacijama iz stvarnog života obično bismo koristili prioritetne redove s prilagođenim Java objektima.

Prvo napravimo klasu nazvanu CustomerOrder koja se koristi za pohranu detalja narudžbe kupca:

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; } }

Ovo je jednostavna Java klasa za spremanje narudžbi kupaca. Ova klasa implementira usporedivo sučelje, tako da možemo odlučiti na temelju čega ovaj objekt treba naručiti u redu prioriteta.

The ordering is decided by the compareTo function in the above code. The line o.orderId > this.orderId ? 1 : -1 instructs that the orders should be sorted based on descending order of the orderId field

Below is the code which creates a priority queue for the CustomerOrder object:

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()); }

In the above code three customer orders have been created and added to the priority queue.

When we run this code we get the following output:

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

As expected, the result comes in descending order of the orderId.

What if we want to prioritize based on orderAmount?

This is again a real life scenario. Let's say that by default the CustomerOrder object is prioritized by the orderId. But then we need a way in which we can prioritize based on orderAmount.

You may immediately think that we can modify the compareTo function in the CustomerOrder class to order based on orderAmount.

But the CustomerOrder class may be used in multiple places in the application, and it would interfere with the rest of the application if we modify the compareTo function directly.

The solution to this is pretty simple: we can create a new custom comparator for the CustomerOrder class and use that along with the priority queue

Below is the code for the custom comparator:

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

This is very similar to the custom integer comparator we saw earlier.

The line o1.getOrderAmount() < o2.getOrderAmount() ? 1 : -1; indicates that we need to prioritize based on descending order of orderAmount.

Below is the code which creates the priority queue:

 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()); }

In the above code we are passing the comparator to the priority queue in the following line of code:

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

Below is the result when we run this code:

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

We can see that the data comes in descending order of the orderAmount.

Code

All the code discussed in this article can be found in this GitHub repo.

Congrats ?

You now know how to use priority queues in Java.

About the author

I love technology and follow the advancements in the field. I also like helping others with my technology knowledge.

Feel free to connect with me on my LinkedIn account //www.linkedin.com/in/aditya1811/

You can also follow me on twitter //twitter.com/adityasridhar18

Feel free to read more of my articles on my blog at adityasridhar.com.