views:

11433

answers:

2

How do I get a PriorityQueue to sort on what I want it to sort on?

Added: And is there a difference between the offer and add methods?

+6  A: 

Use the constructor overload which takes a Comparator<? super E> comparator and pass in a comparator which compares in the appropriate way for your sort order. If you give an example of how you want to sort, we can provide some sample code to implement the comparator if you're not sure. (It's pretty straightforward though.)

As has been said elsewhere: offer and add are just different interface method implementations. In the JDK source I've got, add calls offer.

Here's an example of a priority queue sorting by string length:

// 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
        if (x.length() < y.length())
        {
            return -1;
        }
        if (x.length() > y.length())
        {
            return 1;
        }
        return 0;
    }
}
Jon Skeet
yes please. kind of rusty on Java... =/
Svish
Great example! Thanks =)
Svish
Hmm... just noticed... priorityQueue.comparator() "Returns the comparator used to order this collection, or null if this collection is sorted according to its elements natural ordering (using Comparable)." Does that mean I could just implement Comparable on my class as well?
Svish
Yes if you implement comparable in your class that would work as well
zPesk
You could, yes. I wouldn't do so unless there's a single natural sort order for your class though. If there is, that's the right thing to do :)
Jon Skeet
+3  A: 

Just pass appropriate Comparator to the constructor:

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

The only difference between offer and add is the interface they belong to. offer belongs to Queue<E>, whereas add is originally seen in Collection<E> interface. Apart from that both methods do exactly the same thing - insert the specified element into priority queue.

dragonfly
Thanks for clearing up offer and add methods =)
Svish
Specifically, add() throws an exception if capacity restrictions prevent the item from being added to the queue while offer returns false. Since PriorityQueues do not have a maximum capacity, the difference is moot.
James