Comment utiliser un PriorityQueue?

Comment puis-je obtenir une PriorityQueue pour sortinger ce que je veux que l’on sortinge?

En outre, existe-t-il une différence entre l’ offer et les méthodes d’ add ?

Utilisez la surcharge constructeur qui prend un Comparator comparator Comparator comparator et passer dans un comparateur qui se compare de manière appropriée à votre ordre de sorting. Si vous donnez un exemple de ce que vous voulez sortinger, nous pouvons fournir un exemple de code pour implémenter le comparateur si vous n’êtes pas sûr. (C’est assez simple cependant.)

Comme cela a été dit ailleurs: l’ offer et l’ add sont que des implémentations de méthodes d’interface différentes. Dans la source JDK que j’ai, add offer appels. Bien que l’ add et l’ offer aient un comportement potentiellement différent en général en raison de la possibilité pour les offer d’indiquer que la valeur ne peut pas être ajoutée en raison des limitations de taille, cette différence est sans importance dans PriorityQueue qui est illimité.

Voici un exemple de sorting de queue prioritaire par longueur de chaîne:

 // Test.java import java.util.Comparator; import java.util.PriorityQueue; public class Test { public static void main(Ssortingng[] args) { Comparator comparator = new SsortingngLengthComparator(); PriorityQueue queue = new PriorityQueue(10, comparator); queue.add("short"); queue.add("very long indeed"); queue.add("medium"); while (queue.size() != 0) { System.out.println(queue.remove()); } } } // SsortingngLengthComparator.java import java.util.Comparator; public class SsortingngLengthComparator implements Comparator { @Override public int compare(Ssortingng x, Ssortingng y) { // Assume neither ssortingng is null. Real code should // probably be more robust // You could also just return x.length() - y.length(), // which would be more efficient. if (x.length() < y.length()) { return -1; } if (x.length() > y.length()) { return 1; } return 0; } } 

Voici la sortie:

court

moyen

très longtemps en effet

Solution Java 8

Nous pouvons utiliser l’ lambda expression ou la method reference lambda expression introduite dans Java 8. Si nous avons des valeurs de chaîne stockées dans la queue prioritaire, nous pouvons fournir un comparateur en ligne (basé sur la longueur de la chaîne):

Utiliser l’expression lambda

 PriorityQueue pq= new PriorityQueue(5,(a,b) -> a.length() - b.length()); 

Utilisation de la référence de méthode

 PriorityQueue pq= new PriorityQueue(5, Comparator.comparing(Ssortingng::length)); 

