UNPKG

epubjs

Version:

Render ePub documents in the browser, across many devices

365 lines 108 kB
<?xml version="1.0" encoding="UTF-8" standalone="no"?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"><head><title>Collections</title><link rel="stylesheet" href="core.css" type="text/css"/><meta name="generator" content="DocBook XSL Stylesheets V1.74.0"/></head><body><div class="sect1" title="Collections"><div class="titlepage"><div><div><h1 class="title"><a id="learnjava3-CHP-11-SECT-4"/>Collections</h1></div></div></div><p><a id="I_indexterm11_id741199" class="indexterm"/> <span class="emphasis"><em>Collections</em></span> are data structures that are fundamental to all types of programming. Whenever we need to refer to a group of objects, we have some kind of collection. At the core language level, Java supports collections in the form of arrays. But arrays are static and because they have a fixed length, they are awkward for groups of things that grow and shrink over the lifetime of an application. Arrays also do not represent abstract relationships between objects well. In the early days, the Java platform had only two basic classes to address these needs: the <code class="literal">java.util.Vector</code> class, which represents a dynamic list of objects, and the <code class="literal">java.util.Hashtable</code> class, which holds a map of key/value pairs. Today, Java has a more comprehensive approach to collections called the Collections Framework. The older classes still exist, but they have been retrofitted into the framework (with some eccentricities) and are generally no longer used.</p><p>Though conceptually simple, collections are one of the most powerful parts of any programming language. Collections implement data structures that lie at the heart of managing complex problems. A great deal of basic computer science is devoted to describing the most efficient ways to implement certain types of algorithms over collections. Having these tools at your disposal and understanding how to use them can make your code both much smaller and faster. It can also save you from reinventing the wheel.</p><p>Prior to Java 5, the Collections Framework had two major drawbacks. The first was that—not having generic types to work with—collections were by necessity untyped and worked only with anonymous <code class="literal">Object</code>s instead of real types like <code class="literal">Date</code>s and <code class="literal">String</code>s. This meant that you had to perform a type cast every time you took an object out of a collection. This flew in the face of Java’s compile-time type safety. But in practice, this was less a problem than it was just plain cumbersome and tedious. The second issue was that, for practical reasons, collections could work only with objects and not with primitive types. This meant that any time you wanted to put a number or other primitive type into a collection, you had to store it in a wrapper class first and unpack it later upon retrieving it. The combination of these factors made code working with collections less readable and more dangerous to boot.</p><p>This all changed with the introduction of generic types and autoboxing of primitive values. First, the introduction of generic types, as we described in <a class="xref" href="ch08.html" title="Chapter 8. Generics">Chapter 8</a>, has made it possible for truly typesafe collections to be under the control of the programmer. Second, the introduction of autoboxing and unboxing of primitive types means that you can generally treat objects and primitives as equals where collections are concerned. The combination of these new features can significantly reduce the amount of code you write and add safety as well. As we’ll see, all of the collections classes now take advantage of these features.</p><p>The Collections Framework is based around a handful of interfaces in the <code class="literal">java.util</code> package. These interfaces are divided into two hierarchies. The first hierarchy descends from the <code class="literal">Collection</code> interface. This interface (and its descendants) represents a container that holds other objects. The second, separate hierarchy is based on the <code class="literal">Map</code> interface, which represents a group of key/value pairs where the key can be used to retrieve the value in an efficient way.</p><div class="sect2" title="The Collection Interface"><div class="titlepage"><div><div><h2 class="title"><a id="learnjava3-CHP-11-SECT-4.1"/>The Collection Interface</h2></div></div></div><p><a id="idx10612" class="indexterm"/>The mother of all collections is an interface appropriately named <code class="literal">Collection</code>. It serves as a container that holds other objects, its <span class="emphasis"><em>elements</em></span>. It doesn’t specify exactly how the objects are organized; it doesn’t say, for example, whether duplicate objects are allowed or whether the objects are ordered in any way. These kinds of details are left to child interfaces. Nevertheless, the <code class="literal">Collection</code> interface defines some basic operations common to all collections:</p><div class="variablelist"><dl><dt><span class="term"><code class="literal">public boolean add(</code> <em class="replaceable"><code>element</code></em> <code class="literal">)</code></span></dt><dd><p><a id="I_indexterm11_id741365" class="indexterm"/>This method adds the supplied object to this collection. If the operation succeeds, this method returns <code class="literal">true</code>. If the object already exists in this collection and the collection does not permit duplicates, <code class="literal">false</code> is returned. Furthermore, some collections are read-only. Those collections throw an <code class="literal">UnsupportedOperationException</code> if this method is called.</p></dd><dt><span class="term"><code class="literal">public boolean remove(</code> <em class="replaceable"><code>element</code></em> <code class="literal">)</code></span></dt><dd><p><a id="I_indexterm11_id741411" class="indexterm"/>This method removes the specified object from this collection. Like the <code class="literal">add()</code> method, this method returns <code class="literal">true</code> if the object is removed from the collection. If the object doesn’t exist in this collection, <code class="literal">false</code> is returned. Read-only collections throw an <code class="literal">UnsupportedOperationException</code> if this method is called.</p></dd><dt><span class="term"><code class="literal">public boolean contains(</code> <em class="replaceable"><code>element</code></em> <code class="literal">)</code></span></dt><dd><p><a id="I_indexterm11_id741462" class="indexterm"/>This method returns <code class="literal">true</code> if the collection contains the specified object.</p></dd><dt><span class="term"><code class="literal">public int size()</code></span></dt><dd><p>Use this method to find the number of elements in this collection.</p></dd><dt><span class="term"><code class="literal">public boolean isEmpty()</code></span></dt><dd><p><a id="I_indexterm11_id741494" class="indexterm"/>This method returns <code class="literal">true</code> if this collection has no elements.</p></dd><dt><span class="term"><code class="literal">public Iterator iterator()</code></span></dt><dd><p><a id="I_indexterm11_id741518" class="indexterm"/>Use this method to examine all the elements in this collection. This method returns an <code class="literal">Iterator</code>, which is an object you can use to step through the collection’s elements. We’ll talk more about iterators in the next section.</p></dd></dl></div><p>Additionally, the methods <a id="I_indexterm11_id741536" class="indexterm"/><code class="literal">addAll()</code>, <a id="I_indexterm11_id741546" class="indexterm"/><code class="literal">removeAll()</code>, and <a id="I_indexterm11_id741557" class="indexterm"/><code class="literal">containsAll()</code> accept another <code class="literal">Collection</code> and add, remove, or test for all of the elements of the supplied collection.</p><div class="sect3" title="Generics and collections"><div class="titlepage"><div><div><h3 class="title"><a id="learnjava3-CHP-11-SECT-4.1.1"/>Generics and collections</h3></div></div></div><p><a id="I_indexterm11_id741581" class="indexterm"/> <a id="I_indexterm11_id741592" class="indexterm"/>When using generics, the <code class="literal">Collection</code> type is parameterized with a specific type of element that the collection will hold. This makes a generic collection of “anything” into a specific collection of some type of element. The parameter type becomes the compile-time type of the <code class="literal">element</code> arguments in all of the methods of <code class="literal">Collection</code> (in this case, the <code class="literal">add()</code>, <code class="literal">remove()</code>, and <code class="literal">contains()</code> methods listed earlier). For example, in the following code, we create a <code class="literal">Collection</code> that works with <code class="literal">Date</code>s:</p><a id="I_11_tt705"/><pre class="programlisting"> <code class="n">Collection</code><code class="o">&lt;</code><code class="n">Date</code><code class="o">&gt;</code> <code class="n">dates</code> <code class="o">=</code> <code class="k">new</code> <code class="n">ArrayList</code><code class="o">&lt;</code><code class="n">Date</code><code class="o">&gt;();</code> <code class="c1">// = new ArrayList&lt;&gt;() would </code> <code class="c1">// also work.</code> <code class="n">dates</code><code class="o">.</code><code class="na">add</code><code class="o">(</code> <code class="k">new</code> <code class="n">Date</code><code class="o">()</code> <code class="o">);</code> <code class="n">dates</code><code class="o">.</code><code class="na">add</code><code class="o">(</code> <code class="s">"foo"</code> <code class="o">)</code> <code class="c1">// Error; string type where Date expected!!</code></pre><p><code class="literal">ArrayList</code> is just one implementation of <code class="literal">Collection</code>; we’ll talk about it a bit later. The important thing is that we’ve declared the variable <code class="literal">dates</code> to be of the type <code class="literal">Collection&lt;Date&gt;</code>; that is, a collection of <code class="literal">Date</code>s, and we’ve allocated our <code class="literal">ArrayList</code> to match. Because our collection has been parameterized with the type <code class="literal">Date</code>, the <code class="literal">add()</code> method of the collection becomes <code class="literal">add( Date date )</code> and attempting to add any type of object other than a <code class="literal">Date</code> to the list would have caused a compile-time error.</p><p>If you are working with very old Java code that predates generics, you can simply drop the types and perform the appropriate casts. For example:</p><a id="I_11_tt706"/><pre class="programlisting"> <code class="n">Collection</code> <code class="n">dates</code> <code class="o">=</code> <code class="k">new</code> <code class="n">ArrayList</code><code class="o">();</code> <code class="n">dates</code><code class="o">.</code><code class="na">add</code><code class="o">(</code> <code class="k">new</code> <code class="n">Date</code><code class="o">()</code> <code class="o">);</code> <code class="c1">// unchecked, compile-time warning</code> <code class="n">Date</code> <code class="n">date</code> <code class="o">=</code> <code class="o">(</code><code class="n">Date</code><code class="o">)</code><code class="n">dates</code><code class="o">.</code><code class="na">get</code><code class="o">(</code> <code class="mi">0</code> <code class="o">);</code></pre><p>In this case, we’ll get a compile time warning that we’re using <code class="literal">ArrayList </code>in a potentially unsafe (nongeneric typesafe) way.</p><p>As we’ve described earlier in the book, this is essentially what the Java compiler is doing for us with generics. When using collections (or any generic classes) in this way under Java 5 or later, you will get compile-time warnings indicating that the usage is unchecked, meaning that it is possible to get an error at runtime if you have made a mistake. In this example, a mistake would not be caught until someone tried to retrieve the object from the collection and cast it to the expected type.</p></div><div class="sect3" title="Legacy code and runtime type safety"><div class="titlepage"><div><div><h3 class="title"><a id="learnjava3-CHP-11-SECT-4.1.2"/>Legacy code and runtime type safety</h3></div></div></div><p><a id="idx10597" class="indexterm"/> <a id="idx10647" class="indexterm"/> <a id="idx10669" class="indexterm"/>If you are working with legacy Java code that predates Java 5 generics and you do not wish to introduce generics to it, you can still add a layer of type safety at runtime by switching to a runtime type-checked version of your collection types. Java supplies runtime-checked wrappers for all of the basic collection types. These wrappers enforce a specific Java element type at runtime by throwing <a id="I_indexterm11_id741799" class="indexterm"/><code class="literal">ClassCastException</code> if the wrong element is inserted. For example:</p><a id="I_11_tt707"/><pre class="programlisting"> <code class="n">List</code> <code class="n">list</code> <code class="o">=</code> <code class="k">new</code> <code class="n">ArrayList</code><code class="o">();</code> <code class="n">list</code> <code class="o">=</code> <code class="n">Collections</code><code class="o">.</code><code class="na">checkedList</code><code class="o">(</code> <code class="n">list</code><code class="o">,</code> <code class="n">Date</code><code class="o">.</code><code class="na">class</code> <code class="o">);</code> <code class="n">list</code><code class="o">.</code><code class="na">add</code><code class="o">(</code> <code class="k">new</code> <code class="n">Date</code><code class="o">()</code> <code class="o">);</code> <code class="n">list</code><code class="o">.</code><code class="na">add</code><code class="o">(</code> <code class="s">"foo"</code> <code class="o">);</code> <code class="c1">// Runtime ClassCastException!</code></pre><p>Here, the static <a id="I_indexterm11_id741823" class="indexterm"/><code class="literal">Collections.checkedList()</code> method has wrapped our collection, <code class="literal">list</code>, in a wrapper that implements all of the methods of <code class="literal">List</code>, but checks that we are only holding <code class="literal">Date</code>s. The second argument to the method is the literal <code class="literal">Date.class</code> reference to the <code class="literal">Class</code> of <code class="literal">Date</code>. This serves to tell the wrapper what type we want to enforce. Corresponding “checked” collection methods exist for all of the basic collection interfaces that we’ll see, including the base <code class="literal">Collection</code>, <code class="literal">List</code>, <code class="literal">Set</code>, and <code class="literal">Map</code>.<a id="I_indexterm11_id741893" class="indexterm"/><a id="I_indexterm11_id741900" class="indexterm"/><a id="I_indexterm11_id741907" class="indexterm"/></p></div><div class="sect3" title="Converting between collections and arrays"><div class="titlepage"><div><div><h3 class="title"><a id="learnjava3-CHP-11-SECT-4.1.3"/>Converting between collections and arrays</h3></div></div></div><p><a id="I_indexterm11_id741921" class="indexterm"/> <a id="I_indexterm11_id741930" class="indexterm"/>Converting between collections and arrays is easy. For convenience, the elements of a collection can be retrieved as an array using the following methods:</p><a id="I_11_tt708"/><pre class="programlisting"> <code class="kd">public</code> <code class="n">Object</code><code class="o">[]</code> <code class="nf">toArray</code><code class="o">()</code> <code class="kd">public</code> <code class="o">&lt;</code><code class="n">E</code><code class="o">&gt;</code> <code class="n">E</code><code class="o">[]</code> <code class="n">toArray</code><code class="o">(</code> <code class="n">E</code><code class="o">[]</code> <code class="n">a</code> <code class="o">)</code></pre><p>The first method returns a plain <code class="literal">Object</code> array. With the second form, we can be more specific and get back an array of the correct element type. If we supply an array of sufficient size, it will be filled in with the values. But if the array is too short (e.g., zero length), a new array of the <span class="emphasis"><em>same type but the required length</em></span> will be created and returned to us. So you can just pass in an empty array of the correct type like this:</p><a id="I_11_tt709"/><pre class="programlisting"> <code class="n">Collection</code><code class="o">&lt;</code><code class="n">String</code><code class="o">&gt;</code> <code class="n">myCollection</code> <code class="o">=</code> <code class="o">...;</code> <code class="n">String</code> <code class="o">[]</code> <code class="n">myStrings</code> <code class="o">=</code> <code class="n">myCollection</code><code class="o">.</code><code class="na">toArray</code><code class="o">(</code> <code class="k">new</code> <code class="n">String</code><code class="o">[</code><code class="mi">0</code><code class="o">]</code> <code class="o">);</code></pre><p>(This trick is a little awkward and it would be nice if Java let us specify the type explicitly using a <code class="literal">Class</code> reference, but for some reason, this isn’t the case.) Going the other way, you can convert an array of objects to a <code class="literal">List</code> collection with the static <code class="literal">asList()</code> method of the <code class="literal">java.util.Arrays</code> class:<a id="I_indexterm11_id742004" class="indexterm"/></p><a id="I_11_tt710"/><pre class="programlisting"> <code class="n">String</code> <code class="o">[]</code> <code class="n">myStrings</code> <code class="o">=</code> <code class="o">...;</code> <code class="n">List</code> <code class="n">list</code> <code class="o">=</code> <code class="n">Arrays</code><code class="o">.</code><code class="na">asList</code><code class="o">(</code> <code class="n">myStrings</code> <code class="o">);</code></pre></div></div><div class="sect2" title="Iterator"><div class="titlepage"><div><div><h2 class="title"><a id="learnjava3-CHP-11-SECT-4.2"/>Iterator</h2></div></div></div><p><a id="idx10617" class="indexterm"/>An <a id="I_indexterm11_id742042" class="indexterm"/><span class="emphasis"><em>iterator</em></span> is an object that lets you step through a sequence of values. This kind of operation comes up so often that it is given a standard interface: <code class="literal">java.util.Iterator</code>. The <a id="I_indexterm11_id742059" class="indexterm"/><code class="literal">Iterator</code> interface has only two primary methods:</p><div class="variablelist"><dl><dt><span class="term"><code class="literal">public E next()</code></span></dt><dd><p><a id="I_indexterm11_id742080" class="indexterm"/>This method returns the next element (an element of generic type E) of the associated collection.</p></dd><dt><span class="term"><code class="literal">public boolean hasNext()</code></span></dt><dd><p><a id="I_indexterm11_id742097" class="indexterm"/>This method returns <code class="literal">true</code> if you have not yet stepped through all the <code class="literal">Collection</code>’s elements. In other words, it returns <code class="literal">true</code> if you can call <code class="literal">next()</code> to get the next element.</p></dd></dl></div><p>The following example shows how you could use an <code class="literal">Iterator</code> to print out every element of a collection:</p><a id="I_11_tt711"/><pre class="programlisting"> <code class="kd">public</code> <code class="kt">void</code> <code class="nf">printElements</code><code class="o">(</code><code class="n">Collection</code> <code class="n">c</code><code class="o">,</code> <code class="n">PrintStream</code> <code class="n">out</code><code class="o">)</code> <code class="o">{</code> <code class="n">Iterator</code> <code class="n">iterator</code> <code class="o">=</code> <code class="n">c</code><code class="o">.</code><code class="na">iterator</code><code class="o">();</code> <code class="k">while</code> <code class="o">(</code> <code class="n">iterator</code><code class="o">.</code><code class="na">hasNext</code><code class="o">()</code> <code class="o">)</code> <code class="n">out</code><code class="o">.</code><code class="na">println</code><code class="o">(</code> <code class="n">iterator</code><code class="o">.</code><code class="na">next</code><code class="o">()</code> <code class="o">);</code> <code class="o">}</code></pre><p>In addition to the traversal methods, <code class="literal">Iterator</code> provides the ability to remove an element from a collection:</p><div class="variablelist"><dl><dt><span class="term"><code class="literal">public void remove()</code></span></dt><dd><p><a id="I_indexterm11_id742163" class="indexterm"/>This method removes the most recent object returned from <code class="literal">next()</code> from the associated <code class="literal">Collection</code>.</p></dd></dl></div><p>Not all iterators implement <code class="literal">remove()</code>. It doesn’t make sense to be able to remove an element from a read-only collection, for example. If element removal is not allowed, an <code class="literal">UnsupportedOperationException</code> is thrown from this method. If you call <code class="literal">remove()</code> before first calling <code class="literal">next()</code>, or if you call <code class="literal">remove()</code> twice in a row, you’ll get an <code class="literal">IllegalStateException</code>.</p><div class="sect3" title="For loop over collections"><div class="titlepage"><div><div><h3 class="title"><a id="learnjava3-CHP-11-SECT-4.2.1"/>For loop over collections</h3></div></div></div><p><a id="I_indexterm11_id742229" class="indexterm"/> <a id="I_indexterm11_id742240" class="indexterm"/> <a id="I_indexterm11_id742249" class="indexterm"/>A form of the <code class="literal">for</code> loop, described in <a class="xref" href="ch04.html" title="Chapter 4. The Java Language">Chapter 4</a>, can operate over all types of <a id="I_indexterm11_id742268" class="indexterm"/><code class="literal">Collection</code> objects. For example, we can now step over all of the elements of a typed collection of <code class="literal">Date</code> objects like so:</p><a id="I_11_tt712"/><pre class="programlisting"> <code class="n">Collection</code><code class="o">&lt;</code><code class="n">Date</code><code class="o">&gt;</code> <code class="n">col</code> <code class="o">=</code> <code class="o">...</code> <code class="k">for</code><code class="o">(</code> <code class="n">Date</code> <code class="n">date</code> <code class="o">:</code> <code class="n">col</code> <code class="o">)</code> <code class="n">System</code><code class="o">.</code><code class="na">out</code><code class="o">.</code><code class="na">println</code><code class="o">(</code> <code class="n">date</code> <code class="o">);</code></pre><p>This feature of the Java built-in <code class="literal">for</code> loop is called the “enhanced” <code class="literal">for</code> loop (as opposed to the pregenerics, numeric-only <code class="literal">for</code> loop). The enhanced <code class="literal">for</code> loop applies only to <code class="literal">Collection</code> type collections, not <code class="literal">Map</code>s. <code class="literal">Map</code>s are another type of beast that really contain two distinct sets of objects (keys and values), so it’s not obvious what your intentions would be in such a loop.</p></div><div class="sect3" title="java.util.Enumeration"><div class="titlepage"><div><div><h3 class="title"><a id="learnjava3-CHP-11-SECT-4.2.2"/>java.util.Enumeration</h3></div></div></div><p><a id="I_indexterm11_id742351" class="indexterm"/> <a id="I_indexterm11_id742362" class="indexterm"/> <a id="idx10645" class="indexterm"/>Prior to the introduction of the Collections API there was another iterator interface: <code class="literal">java.util.Enumeration</code>. It used the slightly more verbose names <a id="I_indexterm11_id742389" class="indexterm"/><code class="literal">nextElement()</code> and <a id="I_indexterm11_id742399" class="indexterm"/><code class="literal">hasMoreElements()</code>, but accomplished the same thing. Many older classes provide <a id="I_indexterm11_id742411" class="indexterm"/><code class="literal">Enumeration</code>s where they would now use <code class="literal">Iterator</code>. If you aren’t worried about performance, you can just convert your <code class="literal">Enumeration</code> into a <code class="literal">List</code> with a static convenience method of the <code class="literal">java.util.Collections</code> class:<a id="I_indexterm11_id742445" class="indexterm"/></p><a id="I_11_tt713"/><pre class="programlisting"> <code class="n">Enumeration</code> <code class="n">myEnumeartion</code> <code class="o">=</code> <code class="o">...;</code> <code class="n">List</code> <code class="n">list</code> <code class="o">=</code> <code class="n">Collections</code><code class="o">.</code><code class="na">list</code><code class="o">(</code> <code class="n">myEnumeration</code> <code class="o">);</code></pre></div></div><div class="sect2" title="Collection Types"><div class="titlepage"><div><div><h2 class="title"><a id="learnjava3-CHP-11-SECT-4.3"/>Collection Types</h2></div></div></div><p><a id="idx10613" class="indexterm"/>The <code class="literal">Collection</code> interface has three child interfaces. <code class="literal">Set</code> represents a collection in which duplicate elements are not allowed. <code class="literal">List</code> is a collection whose elements have a specific order. The <code class="literal">Queue</code> interface is a buffer for objects with a notion of a “head” element that’s next in line for processing.</p><div class="sect3" title="Set"><div class="titlepage"><div><div><h3 class="title"><a id="learnjava3-CHP-11-SECT-4.3.1"/>Set</h3></div></div></div><p><a id="I_indexterm11_id742514" class="indexterm"/> <a id="I_indexterm11_id742525" class="indexterm"/> <code class="literal">Set</code> has no methods besides the ones it inherits from <code class="literal">Collection</code>. It simply enforces its no-duplicates rule. If you try to add an element that already exists in a <code class="literal">Set</code>, the <code class="literal">add()</code> method simply returns <code class="literal">false</code>. <code class="literal">SortedSet</code> maintains elements in a prescribed order; like a sorted list that can contain no duplicates. It adds the methods <code class="literal">add()</code> and <code class="literal">remove()</code> to the <code class="literal">Set </code>interface. You can retrieve subsets (which are also sorted) using the <a id="I_indexterm11_id742582" class="indexterm"/><code class="literal">subSet()</code>, <a id="I_indexterm11_id742593" class="indexterm"/><code class="literal">headSet()</code>, and <a id="I_indexterm11_id742603" class="indexterm"/><code class="literal">tailSet()</code> methods. These methods accept one or a pair of elements that mark the boundaries. The <a id="I_indexterm11_id742615" class="indexterm"/><code class="literal">first()</code>, <a id="I_indexterm11_id742625" class="indexterm"/><code class="literal">last()</code>, and <a id="I_indexterm11_id742636" class="indexterm"/><code class="literal">comparator()</code> methods provide access to the first element, the last element, and the object used to compare elements (more on this later).</p><p>Java 7 adds <code class="literal">NavigableSet</code>, which extends <code class="literal">SortedSet</code> and adds methods for finding the closest match greater or lesser than a target value within the sort order of the <code class="literal">Set</code>. This interface can be implemented efficiently using techniques such as skip lists, which make finding ordered elements fast (Java 7 supplies such an implementation, which we’ll note later).</p></div><div class="sect3" title="List"><div class="titlepage"><div><div><h3 class="title"><a id="learnjava3-CHP-11-SECT-4.3.2"/>List</h3></div></div></div><p><a id="idx10598" class="indexterm"/> <a id="idx10649" class="indexterm"/>The next child interface of <code class="literal">Collection</code> is <code class="literal">List</code>. The <code class="literal">List</code> is an ordered collection, similar to an array but with methods for manipulating the position of elements in the list:</p><div class="variablelist"><dl><dt><span class="term"><code class="literal">public boolean add( E</code> <em class="replaceable"><code>element</code></em> <code class="literal">)</code></span></dt><dd><p><a id="I_indexterm11_id742738" class="indexterm"/>This method adds the specified element to the end of the list.</p></dd><dt><span class="term"><code class="literal">public void add( int</code> <em class="replaceable"><code>index</code></em> <code class="literal">, E</code> <em class="replaceable"><code>element</code></em> <code class="literal">)</code></span></dt><dd><p>This method inserts the given object at the supplied position in the list. If the position is less than zero or greater than the list length, an <code class="literal">IndexOutOfBoundsException</code> will be thrown. The element that was previously at the supplied position, and all elements after it, are moved up one index position.</p></dd><dt><span class="term"><code class="literal">public void remove( int</code> <em class="replaceable"><code>index</code></em> <code class="literal">)</code></span></dt><dd><p><a id="I_indexterm11_id742799" class="indexterm"/>This method removes the element at the specified position. All subsequent elements move down one index position.</p></dd><dt><span class="term"><code class="literal">public E get( int</code> <em class="replaceable"><code>index</code></em> <code class="literal">)</code></span></dt><dd><p><a id="I_indexterm11_id742826" class="indexterm"/>This method returns the element at the given position.</p></dd><dt><span class="term"><code class="literal">public Object set( int</code> <em class="replaceable"><code>index</code></em> <code class="literal">, E</code> <em class="replaceable"><code>element</code></em> <code class="literal">)</code></span></dt><dd><p><a id="I_indexterm11_id742861" class="indexterm"/>This method changes the element at the given position to the specified object. There must already be an object at the index or else an <code class="literal">IndexOutOfBoundsException</code> is thrown.</p></dd></dl></div><p>The type <code class="literal">E</code> in these methods refers to the parameterized element type of the <code class="literal">List</code> class. <code class="literal">Collection</code>, <code class="literal">Set</code>, and <code class="literal">List</code> are all interface types. We’ll look at concrete implementations of these shortly.<a id="I_indexterm11_id742905" class="indexterm"/><a id="I_indexterm11_id742912" class="indexterm"/></p></div><div class="sect3" title="Queue"><div class="titlepage"><div><div><h3 class="title"><a id="learnjava3-CHP-11-SECT-4.3.3"/>Queue</h3></div></div></div><p><a id="I_indexterm11_id742926" class="indexterm"/> A <a id="I_indexterm11_id742937" class="indexterm"/><code class="literal">Queue</code> is a collection that acts like a buffer for elements. The queue maintains the insertion order of items placed into it and has the notion of a “head” item. Queues may be first in, first out (FIFO) or last in, first out (LIFO) depending on the implementation:</p><div class="variablelist"><dl><dt><span class="term"><code class="literal">public boolean offer( E element )</code><br/></span><span class="term"><code class="literal">public boolean add( E element )</code></span></dt><dd><p>The <a id="I_indexterm11_id742969" class="indexterm"/><code class="literal">offer()</code> method attempts to place the element into the queue, returning true if successful. Different <code class="literal">Queue</code> types may have different limits or restrictions on element types (including capacity). This method differs from the <a id="I_indexterm11_id742987" class="indexterm"/><code class="literal">add()</code> method inherited from <code class="literal">Collection</code> in that it returns a Boolean value instead of throwing an exception to indicate that the element cannot be accepted.</p></dd><dt><span class="term"><code class="literal">public E</code> <code class="literal">poll()</code><br/></span><span class="term"><code class="literal">public E remove()</code></span></dt><dd><p>The <a id="I_indexterm11_id743027" class="indexterm"/><code class="literal">poll()</code> method removes the element at the head of the queue and returns it. This method differs from the <code class="literal">Collection</code> method <a id="I_indexterm11_id743044" class="indexterm"/><code class="literal">remove()</code> in that if the queue is empty, <code class="literal">null</code> is returned instead of throwing an exception.</p></dd><dt><span class="term"><code class="literal">public E</code> <code class="literal">peek()</code></span></dt><dd><p><a id="I_indexterm11_id743076" class="indexterm"/>This method returns the head element <span class="emphasis"><em>without</em></span> removing it from the queue. If the queue is empty, <code class="literal">null</code> is returned.</p></dd></dl></div><p>Java 7 added <a id="I_indexterm11_id743094" class="indexterm"/><code class="literal">Deque</code>, which is a “double-ended” queue that supports adding, querying, and removing elements from either end of the queue (the head or the tail). <code class="literal">Dequeue</code> has versions of the queue methods—<code class="literal">offer</code>, <code class="literal">poll</code>, and <code class="literal">peek</code>—that operate on the first or last element: <a id="I_indexterm11_id743130" class="indexterm"/><code class="literal">offerFirst()</code>, <a id="I_indexterm11_id743141" class="indexterm"/><code class="literal">pollFirst()</code>, <a id="I_indexterm11_id743151" class="indexterm"/><code class="literal">peekFirst()</code>, <a id="I_indexterm11_id743162" class="indexterm"/><code class="literal">offerLast()</code>, <a id="I_indexterm11_id743173" class="indexterm"/><code class="literal">pollLast()</code>, <a id="I_indexterm11_id743183" class="indexterm"/><code class="literal">peekLast()</code>. Note that <code class="literal">Deque</code> extends <code class="literal">Queue</code> and so is still a type of <code class="literal">Queue</code>. If you use the plain <code class="literal">Queue</code> methods <code class="literal">offer()</code>, <a id="I_indexterm11_id743221" class="indexterm"/><code class="literal">poll()</code>, and <a id="I_indexterm11_id743231" class="indexterm"/><code class="literal">peek()</code> on a <code class="literal">Deque</code>, they operate as a FIFO queue. Specifically, calling <code class="literal">offer()</code> is equivalent to <code class="literal">offerLast()</code> and calling <code class="literal">poll()</code> or <code class="literal">peek()</code> is the same as calling <code class="literal">pollFirst()</code> or <code class="literal">peekFirst()</code>, respectively.</p><p>Finally, Java has a legacy <a id="I_indexterm11_id743282" class="indexterm"/><code class="literal">Stack</code> class that acts as a LIFO queue with “push” and “pop” operations, but <code class="literal">Deque</code> is generally better and should serve as a general replacement for <code class="literal">Stack</code>. Simply use <a id="I_indexterm11_id743306" class="indexterm"/><code class="literal">addFirst()</code> for “push” and <code class="literal">pollFirst()</code> for “pop.”</p></div><div class="sect3" title="BlockingQueue"><div class="titlepage"><div><div><h3 class="title"><a id="learnjava3-CHP-11-SECT-4.3.4"/>BlockingQueue</h3></div></div></div><p><a id="I_indexterm11_id743329" class="indexterm"/> <a id="I_indexterm11_id743340" class="indexterm"/> <code class="literal">BlockingQueue</code> is part of the <a id="I_indexterm11_id743353" class="indexterm"/><code class="literal">java.util.concurrent</code> package. It extends the <code class="literal">Queue</code> interface for queues that may have a fixed capacity or other time-based limitations and allows the user to block, waiting for insertion of an item or for an available item to retrieve. It adds timed wait versions of <a id="I_indexterm11_id743372" class="indexterm"/><code class="literal">offer()</code> and <a id="I_indexterm11_id743382" class="indexterm"/><code class="literal">poll()</code> and additional, blocking <a id="I_indexterm11_id743393" class="indexterm"/><code class="literal">take()</code> and <a id="I_indexterm11_id743403" class="indexterm"/><code class="literal">put()</code> methods:</p><div class="variablelist"><dl><dt><span class="term"><code class="literal">public boolean offer( E element, long time, TimeUnit units )</code></span></dt><dd><p>This method attempts to place the element into the queue, just like the method of the base <code class="literal">Queue</code> interface, but blocks for up to the specified period of time as it waits for space to become available.</p></dd><dt><span class="term"><code class="literal">public E poll( long time, timeUnit unit )</code></span></dt><dd><p>This method attempts to remove the element at the head of the queue, just like the method of the base <code class="literal">Queue</code> interface, but blocks for up to the specified period of time as it waits for an element to become available.</p></dd><dt><span class="term"><code class="literal">public E take()</code></span></dt><dd><p>This method retrieves the element at the head of the queue, blocking if necessary until one becomes available.</p></dd><dt><span class="term"><code class="literal">public void put( E element )</code></span></dt><dd><p>This method adds an element to the queue, blocking if necessary until space becomes available.</p></dd><dt><span class="term"><code class="literal">public boolean add( E element )</code></span></dt><dd><p>This method attempts to add an element to the queue immediately. If successful, it returns <code class="literal">true</code>. If no space is available, it throws an <a id="I_indexterm11_id743488" class="indexterm"/><code class="literal">IllegalStateException</code>. This method is useful for cases where you are not expecting the queue to ever reject an item.<a id="I_indexterm11_id743501" class="indexterm"/></p></dd></dl></div></div></div><div class="sect2" title="The Map Interface"><div class="titlepage"><div><div><h2 class="title"><a id="learnjava3-CHP-11-SECT-4.4"/>The Map Interface</h2></div></div></div><p><a id="idx10606" class="indexterm"/> <a id="idx10618" class="indexterm"/> <a id="idx10658" class="indexterm"/>The Collections Framework also includes the <code class="literal">java.util.Map</code>, which is a collection of key/value pairs. Other names for map are “dictionary” or “associative array.” Maps store and retrieve elements with key values; they are very useful for things like caches or minimalist databases. When you store a value in a map, you associate a key object with a value. When you need to look up the value, the map retrieves it using the key.</p><p>With generics, a <code class="literal">Map</code> type is parameterized with two types: one for the keys and one for the values. The following snippet uses a <code class="literal">HashMap</code>, which is an efficient type of map implementation that we’ll discuss later:</p><a id="I_11_tt714"/><pre class="programlisting"> <code class="n">Map</code><code class="o">&lt;</code><code class="n">String</code><code class="o">,</code> <code class="n">Date</code><code class="o">&gt;</code> <code class="n">dateMap</code> <code class="o">=</code> <code class="k">new</code> <code class="n">HashMap</code><code class="o">&lt;</code><code class="n">String</code><code class="o">,</code> <code class="n">Date</code><code class="o">&gt;();</code> <code class="n">dateMap</code><code class="o">.</code><code class="na">put</code><code class="o">(</code> <code class="s">"today"</code><code class="o">,</code> <code class="k">new</code> <code class="n">Date</code><code class="o">()</code> <code class="o">);</code> <code class="n">Date</code> <code class="n">today</code> <code class="o">=</code> <code class="n">dateMap</code><code class="o">.</code><code class="na">get</code><code class="o">(</code> <code class="s">"today"</code> <code class="o">);</code></pre><p>In legacy code, maps simply map <code class="literal">Object</code> types to <code class="literal">Object</code> types and require the appropriate cast to retrieve values.</p><p>The basic operations on <code class="literal">Map</code> are straightforward. In the following methods, the type <code class="literal">K</code> refers to the key parameter type and the type <code class="literal">V</code> refers to the value parameter type:</p><div class="variablelist"><dl><dt><span class="term"><code class="literal">public V put( K</code> <em class="replaceable"><code>key</code></em> <code class="literal">, V</code> <em class="replaceable"><code>value</code></em> <code class="literal">)</code></span></dt><dd><p><a id="I_indexterm11_id743650" class="indexterm"/>This method adds the specified key/value pair to the map. If the map already contains a value for the specified key, the old value is replaced and returned as the result.</p></dd><dt><span class="term"><code class="literal">public V get( K</code> <em class="replaceable"><code>key</code></em> <code class="literal">)</code></span></dt><dd><p><a id="I_indexterm11_id743675" class="indexterm"/>This method retrieves the value corresponding to <code class="literal">key</code> from the map.</p></dd><dt><span class="term"><code class="literal">public V remove( K</code> <em class="replaceable"><code>key</code></em> <code class="literal">)</code></span></dt><dd><p><a id="I_indexterm11_id743706" class="indexterm"/>This method removes the value corresponding to <code class="literal">key</code> from the map. The value removed is returned.</p></dd><dt><span class="term"><code class="literal">public int size()</code></span></dt><dd><p><a id="I_indexterm11_id743730" class="indexterm"/>Use this method to find the number of key/value pairs in this map.</p></dd></dl></div><p>You can retrieve all the keys or values in the map:</p><div class="variablelist"><dl><dt><span class="term"><code class="literal">public Set keySet()</code></span></dt><dd><p><a id="I_indexterm11_id743751" class="indexterm"/>This method returns a <code class="literal">Set</code> that contains all the keys in this map.</p></dd><dt><span class="term"><code class="literal">public Collection values()</code></span></dt><dd><p><a id="I_indexterm11_id743773" class="indexterm"/>Use this method to retrieve all the values in this map. The returned <code class="literal">Collection</code> can contain duplicate elements.</p></dd></dl></div><p><code class="literal">Map</code> has one child interface, <a id="I_indexterm11_id743792" class="indexterm"/><code class="literal">SortedMap</code>. A <code class="literal">SortedMap</code> maintains its key/value pairs sorted in a particular order according to the key values. It provides the <a id="I_indexterm11_id743809" class="indexterm"/><code class="literal">subMap()</code>, <a id="I_indexterm11_id743820" class="indexterm"/><code class="literal">headMap()</code>, and <a id="I_indexterm11_id743830" class="indexterm"/><code class="literal">tailMap()</code> methods for retrieving sorted map subsets. Like <a id="I_indexterm11_id743841" class="indexterm"/><code class="literal">SortedSet</code>, it also provides a <code class="literal">comparator()</code> method, which returns an object that determines how the map keys are sorted. We’ll talk more about that later. Java 7 adds a <a id="I_indexterm11_id743860" class="indexterm"/><code class="literal">NavigableMap</code> with functionality parallel to that of <code class="literal">NavigableSet</code>; namely, it adds methods to search the sorted elements for an element greater or lesser than a target value.</p><p>Finally, we should make it clear that although related, <code class="literal">Map</code> is not literally a type of <code class="literal">Collection</code> (<code class="literal">Map</code> does not extend the <code class="literal">Collection</code> interface). You might wonder why. All of the methods of the <code class="literal">Collection</code> interface would appear to make sense for <code class="literal">Map</code>, except for <code class="literal">iterator()</code>. A <code class="literal">Map</code>, again, has two sets of objects: keys and values, and separate iterators for each. This is why a <code class="literal">Map</code> does not implement <code class="literal">Collection</code>.</p><p>One more note about maps: some map implementations (including Java’s standard <code class="literal">HashMap</code>) allow <code class="literal">null</code> to be used as a key or value, but others may not.</p><div class="sect3" title="ConcurrentMap"><div class="titlepage"><div><div><h3 class="title"><a id="learnjava3-CHP-11-SECT-4.4.1"/>ConcurrentMap</h3></div></div></div><p><a id="idx10610" class="indexterm"/>The <code class="literal">ConcurrentMap</code> interface is part of the <code class="literal">java.util.concurrent</code> package. It extends the base <code class="literal">Map</code> interface and adds atomic put, remove, and replace functionality that is useful for concurrent programming:</p><div class="variablelist"><dl><dt><span class="term"><code class="literal">public V putIfAbsent( K key, V value )</code></span></dt><dd><p><a id="I_indexterm11_id743996" class="indexterm"/>This method associates the value with the key only if the key was not already in use. If the key exists, no action is taken. If the key does not exist, it is created. The resulting value (<code class="literal">existing</code> or <code class="literal">new</code>) is returned.</p></dd><dt><span class="term"><code class="literal">public boolean remove( Object key, Object value )</code></span></dt><dd><p><a id="I_indexterm11_id744024" class="indexterm"/>This method removes the mapping (key and value) only if the current value associated with the key equals the supplied value. It returns <code class="literal">true</code> if the value was removed, <code class="literal">fals