We are about to switch to a new forum software. Until then we have removed the registration on this forum.
I couldn't find good examples of an implementation of PriorityQueue
for Processing and some of the online Java examples aren't great and/or are misleading. So, here's an example of how to use a PriorityQueue
and implement the required compareTo
method on a custom class.
import java.util.PriorityQueue;
public class FancyClass implements Comparable {
// Required when implementing Comparable
public int compareTo(FancyClass other) {
return this.somenumber.compareTo(other.somenumber);
}
// This must be an Integer and not an int primitive
// or compareTo will throw an exception.
Integer somenumber;
String name;
FancyClass(String _name) {
name = _name;
}
// Custom print value for the class
public String toString() {
return name + ": " + somenumber;
}
}
FancyClass fc1, fc2, fc3, fc4;
PriorityQueue pq;
void setup() {
fc1 = new FancyClass("fc1");
fc2 = new FancyClass("fc2");
fc3 = new FancyClass("fc3");
fc4 = new FancyClass("fc4");
fc1.somenumber = 12;
fc2.somenumber = -1;
fc3.somenumber = 7;
fc4.somenumber = 99;
// Here we do not need to implement a comparator because FancyClass implements Comparable
// and the compareTo method, which is the "natural ordering" for the FancyClass class.
// The 5 is simply the capacity of the priority queue.
pq = new PriorityQueue(5);
// offer() and add() are the same for PriorityQueue
pq.offer(fc1);
pq.offer(fc2);
pq.offer(fc3);
pq.offer(fc4);
}
void draw() {
// Note, this will NOT print them in order!!
println(pq);
// You can only get them in order by polling the queue.
while (!pq.isEmpty ()) {
println("Item: " + pq.poll());
}
noLoop();
}
The output:
[fc2: -1, fc1: 12, fc3: 7, fc4: 99] Item: fc2: -1 Item: fc3: 7 Item: fc1: 12 Item: fc4: 99
There's another way to do this if you don't want the compareTo
method in your class. You write a Comparator
, which requires importing another Java library. You then can provide the Comparator
as a parameter to PriorityQueue
, effectively allowing you to have many different ways for comparing objects of the same class.
import java.util.PriorityQueue;
import java.util.Comparator;
public class FancyClass {
// This doesn't need to be an Integer in this case
int somenumber;
int someothernumber;
String name;
FancyClass(String _name) {
name = _name;
}
// Custom print value for the class
public String toString() {
return name + ", somenumber:" + somenumber + ", someothernumber: " + someothernumber;
}
}
// The Comparators that look at different numbers in FancyClass
static class FancySortOne implements Comparator {
public int compare(FancyClass one, FancyClass two) {
return one.somenumber - two.somenumber;
}
}
static class FancySortTwo implements Comparator {
public int compare(FancyClass one, FancyClass two) {
// Note the difference
return one.someothernumber - two.someothernumber;
}
}
FancyClass fc1, fc2, fc3, fc4;
PriorityQueue pq, pq2;
void setup() {
fc1 = new FancyClass("fc1");
fc2 = new FancyClass("fc2");
fc3 = new FancyClass("fc3");
fc4 = new FancyClass("fc4");
fc1.somenumber = 12;
fc2.somenumber = -1;
fc3.somenumber = 7;
fc4.somenumber = 99;
fc1.someothernumber = 2;
fc2.someothernumber = 17;
fc3.someothernumber = 79;
fc4.someothernumber = 4;
FancySortOne fs1 = new FancySortOne();
FancySortTwo fs2 = new FancySortTwo();
// Provide the Comparator as a parameter
pq = new PriorityQueue(5, fs1);
pq2 = new PriorityQueue(5, fs2);
// offer() and add() are the same for PriorityQueue
pq.offer(fc1);
pq.offer(fc2);
pq.offer(fc3);
pq.offer(fc4);
pq2.offer(fc1);
pq2.offer(fc2);
pq2.offer(fc3);
pq2.offer(fc4);
}
void draw() {
// Note, this will NOT print them in order!!
println(pq);
// You can only get them in order by polling the queue.
while (!pq.isEmpty ()) {
println("Item: " + pq.poll());
}
// Now look at the other comparator
println("\n------------------------------------------\n");
// Note, this will NOT print them in order!!
println(pq2);
// You can only get them in order by polling the queue.
while (!pq2.isEmpty ()) {
println("Item: " + pq2.poll());
}
noLoop();
}
The output:
[fc2, somenumber:-1, someothernumber: 17, fc1, somenumber:12, someothernumber: 2, fc3, somenumber:7, someothernumber: 79, fc4, somenumber:99, someothernumber: 4] Item: fc2, somenumber:-1, someothernumber: 17 Item: fc3, somenumber:7, someothernumber: 79 Item: fc1, somenumber:12, someothernumber: 2 Item: fc4, somenumber:99, someothernumber: 4 ------------------------------------------ [fc1, somenumber:12, someothernumber: 2, fc4, somenumber:99, someothernumber: 4, fc3, somenumber:7, someothernumber: 79, fc2, somenumber:-1, someothernumber: 17] Item: fc1, somenumber:12, someothernumber: 2 Item: fc4, somenumber:99, someothernumber: 4 Item: fc2, somenumber:-1, someothernumber: 17 Item: fc3, somenumber:7, someothernumber: 79
Comments
I'm back just to highlight that we don't need a formal class in order to instantiate an
interface
.We can do instead an anonymous instantiation as long as we provide implementation for each demanded
abstract
method on it: :DCool, thanks for the additions and efficiencies! I tend to try to be as explicit as possible when I write examples for myself, else I spend too much time trying to understand loops, etc. :D
For what it's worth, I was implementing A* and wanted a
PriorityQueue
so that I could explore the frontier more efficiently.