Une collection de queues

Une collection de queues




🛑 TOUTES LES INFORMATIONS CLIQUEZ ICI 👈🏻👈🏻👈🏻

































Une collection de queues




Post an Article


Manage My Drafts



Over 2 million developers have joined DZone.






Refcardz




Trend Reports




Webinars





Zones








|



Agile


AI


Big Data


Cloud


Database


DevOps


Integration


IoT


Java


Microservices


Open Source


Performance


Security


Web Dev






DZone
>
Java Zone
>
The Developer's Guide to Collections: Queues


The Developer's Guide to Collections: Queues


Let's continue our journey into Java collections by examining the concept and proper usage of queues and deques in your code.



Like


(64)



Element
Interface (computing)
Implementation
Peek (software)
Concept (generic programming)
Data structure
Java Development Kit
Java (programming language)
application
Object (computer science)


Popular on DZone


Testing Strategies for Microservices


Everything You Need to Know About Web Pentesting: A Complete Guide


Java Class Loading: Performance Impact


Bad or Good? Behavior Driven Development within Scrum.



Join the DZone community and get the full member experience.
Queues are an essential part of most software applications, whether in an isolated system or a widely-distributed, networked application. In recent years, queues have taken on an entirely new meaning with the acceptance of the Advanced Message Queuing Protocol (AMQP) and many of its implementations, such as RabbitMQ . While these are important aspects of the Java ecosystem, the same importance of queues can be found at the micro-application level, as well. For example, many concurrent (multi-threaded) applications require queues to process data or execute tasks. This category of problem is so prolific, it has even been codified into a well-known problem for decades: The Producer-Consumer problem .
In this last installment of The Developer's Guide to Collections, we will export the queue portion of the Java Collections Framework (JCF) and focus particularly on two types of data structures: Queues and double-ended queues (deque; pronounced "deck"). Starting with an explanation of the concepts behind queues, we will work our way into the actual code of the Queue and Deque interfaces, looking at the intent and logic behind each of these abstractions of the queue concept. Lastly, we will delve into the various queue implementations Java offers and how each implementation differs from one another. With this understanding, we will then be able to make grounded decisions about when and when not to use each implementation. Before diving into these details, though, we must first gain a solid grasp of the concept of a queue.
 A queue is one of the most familiar of collections we see on a daily basis. When we check out at a supermarket, we form a queue at the register (some British dialects refer to this as queuing ). Likewise, when we travel through a drive-through window at a fast food restaurant, we insert our car in a line of other cars and the restaurant staff handles orders one car at a time, starting with the first car in the line and terminating with the last car in the line. Although seemingly different in their application, each of these concepts is closely related. In general, a queue can be defined as follows:
