PriorityBlockingQueue in Java


Java PriorityBlockingQueueViews 1494

PriorityBlockingQueue in Java

The PriorityBlockingQueue is a class in Java that implements the BlockingQueue interface and extends the AbstractQueue class. It implements the concurrent BlockingQueue data structure. The working of a PriorityBlockingQueue is similar to a PriorityQueue but enforces a blocking retrieval operation. This means when we try to add elements when there is no resource, it will throw OutOfMemoryError. Similarly, we cannot remove elements when the queue is empty.

Features

  • We cannot store null values in a PriorityBlockingQueue.
  • It is unbounded and grows dynamically with an initial capacity of 11.
  • There is no guarantee that we can retrieve elements in a particular order using the iterator() or spliterator() methods.
  • To sort the elements we can either use the Arrays.sort or use custom classes or comparators.
  • The elements that we add in a PriorityBlockingQueue need to implement a Comparable interface else it will throw ClassCastException.
  • PriorityBlockingQueue in Java is thread-safe.
  • We can use the drainTo() method to remove the priority elements and store them in another collection.

Hierarchy

PriorityBlockingQueue in Java

Constructors of PriorityBlockingQueue in Java

ConstructorDescription
PriorityBlockingQueue()Creates a default empty PriorityBlockingQueue with capacity 11
PriorityBlockingQueue(Collection c)Creates a PriorityBlockingQueue with the specified elements in the collection
PriorityBlockingQueue(int initialCapacity)Creates an empty PriorityBlockingQueue with the specified initial capacity
PriorityBlockingQueue(int initialCapacity, Comparator c)Creates an empty PriorityBlockingQueue with the specified initial capacity and orders the elements based on the comparator

Methods of PriorityBlockingQueue in Java

MethodDescriptionParameter
Boolean add(String e)Adds the specified element to the end of the queuee - the element to be added.
Return value - True
Boolean addAll(Collection c)Adds a collection of specified elements to the queue.c - collection of elements to be added
Return value - true
void clear()Clears all the elements in the queue.
Comparator comparator()Returns the comparator to order the elements
Boolean contains(Object o)Checks if the queue contains the specified elementReturn value - true if the queue contains the element
Boolean containsAll(Collection c)Checks if the queue contains all the elements in the collectionReturn value - true if the queue contains all the elements
int drainTo(Collection c)Removes all the elements from the queue and adds it to the specified collectionc - Collection to which elements needs to be added
int drainTo(Collection c, int maxElements)Removes the specified maximum number of elements from the queue and adds to the specified collectionc - Collection to which elements needs to be added
maxElements - Maximum number of elements that can be transferred
Integer element()Returns the first element(head) in the queue
Boolean equals(Object o)Compares if the queue contains all the specified elements in the exact orderReturn value - true if object elements match with the queue
Boolean isEmpty()Checks if the queue is empty or notReturn value - true if queue contains no values
Iterator iterator()Retrieves the iterator of queue in sequenceReturn value - Iterator
Boolean offer(Integer e)Inserts the specified element as the taile - element to be added
Boolean offer(Integer e, long timeout, TimeUnit unit)Inserts the specified element to the queuee - element to be added
Integer peek()Retrieves the first element of the queue(head)Returns null if the queue is empty
Integer poll()Retrieves and removes the first element of the queue(head)Returns null if the queue is empty
Integer poll(long timeout, TimeUnit unit)Retrieves and removes the head element from the queue by waiting for the specified time if the element is unavailabletimeout - waiting time
void put(Integer e)Inserts the specified element to the queuee - element to be inserted
int remainingCapacity()Returns the Integer.MAX_VALUE
Integer remove()Removes the first element from the queue
Boolean remove(Object o)Removes the first occurrence of the specified object from the queue if presento - The element that needs to be removed
Return value - true if queue contains the element
Boolean removeAll(Collection c)Removes the first occurrence of all the elements in the collection from the queue if presentc - collection of elements
Return value - true if the queue contains the collection
Boolean retainAll(Collection c)Retains all the elements specified in collection in queue. Other elements will be removedc - collection of elements that has to be retained
Return value - true if the queue changed due to the method called
int size()Fetches the size of the queueReturn value - size of the queue
Spliterator spliterator()Returns a spliterator over the elements in the queue
Integer take()Retrieves and removes the head of the queue
Object[] toArray()Returns an array of elements in proper sequenceReturn value - Array of all elements in the queue in proper sequence
String toString()Returns a String representation of the elements collectionReturn value - String of array elements separated by comma and space and enclosed within []

Example: Add elements to PriorityBlockingQueue

The below example shows how to add elements to a PriorityBlockingQueue in Java. We can insert values using the add(), offer() or put() method whereas to insert a collection of values, we can use the addAll() method.

import java.util.concurrent.PriorityBlockingQueue;

