Home » Core Java » util » Queue » Java Queue Example

About Katerina Zamani

Katerina Zamani
Katerina has graduated from the Department of Informatics and Telecommunications in National and Kapodistrian University of Athens (NKUA) and she attends MSc courses in Advanced Information Systems at the same department. Currently, her main academic interests focus on web applications, mobile development, software engineering, databases and telecommunications.

Java Queue Example

Last updated Jan. 17, 2019

Java provides us Queue interface, where we can keep and handle elements before processing. Except the methods that Collection provides, it also supports some basic operations in order to simulate the classic queue structure. Each of these operations exists in two forms:

  • if a method fails, an exception is thrown. This form includes add(), remove() and element() methods.
  • if a method fails, a special value is returned (null or false). This form contains offer(), poll() and peek() operations.

It is worth to mention that FIFO (first-in-first-out) is the most common way to order the elements in the Queue. In this example we are going to show the operations in order to handle a queue.

1. Explanation of Queue operations

First of all, lets see analytically the basic operations that exist in two different forms.

1.1. Throws exception

  • 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.

1.2. Returns special value

  • 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 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.

2. Queue’s Interfaces

The Queue interface does not define the blocking queue methods, which are common in concurrent programming. These methods, which wait for elements to appear or for space to become available, are defined in the BlockingQueue interface, which extends this interface

  • Deque: abstracts a queue that has two heads. A deque allows adding or removing elements at both ends.
  • BlockingQueue: abstracts a type of queues that waits for the queue to be non-empty when retrieving an element, and waits for space to become available in the queue when storing an element.
  • BlockingDeque: is similar to BlockingQueue, but for double ended queues. It is sub interface of the BlockingQueue.
  • TransferQueue is a specialized BlockingQueue, which producers can wait for consumers to receive elements.

3. Queue’s Implementations

Queue implementations generally do not allow insertion of null elements, although some implementations, such as LinkedList, do not prohibit insertion of null. Even in the implementations that permit it, null should not be inserted into a Queue, as null is also used as a special return value by the poll method to indicate that the queue contains no elements.

Queue implementations generally do not define element-based versions of methods equals and hashCode but instead inherit the identity based versions from class Object, because element-based equality is not always well-defined for queues with the same elements but different ordering properties.

3.1. General-purpose Queue implementations:

  • LinkedList: this class implements both List and Deque interface, thus having hybrid characteristics and behaviors of list and queue. Consider using a LinkedList when you want fast adding and fast removing elements at both ends, plus accessing elements by index.
  • PriorityQueue: this queue orders elements according to their natural ordering, or by a Comparator provided at construction time. Consider using a PriorityQueue when you want to take advantages of natural ordering and fast adding elements to the tail and fast removing elements at the head of the queue.
  • AbstractQueue: This class provides skeletal implementations of some Queue operations. The implementations in this class are appropriate when the base implementation does not allow null elements. Methods add, remove, and element are based on offer, poll, and peek, respectively, but throw exceptions instead of indicating failure via false or null returns. 

3.2. Concurrent Queue implementations:

  • LinkedBlockingQueue: an optionally bounded FIFO blocking queue backed by linked nodes
  • ArrayBlockingQueue: a bounded FIFO blocking queue backed by an array
  • PriorityBlockingQueue: an unbounded blocking priority queue backed by a heap
  • DelayQueue: a time-based scheduling queue backed by a heap
  • SynchronousQueue: a simple rendezvous mechanism that uses the BlockingQueue interface
  • LinkedTransferQueue: an unbounded TransferQueue based on linked nodes
  • ConcurrentLinkedQueue: An unbounded thread-safe queue based on linked nodes.

4. Deque’s Implementations

The Deque interface, pronounced as “deck”, represents a double-ended queue. The Deque interface can be implemented as various types of Collections. The Deque interface implementations are grouped into general-purpose and concurrent implementations.

4.1. General-purpose Queue implementations:

  • ArrayDeque: a simple implementation of the Deque interface. Consider using an ArrayDeque when you want to utilize features of a double ended queue without list-based ones (simpler than a LinkedList).
  • LinkedList: Implements all optional list operations, and permits all elements (including null).

4.2. Concurrent Queue implementations:

  • LinkedBlockingDeque: is the concurrent implementation of the Deque interface.
  • ConcurrentLinkedDeque: An unbounded concurrent deque based on linked nodes.

While Deque implementations are not strictly required to prohibit the insertion of null elements, they are strongly encouraged to do so. Users of any Deque implementations that do allow null elements are strongly encouraged not to take advantage of the ability to insert nulls. This is so because null is used as a special return value by various methods to indicate that the deque is empty.

Deque implementations generally do not define element-based versions of the equals and hashCode methods, but instead inherit the identity-based versions from class Object.

5. Example of Queue

Now, we are going to show in the code how to use the operations we explained above. So, create a new java file with the name QueueClass and paste the following code.

QueueClass.java:

package com.javacodegeeks.core.queue;

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

public class QueueClass {

	public static void main(String[] args) {
		
		Queue myQueue = new LinkedList(); 

		// add elements in the queue using offer() - return true/false
		myQueue.offer("Monday");
		myQueue.offer("Thursday");
		boolean flag = myQueue.offer("Wednesday");
		
		System.out.println("Wednesday inserted successfully? "+flag);
		
		// add more elements using add() - throws IllegalStateException
		try {
			myQueue.add("Thursday");
			myQueue.add("Friday");
			myQueue.add("Weekend");
		} catch (IllegalStateException e) {
			e.printStackTrace();
		}
		
		System.out.println("Pick the head of the queue: " + myQueue.peek());
		
		String head = null;
		try {
			// remove head - remove()
			head = myQueue.remove();
			System.out.print("1) Push out " + head + " from the queue "); 
			System.out.println("and the new head is now: "+myQueue.element());
		} catch (NoSuchElementException e) {
			e.printStackTrace();
		}
		
		// remove the head - poll()
		head = myQueue.poll();
		System.out.print("2) Push out " + head + " from the queue");
		System.out.println("and the new head is now: "+myQueue.peek());
		
		// find out if the queue contains an object
		System.out.println("Does the queue contain 'Weekend'? " + myQueue.contains("Weekend"));
		System.out.println("Does the queue contain 'Monday'? " + myQueue.contains("Monday"));
	}

}

As you can see in the code above, in order to create a queue we should assign LinkedList instance to the Queue object. In addition, you can notice how we call and use the functions we explained before. Also, it is worth to mention that you can use more methods that Queue inherits from Collection, such as contains() method.

You can see the output of the execution of the above code.

Output:

Wednesday inserted successfully? true
Pick the head of the queue: Monday
1) Push out Monday from the queue and the new head is now: Thursday
2) Push out Thursday from the queue and the new head is now: Wednesday
Does the queue contain 'Weekend'? true
Does the queue contain 'Monday'? false

Download the source file

This was a tutorial about Queue in Java. Download the source code of this example: QueueExample.zip

(No Ratings Yet)
Start the discussion Views Tweet it!

Do you want to know how to develop your skillset to become a Java Rockstar?

Subscribe to our newsletter to start Rocking right now!

To get you started we give you our best selling eBooks for FREE!

 

1. JPA Mini Book

2. JVM Troubleshooting Guide

3. JUnit Tutorial for Unit Testing

4. Java Annotations Tutorial

5. Java Interview Questions

6. Spring Interview Questions

7. Android UI Design

 

and many more ....

 

Receive Java & Developer job alerts in your Area

 

Leave a Reply

avatar
  Subscribe  
Notify of