HOWTO · Java

How to Get Maximum Value From A Priority queue in Java

This tutorial demonstrates how to get maximum value from a priority queue in Java.

On this page

To make a max-priority queue in Java, construct a PriorityQueue with a comparator that reverses the values’ natural ordering. Its head is then the greatest element, and repeated calls to poll() remove elements from greatest to least. Java’s default PriorityQueue is a min-heap, so without a comparator its head is the least element.

What Is a Priority Queue in Java

A priority queue retrieves elements according to priority rather than insertion order. It is not a FIFO queue: an element inserted later can be returned first if its priority ranks ahead of the other elements. With natural ordering, the priority is the value’s Comparable order; a comparator supplies a different ordering when needed.

Java’s PriorityQueue is heap-based and provides efficient access to its head. Adding and removing an element take logarithmic time, while inspecting the head with peek() takes constant time. The class is not thread-safe. For concurrent use, consider PriorityBlockingQueue from java.util.concurrent and review its distinct concurrency behavior.

How Java’s PriorityQueue Orders Elements

The ordering rule determines which element is at the head. With the default constructor, integers and strings use natural ordering, so the smallest value is at the head. A comparator can reverse that order or compare a field on a custom object.

A heap does not keep every element in sorted sequence. Its iterator visits the internal heap structure, so iterating a PriorityQueue does not guarantee sorted output. Use peek() to inspect the current head, or repeatedly remove the head when you need values in priority order.

Create a Max-Priority Queue for Natural-Order Values

For integer values, pass a comparator that compares the right operand with the left. The same pattern works for other naturally ordered values such as strings. The queue arranges its head according to the comparator as values are inserted; you do not need to sort the inputs first.

Run this example:

import java.util.PriorityQueue;

public class Main {
    public static void main(String[] args) {
        PriorityQueue<Integer> values = new PriorityQueue<>((left, right) -> {
            if (left < right) return 1;
            if (left > right) return -1;
            return 0;
        });
        values.add(20);
        values.add(10);
        values.add(30);

        System.out.println(values.poll());
        System.out.println(values.poll());
        System.out.println(values.poll());
    }
}

The comparison branches reverse the natural integer order without subtracting values, which could overflow for extreme integers. The queue’s head is the greatest value under this comparator. Each poll() removes that head, so draining the queue produces values in descending order.

For strings, the comparison can use right.compareTo(left) to reverse their natural lexicographic order. This means “maximum” is defined by the value type’s ordering rule; it does not mean longest string or a domain-specific ranking unless the comparator defines that rule.

Order Custom Objects by Priority

A custom object can be ordered by one of its fields. For example, if a Task has an integer priority, compare the right task’s priority with the left task’s priority using explicit less-than and greater-than branches, then return zero when they match. This places tasks with larger priority numbers at the head without arithmetic subtraction.

A comparator must be consistent: if it reports two objects as equal in priority, either may be returned first. A priority queue does not promise stable ordering among ties. Add a secondary comparison, such as a sequence number, when the application needs a defined order for equal-priority tasks.

Retrieve Maximum Elements and Avoid Ordering Pitfalls

Use peek() to view the maximum without removing it. Use poll() to remove and return the current maximum. When the queue has no elements, peek() and poll() return null; check for that result or check isEmpty() before relying on a returned value. Repeatedly calling poll() until it returns null drains the queue in comparator order.

Do not use iteration as a sorted traversal, and do not describe the queue itself as sorted. The comparator controls the head and subsequent removal order. For a max-priority queue, reverse the natural or field-based comparison safely, and use a concurrent queue implementation when multiple threads need to modify the structure.