public class AddElementsPriorityBlockingQueue {

  public static void main(String[] args) {
    PriorityBlockingQueue<Integer> pb = new PriorityBlockingQueue<Integer>();
    pb.add(30);
    pb.add(50);
    pb.add(10);
    
    System.out.println("Elements in PriorityBlockingQueue after add: " + pb);
    
    PriorityBlockingQueue<Integer> pbq = new PriorityBlockingQueue<Integer>();
    pbq.add(70);
    pbq.add(90);
    
    pb.addAll(pbq);
    
    System.out.println("Elements in PriorityBlockingQueue after addAll: " + pb);
    
    pb.put(100);
    System.out.println("Elements in PriorityBlockingQueue after put: " + pb);

    pb.offer(110);
    System.out.println("Elements in PriorityBlockingQueue after offer: " + pb);
    
  }

}
Elements in PriorityBlockingQueue after add: [10, 50, 30]
Elements in PriorityBlockingQueue after addAll: [10, 50, 30, 70, 90]
Elements in PriorityBlockingQueue after put: [10, 50, 30, 70, 90, 100]
Elements in PriorityBlockingQueue after offer: [10, 50, 30, 70, 90, 100, 110]

Example: Remove elements from PriorityBlockingQueue

In the below example, we show how to delete elements using the remove() method. We can also remove the head element using the poll() method. To retain only the collection of elements and delete other elements, we can use the retainAll() method whereas to remove all the collection elements, we can use the removeAll() method.

import java.util.concurrent.PriorityBlockingQueue;

public class DeleteElementsPriorityBlockingQueue throws InterruptedException {

  public static void main(String[] args) {
    PriorityBlockingQueue<Integer> pb = new PriorityBlockingQueue<Integer>();
    pb.add(30);
    pb.add(50);
    pb.add(10);
    
    PriorityBlockingQueue<Integer> pbq = new PriorityBlockingQueue<Integer>();
    pbq.add(70);
    pbq.add(90);
    pbq.add(100);
    
    pb.addAll(pbq);
    
    System.out.println("Elements in PriorityBlockingQueue after add: " + pb);
    
    pb.remove();
    pb.remove(90);
    System.out.println("Elements in PriorityBlockingQueue after remove: " + pb);
    
    Integer val = pb.poll();
    System.out.println("Removed element using poll: " + val);

    Integer value = pb.take();
    System.out.println("Removed element using take: " + value);
    
    pb.retainAll(pbq);
    System.out.println("Elements in PriorityBlockingQueue after retainAll: " + pb);
    
    pb.removeAll(pbq);
    System.out.println("Elements in PriorityBlockingQueue after removeAll: " + pb);
  }

}
Elements in PriorityBlockingQueue after add: [10, 50, 30, 70, 90, 100]
Elements in PriorityBlockingQueue after remove: [30, 50, 100, 70]
Removed element using poll: 30
Removed element using take: 50
Elements in PriorityBlockingQueue after retainAll: [70, 100]
Elements in PriorityBlockingQueue after removeAll: []

Example: Access elements in PriorityBlockingQueue

To check if a particular value exists in the PriorityBlockingQueue, we can use the contains() method whereas to check the existence of a collection of elements, we can use the containsAll() method. In the below example, we can see how to retrieve the head element using the element() and peek() methods.

import java.util.concurrent.PriorityBlockingQueue;

public class AccessElementsPBQ {

  public static void main(String[] args) {
    PriorityBlockingQueue<Integer> pb = new PriorityBlockingQueue<Integer>();
    pb.add(30);
    pb.add(50);
    pb.add(10);
    pb.add(20);
    pb.add(40);
    
    PriorityBlockingQueue<Integer> pbq = new PriorityBlockingQueue<Integer>();
    pbq.add(70);
    pbq.add(90);
    
    pb.addAll(pbq);
    
    System.out.println(pb.contains(100));
    System.out.println(pb.contains(20));
    System.out.println(pb.containsAll(pbq));
    
    System.out.println("Head element using the element() method: " + pb.element());
    System.out.println("Head element using the peek method: " + pb.peek());
    
  
  }

}
false
true
true
Head element using the element() method: 10
Head element using the peek method: 10

Example: Iterate over PriorityBlockingQueue

We can traverse through all values in a PriorityBlockingQueue in Java using the iterator() method.

import java.util.Iterator;
import java.util.concurrent.PriorityBlockingQueue;

public class IteratePBQ {

  public static void main(String[] args) {
    PriorityBlockingQueue<Integer> pb = new PriorityBlockingQueue<Integer>();
    pb.add(30);
    pb.add(50);
    pb.add(10);
    pb.add(20);
    pb.add(40);
    
    //Using iterator
    System.out.println("Using iterator:");
    Iterator<Integer> i = pb.iterator();
    
    while(i.hasNext())
      System.out.println(i.next());
    
  }

}
Using iterator:
10
20
30
50
40