Queues have a distinct set of characteristics and behaviors, where the insertion of a new element in a queue is called enqueuing and the atomic retrieval and removal of the next element from the queue is called dequeuing . If we wish to retrieve the next element from a queue without removing it from the queue, we can peek at the queue, which results in the next element from the queue but leaves it in the queue. Although not all queues are formed in the same manner, the most common type of queue (such as in the supermarket or drive-through examples) is the First-in-First-out (FIFO) queue.
The order of the elements in a queue can vary by the type of queue. In most cases, though, queues are FIFO queues, where the first element enqueued is the first element dequeued. For example, if we enqueue elements A, B, and C (in that order) on a queue, the next element to be dequeued is A, since it is was the first element enqueued (i.e. it is the oldest element). In general, the next element to be dequeued from a queue (in this case, A) is called the head of the queue. A FIFO queue is illustrated in the figure below.
The example of the A, B, and C elements being added to a FIFO queue is illustrated in the figure below. Each enqueue and dequeue step, along with the resulting state of the FIFO queue, is shown, starting with the topmost step and ending with the bottom-most step.
Note that we do not dequeue a specific element (i.e. we do not say dequeue A ). Instead, the head of the queue is always returned when we dequeue; therefore, the target of the dequeue is always implicitly the head of the queue and is never explicitly specified.
The counterpart to a FIFO queue is a Last-in-First-out (LIFO) queue, or a stack , where the last element to be enqueued is the next element to be dequeued. In the vernacular of stacks, the position of the last element pushed onto the stack is called the top and the position of the first element pushed onto the stack is called the bottom (stacks are usually illustrated vertically, such as seen with stacks of paper to be processed or stacks of dishes to be cleaned). For example, if we enqueue elements A, B, and C (in that order) on a stack, the next element to be dequeued is C. With stacks, enqueuing an element is called pushing an element onto the stack while dequeuing an element is called popping an element off of the stack. A stack is illustrated in the figure below.
The previous example of our stack, using A, B, and C as elements, is illustrated in the figure below, with each successive horizontal pane representing the state of the stack as elements are pushed onto it or popped from it.
Similar to the FIFO queue, we do not specify the target of the pop operation on a stack (i.e. we do not say pop C ). Instead, the pop operation always has an implicit target of the top of the stack and thus, no explicit target is provided.
Although both the FIFO queues and stacks both enqueue from one or the other end (i.e. tail for FIFO queues and the top for stacks), there are queues that may enqueue elements at any interior position as well. For example, if we queued patients at a hospital, we would want to enqueue elements by the severity of each patient's injury, rather than when the patient arrived at the hospital. This particular queue is called a priority queue , where each element is assigned a priority and enqueued according to this priority.
The priority of each element may not necessarily be an absolute priority (such as in hospital triage , where an immediate patient always has a higher priority than minimal ), but rather, may have a relative priority. For example, when children are lined up in a classroom by height order, a relative priority is used: Each student is added to the line such as he or she is taller than the student in front and shorter than the student behind him or her. Separate from the group, each student is not considered short or tall, but rather, is considered short er or tall er than another student. In essence, we can discover if a priority is absolute or relative based on the use of superlative or comparative adjectives, respectively (i.e. the most immediate patient for absolute priority or the tall er student for relative priority).
The concept of a priority queue is illustrated in the figure below (where 0 is the highest priority and 2 is the lowest priority).
A priority queue based on the previously discussed classroom lineup scheme is illustrated in the figure below (where the shortest students are placed at the "head of the line").
In the queues we have already seen, elements are always dequeued from the head (or top) of the queue, regardless of the location in which they were enqueued. In general, these types of queues are called single-ended queues since only one end of the queue can be dequeued. In contrast, there are queues from which either end of the queue can be accessed. These double-ended queues (called deques , pronounced decks ) can enqueue and dequeue elements from either end. One end of the queue is called the head , where the element at the head of the queue is called the first element, and the other end is called the tail , where the element at the tail of the queue is called the last element.
It is important to note that all of the queuing behaviors (enqueuing, dequeuing, and peeking) can be used at either end of the deque. This results in six behaviors:
The concept of a deque is illustrated in the figure below.
Deques can conceptually be thought of as the most general of queues, where each of the previously discussed queue types can be theoretically represented by a deque:
With the concept of a queue, as well as their specializations, under our belt, we can now explore the Queue interface, along with Deque interface, that make up the JCF implementation of the general queuing concepts.
Although most off-springs of the Collection interface have a primary sub-interface for their hierarchies (e.g. List and Set interfaces), the queue portion of the collection framework has two: (1) the Queue interface and (2) the Deque interface. Although the Deque interface is actually a sub-interface of the Queue interface, it is important enough to discuss it distinctly from its parent interface.
The Queue interface is a simple interface that captures the basic behavior of a theoretical queue. The Java Development Kit (JDK) 9 interface specification for the Queue interface is depicted in the following snippet.
The methods of the Queue interface can be divided into two categories: Those that throw exceptions to denote failed operations and those that return special values to denote failed operations. The add and offer methods are identical, enqueuing the supplied element to the queue, but the former throws an IllegalStateException  if the element cannot be added due to the state of the queue while the latter returns false if the element cannot be added. Likewise, the remove method throws a NoSuchElementException if the there is no element to dequeue and the poll method returns null if there is no element to dequeue. Lastly, the element method peeks at the head of the queue, throwing a NoSuchElementException if there is no element at the head of the queue while the peek method returns null if no head exists. In general, the special-return-value methods should be used if failure to enqueue, dequeue, or peek is common or expected, such as when using a bounded queue.
In general, the Queue interface methods can be summed up as follows:
Both methods enqueue the element, e , to the queue and return true if the supplied element was successfully added. If the queue implementation does not have a large enough capacity to enqueue the supplied element, the add method throws an IllegalStateException while the offer method returns false . For queue implementations with a non-trivial capacity restriction (i.e. a bounded queue), clients should prefer offer over add .
Both methods dequeue the head of the queue and return the dequeued element (the previous head) of the queue. If no head exists (i.e. the queue is empty), the remove method will throw a NoSuchElementException while the poll method will return null . 
Both methods peek at the head of the queue and non-destructively return the current head of the queue (does not remove the head). If no head exists (i.e. the queue is empty), the element method throws a NoSuchElementException while the peek method returns null .
The interface for a deque may appear to be much more complicated than that of the standard Queue interface, but upon further examination, it is actually quite simple. The JDK 9 Deque interface is depicted in the listing below.
Although this interface includes many more methods that the Queue interface, it only does so because all of the operations of the Queue interface can be executed on either side (head or tail) of the deque. For example, in the case of a Queue , we can only enqueue an element at one side of the queue, but with a Deque , we can enqueue elements at the front (head) or the back (tail). Thus, we only have the add and offer methods for the Queue interface, but we have the addFirst , addLast , offerFirst , and offerLast methods for the Deque interface.
In general, the following enqueue, dequeue, and peek methods are enumerated for a Deque :
Note that while the Queue interface has the element method, the Deque interface uses getter methods in its place (instead of elementFirst a nd elementLast , the Deque interface uses getFirst and getLast , respectively). In the same manner as the Queue interface, the add , remove , and get methods throw exceptions when the desired operation cannot be performed (the same exceptions as their Queue interface counterparts), while the offer, poll, and peek methods use special return values to denote failure of the desired operation.
The first two methods act as convenience methods, removing the first element that matches the supplied element and the last element that matches the supplied element, respectively, from the deque. Matching elements are determined using the Object#equals method, which uses the following logic for each element, e , in the deque: (o == e) || (o != null && o.equals(e)) . In both cases, true is returned if the supplied element was removed from the deque.
The remove method is logically equivalent to the removeFirstOccurrence method, removing the first matching element in the deque and returning true if the a matching element was successfully removed from the deque.
Since the deques are also queues, the Deque interface extends the Queue interface and expects the methods inherited from the Queue interface to behave as FIFO operations. Thus, calling add or offer enqueues an element to the tail of the queue; calling remove or poll dequeues an element from the head of the queue; calling element or peek peeks at the element at the head of the queue. Thus, the existing Queue methods can be summarized as equivalent Deque interface behaviors in the following table (note that this does not mean that a Deque implementation must call these methods, but rather, these methods have equivalent behavior):
This method enqueues all of the elements in the supplied collection to the tail of deque. This method is equivalent to calling addLast for each element and returns true if deque changed as a result of this call. If a deque implementation has a non-trivial capacity restriction, it is preferable to call offer on each of the element in c  rather than calling addAll .
As stated in the conceptual overview section of this article, deques can also be used as stacks. Thus, the Deque interface includes stack methods–namely push and pop (as peek already exists). Although a Stack interface does not exist in the collections framework (as there already exists a Stack class in the framework), it can be effectively understood to be the following (note that this interface does not exist in the collections framework):
Although the Stack interface does not exist , the Deque interface includes these methods as though they did and expects the behavior of these methods to reflect the following Deque methods:
Note that the push and pop methods use the exception-throwing style methods while the peek method uses the special-return-value style method.
The contains method returns true if the supplied object is contained in the deque and returns false otherwise. The size method returns the current number of elements in the deque. 
The iterator method returns an Iterator that will traverse each element of the deque sequentially starting at its head (first element) and ending with its tail (last element). The descendingIterator returns an Iterator that traverses the deque in the reverse order, starting at the tail (last element) and ending with the head (first element).
The Queue interface hierarchy may appear more complicated than other collection subtype hierarchies, but if we keep our wits about the conceptual idea of a queue, it is actually quite simple. The non-concurrent hierarchy for the JDK 9 Queue interface is illustrated below, where interfaces are represented in green, abstract classes are represented in blue, and concrete implementation classes are represented in purple.
Starting with the root of the interface, we reach the Queue interface, which defines the basic queue behaviors (enqueuing, dequeuing, and peeking) as seen in the previous section. Following the left side of the hierarchy down, we reach the AbstractQueue class, which is a more specialized AbstractCollection class that maintains the basic queue functionality for add , remove , element , and addAll in ter
bacchanale amateur
Terry Summers percée par une bonne bite
Une fille avec des melons gigantesques

Report Page