82

Why did they name PriorityQueue if you can't insertWithPriority? It seems very similar to a heap. Are there any differences? If no difference, then why was it named PriorityQueue and not Heap?

roottraveller
  • 7,942
  • 7
  • 60
  • 65
Jeff Chen
  • 895
  • 1
  • 7
  • 9
  • 18
    I'm not sure if it differs from a min-heap, but generally Java Objects are named based on the functionality they provide, not named based on how they are implemented. – Daniel May 19 '11 at 22:54
  • 1
    @Daniel Ok that explains why it's not called a heap, but why is it called a PriorityQueue if it does not support the functionality of a priority queue? – Jeff Chen May 19 '11 at 22:58
  • 9
    It _does_ support the functionality of a priority queue. – Matt Ball May 19 '11 at 23:04
  • `min-heap` and `max-heap` are both `priority queue`, it depends on how you define the order of priority. That is to say, a priority queue can be a min-heap or a max-heap in your algorithm. – Yossarian42 Nov 02 '19 at 21:50

7 Answers7

112

The default PriorityQueue is implemented with Min-Heap, that is the top element is the minimum one in the heap.

In order to implement a max-heap, you can create your own Comparator:

import java.util.Comparator;

public class MyComparator implements Comparator<Integer>
{
    public int compare( Integer x, Integer y )
    {
        return y - x;
    }
}

So, you can create a min-heap and max-heap in the following way:

PriorityQueue minHeap=new PriorityQueue();
PriorityQueue maxHeap=new PriorityQueue(size, new MyComparator());
spiralmoon
  • 3,084
  • 2
  • 25
  • 26
  • 4
    exactly it's a min-heap because the default sort order is ascending – stivlo Jan 22 '14 at 11:31
  • 2
    @ThinkRecursively doing a `minus` to get a reverse comparator is a terrible idea – Eugene Oct 02 '18 at 19:55
  • 7
    Easier max-heap: `Queue maxHeap = new PriorityQueue(Collections.reverseOrder());` as [since 1.8](https://docs.oracle.com/javase/8/docs/api/java/util/PriorityQueue.html), you can just pass in the Comparator without needing to pass in the initial capacity. – Neil P. Mar 04 '19 at 16:39
  • 2
    Using `y - x` as a comparator is broken, as it can overflow. The safe solution `Collections.reverseOrder()` exists since Java 1.2. – Holger Mar 13 '19 at 08:30
  • 4
    @Neil when you use Java 8, you can use `new PriorityQueue<>(Collections.reverseOrder())` (use the “diamond operator”). – Holger Mar 13 '19 at 08:31
  • how does collections.reverseOrder work? and how will y-x work , can you explain what it does? @spiralmoon – Rohan Devaki Jan 03 '22 at 07:51
61

For max-heap you can use:

PriorityQueue<Integer> queue = new PriorityQueue<>(10, Collections.reverseOrder());
Hengameh
  • 892
  • 7
  • 12
  • 14
    [Since 1.8](https://docs.oracle.com/javase/8/docs/api/java/util/PriorityQueue.html), you can just pass in the Comparator without needing to pass in the initial capacity: `Queue maxHeap = new PriorityQueue(Collections.reverseOrder());` – Neil P. Mar 04 '19 at 16:38
35

Add() works like an insertWithPriority.

You can define priority for the type that you want using the constructor:

PriorityQueue(int, java.util.Comparator)

look under https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/util/PriorityQueue.html

The order the Comparator gives will represent the priority in the queue.

Sumiya
  • 317
  • 4
  • 5
Marcelo
  • 11,218
  • 1
  • 37
  • 51
9

Default behaviour as described in other answers

Min Heap(Default):

PriorityQueue<Integer> priorityQueue = new PriorityQueue<>();

For Max Heap:

PriorityQueue<Integer> priorityQueue = new PriorityQueue<>((o1, o2) -> o2-o1);
GauravRatnawat
  • 717
  • 1
  • 11
  • 25
6

From Java docs

Priority queue represented as a balanced binary heap: the two children of queue[n] are queue[2*n+1] and queue[2*(n+1)]. The priority queue is ordered by comparator, or by the elements' natural ordering.


Here is a working code for maxHeap and minHeap using PriorityQueue -

class HeapDemo {
    private final static int HEAP_SIZE = 10; //size of heap

    //INNER CLASS
    static class maxHeapComparator implements Comparator<Integer> {
        @Override
        public int compare (Integer x, Integer y) {
            return y-x; //reverse order
        }
    }

    public static void main(String[] args) {
        PriorityQueue<Integer> minHeap = new PriorityQueue<>(HeapDemo.HEAP_SIZE); 
        PriorityQueue<Integer> maxHeap = new PriorityQueue<>(HeapDemo.HEAP_SIZE, new maxHeapComparator());  

        for(int i=1; i<=HeapDemo.HEAP_SIZE; ++i){
            int data = new Random().nextInt(100) +1; //number between 0 to 100
            minHeap.add(data);
            maxHeap.add(data);
        }

        System.out.print("\nMIN Heap : ");
        Iterator<Integer> iter = minHeap.iterator();
        while(iter.hasNext()){
            System.out.print(iter.next() + " ");
        }

        System.out.print("\nMAX Heap : ");
        iter = maxHeap.iterator();
        while(iter.hasNext()) {
            System.out.print(iter.next() + " ");
        }
    }
}

sample o/p :

MIN Heap : 20 32 37 41 53 91 41 98 47 86 
MAX Heap : 98 91 41 53 86 20 37 41 32 47 
roottraveller
  • 7,942
  • 7
  • 60
  • 65
  • As with all other answers, using `y - x` as a comparator is broken, as it can overflow. The safe solution `Collections.reverseOrder()` exists since Java 1.2. – Holger Mar 13 '19 at 08:33
6

From the PriorityQueue JavaDocs:

An unbounded priority queue based on a priority heap. The elements of the priority queue are ordered according to their natural ordering, or by a Comparator provided at queue construction time, depending on which constructor is used.

Priority is meant to be an inherent property of the objects in the queue. The elements are ordered based on some sort of comparison. To insert some object with a given priority, you would just set whatever field(s) on the object affect the ordering, and add() it.


And, as @Daniel commented,

Generally Java Objects are named based on the functionality they provide, not named based on how they are implemented.

Community
  • 1
  • 1
Matt Ball
  • 354,903
  • 100
  • 647
  • 710
3

From http://docs.oracle.com/javase/7/docs/api/java/util/PriorityQueue.html

An unbounded priority queue based on a priority heap. The elements of the priority queue are ordered according to their natural ordering, or by a Comparator provided at queue construction time

for integer, long, float, double, character, boolean (i.e. primitive data types) the natural ordering is ascending order, that's why Arrays.sort(arr) {where arr is an array of primitive data type} sorts the value of arr in ascending order. You can change the natural ordering by using a Comparator

Comparator can be used in two ways either

Arrays.sort(arr, new Comparator<Integer>() {
     public int compare(Integer x, Integer y) {
         return y - x;
     }
});
  • If you have java8 then you can use the lambda expression

Arrays.sort(arr, (Integer x, Integer y) -> y - x);

This sorts the array arr in descending order

Jared Burrows
  • 54,294
  • 25
  • 151
  • 185
Anupam Ghosh
  • 314
  • 3
  • 10
  • 3
    Using `y - x` as a comparator is broken, as it can overflow. The safe solution `Collections.reverseOrder()` exists since Java 1.2. – Holger Mar 13 '19 at 08:32
  • @Holger, excellent point about overlfow. worth adding to SonarCube rules – Vortex Jan 27 '22 at 18:54