Example: drainTo() method

Below is an example of how to remove elements from one collection and transfer them to another collection using the drainTo() method. We can notice that the first queue pb is empty after using the drainTo() method and the second queue pbq is filled with values of pb.

import java.util.concurrent.PriorityBlockingQueue;

public class drainToDemo {

  public static void main(String[] args) {
    PriorityBlockingQueue<Integer> pb = new PriorityBlockingQueue<Integer>();
    pb.add(30);
    pb.add(50);
    pb.add(10);
    pb.add(20);
    pb.add(40);
    
    PriorityBlockingQueue<Integer> pbq = new PriorityBlockingQueue<Integer>();
    pb.drainTo(pbq);
    
    System.out.println("Elements in the first collection: " + pb);
    System.out.println("Elements in the second collection: " + pbq);

  }

}
Elements in the first collection: []
Elements in the second collection: [10, 20, 30, 40, 50]

Example: Using comparator in PriorityBlockingQueue

We can order the elements in the PriorityQueue based on a custom comparator. In the below example, we create a custom comparator that returns the highest element as the head.

import java.util.Comparator;
import java.util.concurrent.PriorityBlockingQueue;

public class ComparatorPBQ {

  public static void main(String[] args) {
    PriorityBlockingQueue<Integer> pb = new PriorityBlockingQueue<Integer>(5, new SampleComparator());
    pb.add(30);
    pb.add(50);
    pb.add(10);
    pb.add(20);
    pb.add(40);
    
    System.out.println(pb);
    

  }

}

Comparator.java

import java.util.Comparator;
public class SampleComparator implements Comparator<Integer> {

  @Override
  public int compare(Integer x, Integer y) {
    if(x < y)
      return 1;
    else
      return -1;
  }

}
[50, 40, 10, 20, 30]

Example: Blocking retrieval operation

Below is an example to demonstrate the blocking retrieval operation using the PriorityBlockingQueue. When a new thread starts, it waits for a second before printing every integer value. The take() method, retrieves and removes the element by waiting for the value for the specified time.

import java.util.concurrent.PriorityBlockingQueue;
import java.util.concurrent.TimeUnit;

public class BlockingRetrievalDemo {

  public static void main(String[] args) throws InterruptedException {
    PriorityBlockingQueue<Integer> pb = new PriorityBlockingQueue<Integer>();
    new Thread(() ->
    {
      System.out.println("Waiting...");
      
      try {
        while(true) {
          Integer t = pb.take();
          System.out.println("Value: " + t);
          
          Thread.sleep(TimeUnit.SECONDS.toMillis(1));
        }
      }
      catch(Exception e) {
        e.printStackTrace();
      }
    }
    ).start();
    
    Thread.sleep(TimeUnit.SECONDS.toMillis(2));
    pb.add(10);
    
    Thread.sleep(TimeUnit.SECONDS.toMillis(2));
    pb.add(20);
    
    Thread.sleep(TimeUnit.SECONDS.toMillis(2));
    pb.add(30);
  }

}
Waiting...
Value: 10
Value: 20
Value: 30

Example: Creating a PriorityBlockingQueue from a Collection

The below example shows how to create a PriorityBlockingQueue from a LinkedList Collection. We can see that there is a difference in the order it lists the values in a LinkedList and PriorityBlockingQueue.

import java.util.LinkedList;
import java.util.concurrent.PriorityBlockingQueue;

public class PBQCollection {

  public static void main(String[] args) {
    LinkedList<Integer> l = new LinkedList<Integer>();
    l.add(10);
    l.add(80);
    l.add(40);
    l.add(20);
    l.add(30);
    System.out.println("Elements in LinkedList: " + l);
    
    PriorityBlockingQueue<Integer> p = new PriorityBlockingQueue<Integer>(l);
    System.out.println("Elements in PriorityBlockingQueue: " + p);
    

  }

}
Elements in LinkedList: [10, 80, 40, 20, 30]
Elements in PriorityBlockingQueue: [10, 20, 40, 80, 30]

Example: Sorting using Inbuilt comparator

We can sort the values in a PriorityBlockingQueue in Java using the built-in comparator. In the below example, we print the values in the reverse order using the Comparator built-in method reverseOrder().

import java.util.Comparator;
import java.util.concurrent.PriorityBlockingQueue;

public class ComparatorPBQDemo {

  public static void main(String[] args) {
    PriorityBlockingQueue<Integer> pbq = new PriorityBlockingQueue<Integer>(5, Comparator.reverseOrder());
    
    pbq.add(20);
    pbq.add(40);
    pbq.add(60);
    pbq.add(80);
    pbq.add(100);
    
    System.out.println(pbq);
  }

}
[100, 80, 40, 20, 60]

 

Reference

Translate ยป