Tuesday, May 31, 2022

How to use Queue Interface in Java? Example Tutorial

The JDK provides an implementation of several data structures in the Java collection framework like ArrayList is a dynamic array, LinkedList represents a linked list, HashMap represents a hash table data structure, and Queue interface represent queue data structure. Btw, If you are not familiar with data structure itself, then you can also see Introduction to Data Structures & Algorithms in Java, an excellent course to start with the essential data structure in Java. The Queue data structure allows you to process elements in the first in first out order, and that's why it is also known as a FIFO data structure. 

In order to provide "FIRST IN FIRST OUT" functionality, it allows you to insert data at one end and delete data from other ends, also known as consuming data. If you need to process objects in the FIFO order, you can use a Queue to store them.

Since Queue is an interface, you cannot use it directly, either you need to use its implementation classes. JDK provides two implementations of the Queue interface, a PriorityQueue and LinkedList.

A PriorityQueue allows you to consume elements based upon their priority, very useful to implement a TODO list where the highest priority item should always be at the head and consumed first. On the other hand, LinkedList is a classical linked list, but you can use it as Queue as well.

In order to use Queue, you need to be familiar with essential methods to perform basic operations, like adding elements into a queue, consuming elements from a queue, or checking elements without consuming.

Any Queue implementation provides two sets of a method to perform this basic operation, the first set of methods are derived from java.util.Collection interface because Queue is also a Collection and second set of methods is added to simulate queue data structure behavior.

For example, to add an element to the Queue you can use either add() or offer() method and to remove an element you can use remove() or poll() methods. The only difference between the two sets of the method is that methods from Collection throw Exception when they fail but other sets of methods, like offer(), poll(), and peek() return null or false when they fail.

If you are not familiar with the Java Collection framework or Java in general then  I highly recommend you to join a comprehensive Java course to learn in a structured manner. If you need a reference, I recommendThe Complete Java Master Class by Tim Buchalka on Udemy. This 80+ hour online course is great to learn Java online from scratch. 





Important methods from Queue Interface in Java

Let's see some of the essential methods from the Queue interface to perform basic operations. As I told you before, methods are divided into two categories, one which throws Exception and others which return null or false. You can use the one which suits your requirements.


Methods that throws an exception when Fail

Add (E e): inserts the element e to the tail of the queue. If there is no space available because of capacity restrictions, IllegalStateException is thrown.

remove(): removes and returns the head (the first element) of the queue. If the queue is empty, NoSuchElementException is thrown.

element(): just returns the head of the queue, without removing it. If the queue is empty, again NoSuchElementException is thrown.


How to use Queue in Java -  Example Tutorial



Methods that Returns special value on Failure

offer(E e): adds the element e to the tail of the queue. If the insertion is successful, the method returns true; otherwise, it returns false. Generally, if there are capacity bounds, it is preferred to use add method instead.

poll(): like the remove() function, it retrieves and removes the head of the queue. The only difference from remove() is that poll() operation returns null when the queue is empty.

peek(): just like element() operation it retrieves and returns the head of the queue, without removing it. In this situation, when the queue is empty, it returns null.

I generally prefer to use the methods from the Queue interface, i.e. offer, poll, and peek because they don't fail with Exception and they improve readability.  If you see add() you are not sure whether you are dealing with a Queue or Collection, but if you see the offer(), you know that you are dealing with a Queue.

Btw, If you haven't read it yet then read Effective Java 3rd edition for more of such practical tips on Java programming.




How to use Queue in Java - Example

Here is a simple example of using the Queue interface in Java. This class behaves the same as Queue data structure like you can do FIFO processing.  If you understand that it would be very easy to use this interface and its different implementation classes like PriorityQueue, LinkedList, and others.

import java.util.LinkedList;
import java.util.Queue;

/**
 * Java Program to use Queue  interface
 * @author Javin Paul
 */
public class QueueDemo{

    public static void main(String args[]) {

        Queue<String> months = new LinkedList<String>();

        // Example 1 - Adding objects into Queue
        System.out.println("Queue : " + months);
        months.add("JAN");
        months.add("FEB");
        months.add("MAR");
        months.add("APR");
        months.add("MAY");
        months.add("JUN");
        months.add("JUL");
        months.add("AUG");
        months.add("SEP");
        months.add("OCT");
        months.add("NOV");
        months.add("DEC");
        System.out.println("Queue after initialization : " + months);

        // Example 2 - Checking if an Object is in Queue or not
        boolean hasMay = months.contains("MAY");
        System.out.println("Does Queue has MAY in it? " + hasMay);

        // Example 3 - Retrieving value from head of Queue
        String head = months.peek();
        System.out.println("Head of the Queue contains : " + head);

        // Example 4 - Removing objects from head of the Queue
        String oldHead = months.poll();
        String newHead = months.peek();
        System.out.println("old head : " + oldHead);
        System.out.println("new head : " + newHead);

        // Example 5 - Another way to remove head objects from Queue
        months.remove();
        System.out.println("now head of Queue is: " + months.peek());

    }

}


Output :
Queue : []
Queue after initialization : [JAN, FEB, MAR, APR, MAY, JUN, JUL, AUG, SEP, OCT, NOV, DEC]
Does Queue has MAY in it? true
Head of the Queue contains : JAN
old head : JAN
new head : FEB
now head of Queue is: MAR


It is worth mentioning that FIFO (first-in-first-out) is the most common way to order the elements in the Queue, but that's not the only order.

You have PriorityQueue on which you can order elements based upon orders defined by their Comparator or Comparable, it will guarantee that the head will always be the lowest element.

That's all about how to use Queue in Java. You have the luxury to choose between two sets of methods, one which throws an exception and the other which returns null and you can choose depending on your requirements.

You can not only use the Queue interface to impose FIFO order of processing but also use different implementations, like PriorityQueue to process elements based upon order defined they their Comparator.


Other Java tutorials and resources you may like

Thanks for reading this article so far. If you like this tutorial, then please share it with your friends and colleagues. If you have any questions or feedback, then please drop a note. I will try to answer my best. 

P.S. - If you are a complete beginner in the Java world and looking for a free Udemy course to learn Java online then I also suggest you join Java Tutorial for Complete Beginners (FREE) course on Udemy. More than 1.2 million people have used this course to learn Java online. 

1 comment:

Feel free to comment, ask questions if you have any doubt.