I’m trying to understand how to properly use a PriorityQueue in Java and how to make it sort elements based on my custom criteria. By default, it seems to sort elements in natural order, but what if I want to define my own sorting logic?
Also, while looking through the documentation, I noticed both the offer() and add() methods. Is there any difference between them, or are they interchangeable?
If you want to customize sorting without creating a separate class, you can use an anonymous comparator like this:
PriorityQueue<Integer> pq = new PriorityQueue<>((a, b) -> b - a); // Max-Heap
pq.add(10);
pq.add(20);
pq.add(5);
System.out.println(pq.poll()); // Outputs 20 (highest first)
Here, we override the default natural ordering using a lambda function. This turns it into a Max-Heap where the highest value comes out first.
If your PriorityQueue is working with complex objects, like a Person, defining a separate Comparator class makes things cleaner and reusable:
class Person {
String name;
int age;
Person(String name, int age) {
this.name = name;
this.age = age;
}
}
class AgeComparator implements Comparator<Person> {
@Override
public int compare(Person p1, Person p2) {
return Integer.compare(p1.age, p2.age); // Sort by age (ascending)
}
}
// Usage:
PriorityQueue<Person> pq = new PriorityQueue<>(new AgeComparator());
pq.add(new Person("Alice", 30));
pq.add(new Person("Bob", 25));
System.out.println(pq.poll().name); // Outputs "Bob" (youngest first)
This makes the sorting logic reusable and improves readability.
If your class implements Comparable, or you use Comparator.comparing(), it simplifies things:
PriorityQueue<Person> pq = new PriorityQueue<>(Comparator.comparing(p -> p.age));
This sorts the PriorityQueue based on age in ascending order.