A Prioritási várólistákat nagyon gyakran használják a való életben. Ebben a cikkben megtudhatjuk, hogy melyek a kiemelt várólisták, és hogyan tudjuk ezeket használni a Java-ban.
Mielőtt megvitatnánk, mi a prioritási sor, nézzük meg, mi a rendes sor.
A FIFO (first in first out) struktúrát egy szokásos sor követi. Ez azt jelenti, hogy ha 3 üzenet - m1, m2 és m3 - ebben a sorrendben kerül a sorba, akkor pontosan ugyanabban a sorrendben jönnek ki a sorból.
Miért van szükségünk sorokra?
Tegyük fel, hogy vannak adatgyártóink (például amikor a felhasználó rákattint egy weboldalra), amelyek rendkívül gyorsak. De akkor később ezeket az adatokat lassabban akarjuk felhasználni.
Ebben az esetben a gyártó az összes üzenetet a sorba tolja, a fogyasztó pedig ezeket az üzeneteket később lassabban, a sorból fogyasztja.
Mi a kiemelt sor?
Mint korábban említettük, a rendes sornak az első az elsőben kimenet szerkezete van. Bizonyos esetekben azonban az üzeneteket a sorban akarjuk feldolgozni a prioritásuk alapján, és nem az alapján, hogy az üzenet mikor lépett be a sorba.
A prioritási sorok segítik a fogyasztókat a magasabb prioritású üzenetek elfogyasztásában, majd az alacsonyabb prioritású üzenetek követésével.
Kiemelt sorok a Java-ban
Most nézzünk meg néhány tényleges Java-kódot, amely megmutatja, hogyan kell használni a prioritási sorokat.
Kiemelt sorok természetes rendezéssel
Íme néhány kód, amely bemutatja, hogyan lehet egyszerű prioritási sort létrehozni a karakterláncokhoz
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()); } }
Az első sor azt mondja, hogy prioritási várólistát hozunk létre:
Queue testStringsPQ = new PriorityQueue();
A PriorityQueue a java.util csomagban érhető el.
Ezután véletlenszerű sorrendben 5 karakterláncot adunk a prioritási sorba. Ehhez az add () függvényt használjuk az alábbiak szerint:
testStringsPQ.add("abcd"); testStringsPQ.add("1234"); testStringsPQ.add("23bc"); testStringsPQ.add("zzxx"); testStringsPQ.add("abxy");
Annak érdekében, hogy a legfrissebb elemet elérjük a sorból, a poll () függvényt használjuk az alábbiak szerint:
testStringsPQ.poll()
A poll () megadja nekünk a legfrissebb tételt, és eltávolítja a sorból is. Ha azt szeretnénk elérni, hogy a legfrissebb elemet eltávolítsuk a sorból, akkor használhatjuk a peek () függvényt:
testStringsPQ.peek()
Végül kinyomtatjuk az összes elemet a sorból a poll () függvény használatával, az alábbiak szerint:
while (!testStringsPQ.isEmpty()) { System.out.println(testStringsPQ.poll()); }
Itt van a fenti program kimenete:
1234 23bc abcd abxy zzxx
Mivel nem mondtuk meg az elsőbbségi várólistának, hogyan állítsuk fontossági sorrendbe a tartalmát, alapértelmezett természetes sorrendet használt. Ebben az esetben visszaadta nekünk az adatokat a húrok növekvő sorrendjében. Ez nem ugyanaz a sorrend, amelyben az elemeket felvették a sorba.
Mi a helyzet az egyedi megrendeléssel?
Ez is lehetséges, és összehasonlító segítségével megtehetjük .
Hozzunk létre most egy egész prioritású sort. De ezúttal kapjuk meg az eredményt csökkenő értékrend szerint.
Ennek érdekében először létre kell hoznunk egy egész összehasonlítót:
static class CustomIntegerComparator implements Comparator { @Override public int compare(Integer o1, Integer o2) { return o1 < o2 ? 1 : -1; } }
Az összehasonlító létrehozása érdekében megvalósítjuk az összehasonlító felületet és felülírjuk az összehasonlítási módszert.
Az o1 <o2 használatával? 1: -1 csökkenő sorrendben kapjuk meg az eredményt. Ha o1> o2-t használtunk volna ? 1: -1, akkor növekvő sorrendben kaptuk volna meg az eredményt
Most, hogy megvan az összehasonlító, hozzá kell adnunk ezt az összehasonlítót a prioritási sorhoz. Ezt így tehetjük:
Queue testIntegersPQ = new PriorityQueue(new CustomIntegerComparator());
Itt van a kód többi része, amely elemeket ad hozzá a prioritási sorba és kinyomtatja őket:
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()); }
A fenti program kimenete az alábbiakban látható:
12 11 6 5 -1
Láthatjuk, hogy az összehasonlító jól végezte munkáját. Most a prioritási sorban csökkenő sorrendben adjuk meg az egész számokat.
Prioritási sor Java objektumokkal
Eddig a pontig láttuk, hogyan használhatjuk a karakterláncokat és az egész számokat prioritási sorokkal.
A való életben alkalmazott alkalmazásokban általában prioritási sorokat használunk egyedi Java objektumokkal.
Először hozzunk létre egy CustomerOrder nevű osztályt, amely az ügyfelek megrendelésének részleteit tárolja:
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; } }
Ez egy egyszerű Java osztály az ügyfelek megrendelésének tárolására. Ez az osztály összehasonlítható interfészt valósít meg , így eldönthetjük, milyen alapon kell megrendelni ezt az objektumot a prioritási sorban.
A sorrendet a fenti kód összehasonlító funkciója dönti el. Az o.orderId> this.orderId sor? Az 1: -1 utasítja, hogy a megrendeléseket a orderId mező csökkenő sorrendje alapján rendezzék
Az alábbiakban látható az a kód, amely prioritási várólistát hoz létre a CustomerOrder objektumhoz:
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()); }
A fenti kódban három vevői megrendelés készült, és hozzá lett adva a prioritási sorhoz.
Amikor futtatjuk ezt a kódot, a következő kimenetet kapjuk:
orderId:3, orderAmount:50.0, customerName:customer3 orderId:2, orderAmount:300.0, customerName:customer2 orderId:1, orderAmount:100.0, customerName:customer1
Ahogy az várható volt, az eredmény a orderId csökkenő sorrendjében jön .
Mi van, ha a orderAmount alapján szeretnénk fontossági sorrendet állítani?
Ez ismét egy valós forgatókönyv. Tegyük fel, hogy alapértelmezés szerint a CustomerOrder objektumot a orderId rangsorolja. De akkor szükségünk van egy módra, amellyel a orderAmount alapján rangsorolhatjuk.
Lehet azonnal úgy gondolja, hogy tudjuk módosítani a compareTo funkciót a CustomerOrder c kislány rendelésre alapuló orderAmount.
De a CustomerOrder c lass több helyen is használható az alkalmazásban, és ez zavarná az alkalmazás többi részét, ha közvetlenül módosítanánk a CompareTo függvényt.
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.