I'm trying to implement a heap using a PriorityQueue as follows:
PriorityQueue<Node> heap = new PriorityQueue<Node>();
Set<String> allWords = codebook.getAllWords();
for(String word : allWords)
{
heap.add(new Node(word, codebook.getProbability(word)));
System.out.println(heap.toString());
}
Where I've defined Node as as private class inside the same class that holds the above method. Node is defined as:
private static class Node implements Comparable
{
protected Node left;
protected Node right;
protected String name;
protected double frequency;
public Node(String n, double f)
{
name = n;
frequency = f;
}
public Node(double f, Node l, Node r)
{
frequency = f;
left = l;
right = r;
}
@Override
public int compareTo(Object arg0)
{
Node other = (Node)(arg0);
if(this.frequency < other.frequency)
{
System.out.println(name + " < " + other.name);
return -1;
}
else if(this.frequency > other.frequency)
{
System.out.println(name + " > " + other.name);
return 1;
}
System.out.println(name + " is equal to " + other.name);
return 0;
}
public String toString()
{return name;}
}
However, when I add nodes to the PriorityQueue, they are not ordered by frequency. Based on output from my println statements, the correct values are returned by Node.compareTo(). For example, given the dataset:
My code produces:
// add need
[need]
// add cat
cat < need
[cat, need]
// add neat
neat > cat
[cat, need, neat]
when the PriorityQueue should be [cat, neat, need]
Any tips as to why this is happening?
The order from an iterator for PriorityQueue
is undefined; the order when calling poll()
should be the comparator ordering. From the API spec,
iterator()
Returns an iterator over the elements in this queue. The iterator does not return the elements in any particular order.
If what you really need is a sorted set, use SortedSet
OR put things into a collection and use Collections.sort()
. If, however, you really need a pqueue, here's my example fix:
import java.util.HashMap;
import java.util.Map;
import java.util.PriorityQueue;
import java.util.Set;
public class TestPriorityQueue
{
static Map<String,Double> codebook = new HashMap<String, Double>();
static {
codebook.put("need", 3.0);
codebook.put("cat", 1.0);
codebook.put("neat", 2.0);
}
public static void main(String[] args)
{
test();
}
public static void test() {
PriorityQueue<Node> heap = new PriorityQueue<Node>();
Set<String> allWords = codebook.keySet();
for (String word : allWords) {
heap.add(new Node(word, codebook.get(word)));
System.out.println(heap.toString());
}
System.out.println("In order now:");
while(!heap.isEmpty()) {
System.out.println(heap.poll());
}
}
private static class Node implements Comparable<Node>
{
protected Node left;
protected Node right;
protected String name;
protected double frequency;
public Node(String n, double f)
{
name = n;
frequency = f;
}
public Node(double f, Node l, Node r)
{
frequency = f;
left = l;
right = r;
}
@Override
public int compareTo(Node arg0)
{
if(this.frequency < arg0.frequency)
{
System.out.println(name + " < " + arg0.name);
return -1;
}
else if(this.frequency > arg0.frequency)
{
System.out.println(name + " > " + arg0.name);
return 1;
}
System.out.println(name + " is equal to " + arg0.name);
return 0;
}
public String toString()
{return name;}
}
}
Gives:
[need]
cat < need
[cat, need]
neat > cat
[cat, need, neat]
In order now:
neat < need
cat
neat
need