418 votes

Java: Comment utiliser une PriorityQueue?

Comment puis-je obtenir un PriorityQueue pour trier sur ce que je veux trier?

Ajouté: Et existe-t-il une différence entre les méthodes offer et add ?

485voto

Jon Skeet Points 692016

Utiliser la surcharge du constructeur qui prend un Comparator<? super E> comparator et passer à un comparateur qui compare de manière appropriée pour votre ordre de tri. Si vous donner un exemple de la façon dont vous voulez trier, nous pouvons fournir un exemple de code pour mettre en œuvre le comparateur si vous n'êtes pas sûr. (C'est assez simple.)

Comme il a été dit ailleurs: - offer et add sont simplement différentes implémentations de la méthode de l'interface. Dans le JDK source que j'ai, add des appels offer. Bien qu' add et offer ont potentiellement des comportements différents en général, en raison de la capacité pour l' offer à indiquer que la valeur ne peut pas être ajouté en raison des limitations de taille, cette différence n'est pas pertinent en PriorityQueue qui est sans bornes.

Voici un exemple d'une file d'attente de priorité de tri par longueur de la chaîne:

// Test.java
import java.util.Comparator;
import java.util.PriorityQueue;

public class Test
{
    public static void main(String[] args)
    {
        Comparator<String> comparator = new StringLengthComparator();
        PriorityQueue<String> queue = 
            new PriorityQueue<String>(10, comparator);
        queue.add("short");
        queue.add("very long indeed");
        queue.add("medium");
        while (queue.size() != 0)
        {
            System.out.println(queue.remove());
        }
    }
}

// StringLengthComparator.java
import java.util.Comparator;

public class StringLengthComparator implements Comparator<String>
{
    @Override
    public int compare(String x, String y)
    {
        // Assume neither string 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;
    }
}

53voto

Vibha pandey Points 271

Pour la démonstration de l'utilisation de la File d'attente de Priorité,voici un exemple réel, où l'ordre des patients d'être traités par un médecin peut être déterminée en vérifiant si c'est un cas d'urgence ou pas.

Ci-dessous est le code pour le "Patient" de la classe:

package com 
public class Patient {

  private int id;

  private String name;

  private boolean emergencyCase;

  public Patient(int id, String name, boolean emergencyCase) {
    this.id = id;
    this.name = name;
    this.emergencyCase = emergencyCase;
 }

/**
 * @return the id
 */
public int getId() {
    return id;
}

/**
 * @param id the id to set
 */
public void setId(int id) {
    this.id = id;
}

/**
 * @return the name
 */
public String getName() {
    return name;
}

/**
 * @param name the name to set
 */
public void setName(String name) {
    this.name = name;
}

/**
 * @return the emergencyCase
 */
public boolean isEmergencyCase() {
    return emergencyCase;
}

/**
 * @param emergencyCase the emergencyCase to set
 */
 public void setEmergencyCase(boolean emergencyCase) {
    this.emergencyCase = emergencyCase;
 }
} 

Et ci-dessous est le code pour le test Patient file d'attente de priorité:

import com.Patient;
import java.util.Comparator;
import java.util.PriorityQueue;
public class PQueueTest {
public static void main(String[] args) {
    PriorityQueue<Patient> patientQueue = new PriorityQueue<Patient>(10, new Comparator<Patient>() {
        public int compare(Patient patient1, Patient patient2) {
            return (patient1.isEmergencyCase() == patient2.isEmergencyCase()) ? (Integer.valueOf(patient1.getId()).compareTo(patient2.getId()))
                                                                              : (patient1.isEmergencyCase() ? -1 : 1);
        }
    });

    patientQueue.add(new Patient(1, "Patient1", false));
    patientQueue.add(new Patient(2, "Patient2", false));
    patientQueue.add(new Patient(3, "Patient3", true));
    patientQueue.add(new Patient(4, "Patient4", false));
    patientQueue.add(new Patient(5, "Patient5", true));

    System.out.println();
    System.out.print("Doctor's waiting for patients  : ");
    while(true) {
        Patient currentPatient = patientQueue.poll();
        if(currentPatient == null) {
            break;
        }

        System.out.print(currentPatient.getName() + " <-- ");
    }
    System.out.println();
}
}

La sortie pour l'exemple ci-dessus est:

Doctor's waiting for patients : Patient3 <-- Patient5 <-- Patient1 <-- Patient2 <-- Patient4 <-- 

ajouter() par rapport à l'offre (le)

Est-il une différence entre la méthode add() et l'offre() la méthode? Non, pas vraiment. En fait, la méthode add() appels d'offre() directement – de sorte qu'il n'est pas question que celle que vous utilisez. Pour des raisons de cohérence, vous devriez coller avec un bien - n'est pas seulement au hasard parsemer ajouter()-s et de l'offre (le) s dans votre code.

26voto

dragonfly Points 1285

Il suffit de passer au approprié Comparator le constructeur:

PriorityQueue(int initialCapacity, Comparator<? super E> comparator)

La seule différence entre offer et add est l'interface à laquelle ils appartiennent. offer appartient Queue<E>, alors que add est à l'origine vu en Collection<E> interface. En dehors de cela deux méthodes font exactement la même chose - insérer l'élément spécifié dans la file d'attente de priorité.

19voto

Peter Points 4666

de l' API de file d' attente :

La méthode d'offre insère un élément si possible, sinon retourne false. Cela diffère de la méthode Collection.add, qui peut échouer à ajouter un élément uniquement 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 des files d'attente à capacité fixe (ou "délimitée").

15voto

Dickson Points 361

pas différent, comme le déclare javadoc:

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

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X