Ensuite, nous pouvons utiliser l’un d’eux comme:

 public static void main(Ssortingng[] args) { PriorityQueue pq= new PriorityQueue(5, (a,b) -> a.length() - b.length()); // or pq = new PriorityQueue(5, Comparator.comparing(Ssortingng::length)); pq.add("Apple"); pq.add("PineApple"); pq.add("Custard Apple"); while (pq.size() != 0) { System.out.println(pq.remove()); } } 

Cela va imprimer:

 Apple PineApple Custard Apple 

Pour inverser l’ordre (pour le changer en queue maximale), changez simplement l’ordre dans le comparateur en ligne.

offre () vs add ()

Selon la doc

La méthode offre insère un élément si possible, sinon retourne false. Cela diffère de la méthode Collection.add, qui ne parvient pas à append un élément en lançant une exception non contrôlée. La méthode de l’offre est conçue pour être utilisée lorsque la défaillance est une occurrence normale, plutôt qu’exceptionnelle, par exemple dans les files d’attente à capacité fixe (ou «limitée»).

Lorsque vous utilisez une queue à capacité restreinte, off () est généralement préférable à add (), qui ne peut pas insérer un élément uniquement en lançant une exception. Et PriorityQueue est une queue prioritaire non liée basée sur un segment de priorité.

Il suffit de passer le Comparator approprié au constructeur :

 PriorityQueue(int initialCapacity, Comparator comparator) 

La seule différence entre l’ offer et l’ add est l’interface à laquelle ils appartiennent. offer appartient à la Queue d’ Queue , alors que l’ add est vu à l’origine dans l’interface Collection . En dehors de cela, les deux méthodes font exactement la même chose: insérer l’élément spécifié dans la queue prioritaire.

de l’ API Queue :

La méthode offre insère un élément si possible, sinon retourne false. Cela diffère de la méthode Collection.add, qui ne parvient pas à append un élément en lançant une exception non contrôlée. La méthode de l’offre est conçue pour être utilisée lorsque la défaillance est une occurrence normale, plutôt qu’exceptionnelle, par exemple dans les files d’attente à capacité fixe (ou «limitée»).

pas différent, comme déclaré dans javadoc:

 public boolean add(E e) { return offer(e); } 

Juste pour répondre à la question add() vs offer() puisque l’autre répond parfaitement à imo, et cela pourrait ne pas être le cas:

Selon JavaDoc on Interface Queue , “la méthode offer insère un élément si possible, sinon renvoie false. Cela diffère de la méthode Collection.add, qui peut ne pas append un élément en lançant une exception non contrôlée. La méthode offre est conçue pour utiliser lorsque la défaillance est une occurrence normale, plutôt qu’exceptionnelle, par exemple, dans des files d’attente à capacité fixe (ou “limitée”). ”

Cela signifie que si vous pouvez append l’élément (ce qui devrait toujours être le cas dans PriorityQueue), ils fonctionnent exactement de la même manière. Mais si vous ne pouvez pas append l’élément, offer() vous donnera un joli et très false retour, alors que add() génère une exception non vérifiée que vous ne voulez pas dans votre code. Si le défaut d’append signifie que le code fonctionne comme prévu et / ou c’est quelque chose que vous allez vérifier normalement, utilisez l’ offer() . Si l’échec de l’ajout signifie que quelque chose est cassé, utilisez add() et gérez l’exception résultante renvoyée conformément aux spécifications de l’interface Collection .

Ils sont tous deux implémentés de cette manière pour remplir le contrat sur l’interface de queue spécifiant l’ offer() échoue en renvoyant un false ( méthode préférée dans les files d’attente restreintes ) et conservant le contrat sur l’interface Collection jeter une exception .

Quoi qu’il en soit, j’espère que cela clarifie au moins cette partie de la question.

Ici, nous pouvons définir un comparateur défini par l’utilisateur:

Code ci-dessous:

  import java.util.*; import java.util.Collections; import java.util.Comparator; class Checker implements Comparator { public int compare(Ssortingng str1, Ssortingng str2) { if (str1.length() < str2.length()) return -1; else return 1; } } class Main { public static void main(String args[]) { PriorityQueue queue=new PriorityQueue(5, new Checker()); queue.add("india"); queue.add("bangladesh"); queue.add("pakistan"); while (queue.size() != 0) { System.out.printf("%s\n",queue.remove()); } } } 

Sortie:

  india pakistan bangladesh 

Différence entre l’offre et les méthodes d’ajout: lien

Je m’interrogeais également sur la commande d’impression. Considérez ce cas, par exemple:

Pour une queue prioritaire:

 PriorityQueue pq3 = new PriorityQueue(); 

Ce code:

 pq3.offer("a"); pq3.offer("A"); 

peut imprimer différemment que:

 Ssortingng[] sa = {"a", "A"}; for(Ssortingng s : sa) pq3.offer(s); 

J’ai trouvé la réponse à une discussion sur un autre forum , où un utilisateur a déclaré: “Les méthodes offer () / add () insèrent uniquement l’élément dans la queue. Si vous voulez un ordre prévisible, vous devez utiliser peek / poll de la queue. ”

Au lieu d’utiliser Comparator , vous pouvez également avoir la classe que vous utilisez dans votre outil PriorityQueue Comparable (et remplacer en compareTo méthode compareTo ).

Notez qu’il est généralement préférable d’utiliser Comparable plutôt que Comparator si cet ordre est l’ordre intuitif de l’object – si, par exemple, vous avez un cas d’utilisation pour sortinger les objects Person par âge, il est préférable d’utiliser Comparator .

 import java.lang.Comparable; import java.util.PriorityQueue; class Test { public static void main(Ssortingng[] args) { PriorityQueue queue = new PriorityQueue(); queue.add(new MyClass(2, "short")); queue.add(new MyClass(2, "very long indeed")); queue.add(new MyClass(1, "medium")); queue.add(new MyClass(1, "very long indeed")); queue.add(new MyClass(2, "medium")); queue.add(new MyClass(1, "short")); while (queue.size() != 0) System.out.println(queue.remove()); } } 
 class MyClass implements Comparable { int sortFirst; Ssortingng sortByLength; public MyClass(int sortFirst, Ssortingng sortByLength) { this.sortFirst = sortFirst; this.sortByLength = sortByLength; } @Override public int compareTo(MyClass other) { if (sortFirst != other.sortFirst) return Integer.compare(sortFirst, other.sortFirst); else return Integer.compare(sortByLength.length(), other.sortByLength.length()); } public Ssortingng toSsortingng() { return sortFirst + ", " + sortByLength; } } 

Sortie:

 1, short 1, medium 1, very long indeed 2, short 2, medium 2, very long indeed 

Priorité File d’attente a une priorité assignée à chaque élément. L’élément avec la plus haute priorité apparaît dans la partie supérieure de la queue. Maintenant, cela dépend de vous comment vous voulez que la priorité soit assignée à chacun des éléments. Si vous ne le faites pas, le Java le fera par défaut. L’élément avec la valeur la plus faible se voit atsortingbuer la priorité la plus élevée et est donc d’abord retiré de la queue. S’il y a plusieurs éléments avec la même priorité, le lien est rompu arbitrairement. Vous pouvez également spécifier un ordre en utilisant Comparator dans le constructeur PriorityQueue(initialCapacity, comparator)

Exemple de code:

 PriorityQueue queue1 = new PriorityQueue<>(); queue1.offer("Oklahoma"); queue1.offer("Indiana"); queue1.offer("Georgia"); queue1.offer("Texas"); System.out.println("Priority queue using Comparable:"); while (queue1.size() > 0) { System.out.print(queue1.remove() + " "); } PriorityQueue queue2 = new PriorityQueue(4, Collections.reverseOrder()); queue2.offer("Oklahoma"); queue2.offer("Indiana"); queue2.offer("Georgia"); queue2.offer("Texas"); System.out.println("\nPriority queue using Comparator:"); while (queue2.size() > 0) { System.out.print(queue2.remove() + " "); } 

Sortie:

 Priority queue using Comparable: Georgia Indiana Oklahoma Texas Priority queue using Comparator: Texas Oklahoma Indiana Georgia 

Sinon, vous pouvez également définir un comparateur personnalisé:

 import java.util.Comparator; public class SsortingngLengthComparator implements Comparator { @Override public int compare(Ssortingng x, Ssortingng y) { //Your Own Logic } } 

Voici l’exemple simple que vous pouvez utiliser pour l’apprentissage initial:

 import java.util.Comparator; import java.util.PriorityQueue; import java.util.Queue; import java.util.Random; public class PQExample { public static void main(Ssortingng[] args) { //PriorityQueue with Comparator Queue cpq = new PriorityQueue<>(7, idComp); addToQueue(cpq); pollFromQueue(cpq); } public static Comparator idComp = new Comparator(){ @Override public int compare(Customer o1, Customer o2) { return (int) (o1.getId() - o2.getId()); } }; //utility method to add random data to Queue private static void addToQueue(Queue cq){ Random rand = new Random(); for(int i=0;i<7;i++){ int id = rand.nextInt(100); cq.add(new Customer(id, "KV"+id)); } } private static void pollFromQueue(Queue cq){ while(true){ Customer c = cq.poll(); if(c == null) break; System.out.println("Customer Polled : "+c.getId() + " "+ c.getName()); } } } 

Passez lui un Comparator . Remplissez le type de votre choix à la place de T

Utilisation de lambdas (Java 8+):

 int initialCapacity = 10; PriorityQueue pq = new PriorityQueue<>(initialCapacity, (e1, e2) -> { return e1.compareTo(e2); }); 

Manière classique, en utilisant la classe anonyme:

 int initialCapacity = 10; PriorityQueue pq = new PriorityQueue<>(initialCapacity, new Comparator () { @Override public int compare(T e1, T e2) { return e1.compareTo(e2); } }); 

Pour sortinger dans l’ordre inverse, échangez simplement e1, e2.