In this tutorial, we discuss queues in Java. So, what is a
queue? A queue is a list of objects. In ordinary day-to-day life, people join a
queue at the end, and leave the queue at the front. In Java, and programming in
general, the front of the queue is referred to as the “head”, while the end of
the queue is referred to as the “tail”. So in Java, we say that we add items to
the “tail” of a queue and remove items from the “head” of a queue.
Queues in programming implement the “first-in-first-out”
principle, which is just another way of saying that the first item to enter a
list is the first one to be removed. Also, the last item to enter a queue is
the last item to be removed, as it makes its way from the tail towards the
head.
An example of a class that implements the Queue interface is
LinkedList. Another example of a class that implements the Queue interface is
the ArrayBlockingQueue. There are many classes that implement Queue, but in
this tutorial, we are going to look at the ArrayBlockingQueue. Unlike a
LinkedList which can have an infinite size, ArrayBlockingQueue has a fixed
size. Here is how we can define an ArrayBlockingQueue.
Queue<String> queue1 = new
ArrayBlockingQueue<String>(5);
There are two sets of methods that you can use with regards
to Queue. The first set of methods throws exceptions while the second set of
queue methods returns a special value.
Throws
Exception
|
Returns
Special Value
|
|
Insert
|
add()
|
offer()
|
Remove
|
remove()
|
poll()
|
Examine
|
element()
|
peek()
|
The first set of methods throw exceptions if you try to do
something that makes no sense. For example, let us try to use the add() method
to add more items than the specified size of the queue. We specified that the
size of the queue is 5. Let’s try to add six items:
queue1.add(“root”);
queue1.add(“leaves”);
queue1.add(“shoot”);
queue1.add(“fruit”);
queue1.add(“flower”);
queue1.add(“branch”);Figure 1: Trying to add more items than the size of an ArrayBlockingQueue
Java will throw an IllegalStateException. You will also
notice that when we wrote the above lines, Java didn’t force us to handle the
exception. So, this is another example of an unchecked exception, also known as
a runtime exception.
We can surround sixth queue1.add(“branch”); with a try-catch
block like this:
try {
queue1.add(“branch”);
} catch (IllegalStateException e) {
System.out.println(“Can’t
add more items to queue.”);
}Figure 2: Handling an IllegalStateException thrown when you try to add more items than the size of an ArrayBlockingQueue
To see what is inside the queue, we can use a for loop:
for (String content: queue1) {
System.out.println(content);
}Figure 3: To see what is inside a queue
If you want to find out what the head of the queue is, you
can use the element() method like this:
Figure 4: Using the element() method to find out the head of the queue
If you try to call the element() method when there is no item
in the queue, Java will throw a NoSuchElementException, which we can surround
with a try-catch block like this:
try {
System.out.println(“The head of the
queue is: ” + queue1.element());
} catch (NoSuchElementException e) {
System.out.println(“The
queue is empty”);
}Figure 5: How to handle the NoSuchElementException thrown when we try to find the head of an empty queue
To remove values from a queue, we use the remove() method.
The remove() method will remove the item that is at the head of the queue and
return it.
System.out.println(queue1.remove());
System.out.println(queue1.remove());
System.out.println(queue1.remove());
System.out.println(queue1.remove());
System.out.println(queue1.remove());
System.out.println(queue1.remove());
System.out.println(queue1.remove());
Figure 6: Removing more items than there are in a list leads to the throwing of an exception
So we can also surround the sixth attempt to remove the item
from the queue with a try-catch block:
try {
System.out.println(queue1.remove());
} catch (NoSuchElementException e) {
System.out.println(“Tried
to remove more elements that there are”);
}
Figure 7: How to handle an exception thrown by trying to remove more items than there are in a queue
Queues also have methods that return a special value instead
of throwing an exception. Let’s create a new queue for demonstration:
Queue<String> queue2 = new
ArrayBlockingQueue<String>(2);
We are going to look at the offer() method, which is similar
to the add() method. We will also look at the poll() method, which is similar
to the remove() method. Finally, we will look at the peek() method, which is
similar to the element() method.
Now, let us add some items to the queue using the offer()
method.
queue2.offer(“moss”);
queue2.offer(“algae”);
queue2.offer(“lichen”);
Now, notice that we are trying to add a third item “lichen”
despite the fact that we specified that queue2 can only hold two elements. What
Java does is it will ignore all the items that are beyond the size of the
queue. How do we know this? We can examine the contents of queue2 using a
foreach loop like this:
for (String content: queue2) {
System.out.println(content);
}Figure 8: Adding items to a queue using the offer() method
Now, let us remove some items to the queue using the poll()
method.
queue2.poll();
queue2. poll ();
queue2. poll ();
Now, notice that we are trying to remove a third item
“lichen” despite the fact that we specified that queue2 can only hold two
elements. What Java does is it will ignore all the items that are beyond the
size of the queue. How do we know this? We can examine the contents of queue2
using a foreach loop like this:
for (String content: queue2) {
System.out.println(content);
}
Figure 9: Using the poll() method to remove items from a queue
Now, we can use the peek() method to examine the head of the
queue like this:
Figure 10: Using the peek() method to identify the item at the head of the queue
If there are no items in the queue, the peek() method returns
“null”.
So there you go… the Queue interface. It has two sets of
methods that do the same things, only that one set of methods throws an
exception while the other returns a special value. If you want a bounded list,
you can use an ArrayBlockingQueue. But if you want an unbounded queue, use a
LinkedList.
Queues are very useful in multithreading and we shall see
this in the multithreading section.
In the next tutorial, we are going to look at iterators.
Incase you have any questions or comments, please feel free
to leave them in the comments section below and I will address them.
No comments:
Post a Comment