1 <?xml version="1.0" encoding="utf-8"?>
   2 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
   3     "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
   4 
   5 <!--
   6  Copyright (c) 1998, 2017, Oracle and/or its affiliates. All rights reserved.
   7  DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   8 
   9  This code is free software; you can redistribute it and/or modify it
  10  under the terms of the GNU General Public License version 2 only, as
  11  published by the Free Software Foundation.  Oracle designates this
  12  particular file as subject to the "Classpath" exception as provided
  13  by Oracle in the LICENSE file that accompanied this code.
  14 
  15  This code is distributed in the hope that it will be useful, but WITHOUT
  16  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  17  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  18  version 2 for more details (a copy is included in the LICENSE file that
  19  accompanied this code).
  20 
  21  You should have received a copy of the GNU General Public License version
  22  2 along with this work; if not, write to the Free Software Foundation,
  23  Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  24 
  25  Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  26  or visit www.oracle.com if you need additional information or have any
  27  questions.
  28 -->
  29 
  30 <html lang="en-US" xmlns="http://www.w3.org/1999/xhtml" xml:lang=
  31 "en-US">
  32 <head>
  33 <title>Java Collections API Design FAQ</title>
  34 </head>
  35 <body>
  36 <h2>Java Collections API Design FAQ</h2>
  37 <!-- Body text begins here -->
  38 <hr />
  39 This document answers frequently asked questions concerning the
  40 design of the Java collections framework. It is derived from the
  41 large volume of traffic on the collections-comments alias. It
  42 serves as a design rationale for the collections framework.
  43 <h3>Core Interfaces - General Questions</h3>
  44 <ol>
  45 <li><a href="#a1"><b>Why don't you support immutability directly in
  46 the core collection interfaces so that you can do away with
  47 <em>optional operations</em> (and
  48 UnsupportedOperationException)?</b></a></li>
  49 <li><a href="#a2"><b>Won't programmers have to surround any code
  50 that calls optional operations with a try-catch clause in case they
  51 throw an UnsupportedOperationException?</b></a></li>
  52 <li><a href="#a3"><b>Why isn't there a core interface for "bags"
  53 (AKA multisets)?</b></a></li>
  54 <li><a href="#a28"><b>Why didn't you use "Beans-style names" for
  55 consistency?</b></a></li>
  56 </ol>
  57 <h3>Collection Interface</h3>
  58 <ol>
  59 <li><a href="#a5"><b>Why doesn't Collection extend Cloneable and
  60 Serializable?</b></a></li>
  61 <li><a href="#a6"><b>Why don't you provide an "apply" method in
  62 Collection to apply a given method ("upcall") to all the elements
  63 of the Collection?</b></a></li>
  64 <li><a href="#a7"><b>Why didn't you provide a "Predicate" interface,
  65 and related methods (e.g., a method to find the first element in
  66 the Collection satisfying the predicate)?</b></a></li>
  67 <li><a href="#a8"><b>Why don't you provide a form of the addAll
  68 method that takes an Enumeration (or an Iterator)?</b></a></li>
  69 <li><a href="#a9"><b>Why don't the concrete implementations in the
  70 JDK have Enumeration (or Iterator) constructors?</b></a></li>
  71 <li><a href="#a10"><b>Why don't you provide an Iterator.add
  72 method?</b></a></li>
  73 </ol>
  74 <h3>List Interface</h3>
  75 <ol>
  76 <li><a href="#a11"><b>Why don't you rename the List interface to
  77 Sequence; doesn't "list" generally suggest "linked list"? Also,
  78 doesn't it conflict with java.awt.List?</b></a></li>
  79 <li><a href="#a12"><b>Why don't you rename List's set method to
  80 replace, to avoid confusion with Set.</b></a></li>
  81 </ol>
  82 <h3>Map Interface</h3>
  83 <ol>
  84 <li><a href="#a14"><b>Why doesn't Map extend
  85 Collection?</b></a></li>
  86 </ol>
  87 <h3>Iterator Interface</h3>
  88 <ol>
  89 <li><a href="#a18"><b>Why doesn't Iterator extend
  90 Enumeration?</b></a></li>
  91 <li><a href="#a19"><b>Why don't you provide an Iterator.peek method
  92 that allows you to look at the next element in an iteration without
  93 advancing the iterator?</b></a></li>
  94 </ol>
  95 <h3>Miscellaneous</h3>
  96 <ol>
  97 <li><a href="#a23"><b>Why did you write a new collections framework
  98 instead of adopting JGL (a preexisting collections package from
  99 ObjectSpace, Inc.) into the JDK?</b></a></li>
 100 <li><a href="#a26"><b>Why don't you eliminate all of the methods and
 101 classes that return "views" (Collections backed by other
 102 collection-like objects). This would greatly reduce
 103 aliasing.</b></a></li>
 104 <li><a href="#a27"><b>Why don't you provide for "observable"
 105 collections that send out Events when they're
 106 modified?</b></a></li>
 107 </ol>
 108 <hr size="3" noshade="noshade" />
 109 <h3>Core Interfaces - General Questions</h3>
 110 <ol>
 111 <li><a name="a1" id="a1"><b>Why don't you support immutability
 112 directly in the core collection interfaces so that you can do away
 113 with <em>optional operations</em> (and
 114 UnsupportedOperationException)?</b></a>
 115 <p>This is the most controversial design decision in the whole API.
 116 Clearly, static (compile time) type checking is highly desirable,
 117 and is the norm in Java. We would have supported it if we believed
 118 it were feasible. Unfortunately, attempts to achieve this goal
 119 cause an explosion in the size of the interface hierarchy, and do
 120 not succeed in eliminating the need for runtime exceptions (though
 121 they reduce it substantially).</p>
 122 <p>Doug Lea, who wrote a popular Java collections package that did
 123 reflect mutability distinctions in its interface hierarchy, no
 124 longer believes it is a viable approach, based on user experience
 125 with his collections package. In his words (from personal
 126 correspondence) "Much as it pains me to say it, strong static
 127 typing does not work for collection interfaces in Java."</p>
 128 <p>To illustrate the problem in gory detail, suppose you want to
 129 add the notion of modifiability to the Hierarchy. You need four new
 130 interfaces: ModifiableCollection, ModifiableSet, ModifiableList,
 131 and ModifiableMap. What was previously a simple hierarchy is now a
 132 messy heterarchy. Also, you need a new Iterator interface for use
 133 with unmodifiable Collections, that does not contain the remove
 134 operation. Now can you do away with UnsupportedOperationException?
 135 Unfortunately not.</p>
 136 <p>Consider arrays. They implement most of the List operations, but
 137 not remove and add. They are "fixed-size" Lists. If you want to
 138 capture this notion in the hierarchy, you have to add two new
 139 interfaces: VariableSizeList and VariableSizeMap. You don't have to
 140 add VariableSizeCollection and VariableSizeSet, because they'd be
 141 identical to ModifiableCollection and ModifiableSet, but you might
 142 choose to add them anyway for consistency's sake. Also, you need a
 143 new variety of ListIterator that doesn't support the add and remove
 144 operations, to go along with unmodifiable List. Now we're up to ten
 145 or twelve interfaces, plus two new Iterator interfaces, instead of
 146 our original four. Are we done? No.</p>
 147 <p>Consider logs (such as error logs, audit logs and journals for
 148 recoverable data objects). They are natural append-only sequences,
 149 that support all of the List operations except for remove and set
 150 (replace). They require a new core interface, and a new
 151 iterator.</p>
 152 <p>And what about immutable Collections, as opposed to unmodifiable
 153 ones? (i.e., Collections that cannot be changed by the client AND
 154 will never change for any other reason). Many argue that this is
 155 the most important distinction of all, because it allows multiple
 156 threads to access a collection concurrently without the need for
 157 synchronization. Adding this support to the type hierarchy requires
 158 four more interfaces.</p>
 159 <p>Now we're up to twenty or so interfaces and five iterators, and
 160 it's almost certain that there are still collections arising in
 161 practice that don't fit cleanly into any of the interfaces. For
 162 example, the <em>collection-views</em> returned by Map are natural
 163 delete-only collections. Also, there are collections that will
 164 reject certain elements on the basis of their value, so we still
 165 haven't done away with runtime exceptions.</p>
 166 <p>When all was said and done, we felt that it was a sound
 167 engineering compromise to sidestep the whole issue by providing a
 168 very small set of core interfaces that can throw a runtime
 169 exception.</p>
 170 </li>
 171 <li><a name="a2" id="a2"><b>Won't programmers have to surround any
 172 code that calls optional operations with a try-catch clause in case
 173 they throw an UnsupportedOperationException?</b></a>
 174 <p>It was never our intention that programs should catch these
 175 exceptions: that's why they're unchecked (runtime) exceptions. They
 176 should only arise as a result of programming errors, in which case,
 177 your program will halt due to the uncaught exception.</p>
 178 </li>
 179 <li><a name="a3" id="a3"><b>Why isn't there a core interface for
 180 "bags" (AKA multisets)?</b></a>
 181 <p>The Collection interface provides this functionality. We are not
 182 providing any public implementations of this interface, as we think
 183 that it wouldn't be used frequently enough to "pull its weight." We
 184 occasionally return such Collections, which are implemented easily
 185 atop AbstractCollection (for example, the Collection returned by
 186 Map.values).</p>
 187 </li>
 188 <li><a name="a28" id="a28"><b>Why didn't you use "Beans-style
 189 names" for consistency?</b></a>
 190 <p>While the names of the new collections methods do not adhere to
 191 the "Beans naming conventions", we believe that they are
 192 reasonable, consistent and appropriate to their purpose. It should
 193 be remembered that the Beans naming conventions do not apply to the
 194 JDK as a whole; the AWT did adopt these conventions, but that
 195 decision was somewhat controversial. We suspect that the
 196 collections APIs will be used quite pervasively, often with
 197 multiple method calls on a single line of code, so it is important
 198 that the names be short. Consider, for example, the Iterator
 199 methods. Currently, a loop over a collection looks like this:</p>
 200 <pre>
 201     for (Iterator i = c.iterator(); i.hasNext(); )
 202         System.out.println(i.next());
 203 </pre>
 204 Everything fits neatly on one line, even if the Collection name is
 205 a long expression. If we named the methods "getIterator",
 206 "hasNextElement" and "getNextElement", this would no longer be the
 207 case. Thus, we adopted the "traditional" JDK style rather than the
 208 Beans style.</li>
 209 </ol>
 210 <hr />
 211 <h3>Collection Interface</h3>
 212 <ol>
 213 <li><a name="a5" id="a5"><b>Why doesn't Collection extend Cloneable
 214 and Serializable?</b></a>
 215 <p>Many Collection implementations (including all of the ones
 216 provided by the JDK) will have a public clone method, but it would
 217 be mistake to require it of all Collections. For example, what does
 218 it mean to clone a Collection that's backed by a terabyte SQL
 219 database? Should the method call cause the company to requisition a
 220 new disk farm? Similar arguments hold for serializable.</p>
 221 <p>If the client doesn't know the actual type of a Collection, it's
 222 much more flexible and less error prone to have the client decide
 223 what type of Collection is desired, create an empty Collection of
 224 this type, and use the addAll method to copy the elements of the
 225 original collection into the new one.</p>
 226 </li>
 227 <li><a name="a6" id="a6"><b>Why don't you provide an "apply" method
 228 in Collection to apply a given method ("upcall") to all the
 229 elements of the Collection?</b></a>
 230 <p>This is what is referred to as an "Internal Iterator" in the
 231 "Design Patterns" book (Gamma et al.). We considered providing it,
 232 but decided not to as it seems somewhat redundant to support
 233 internal and external iterators, and Java already has a precedent
 234 for external iterators (with Enumerations). The "throw weight" of
 235 this functionality is increased by the fact that it requires a
 236 public interface to describe upcalls.</p>
 237 </li>
 238 <li><a name="a7" id="a7"><b>Why didn't you provide a "Predicate"
 239 interface, and related methods (e.g., a method to find the first
 240 element in the Collection satisfying the predicate)?</b></a>
 241 <p>It's easy to implement this functionality atop Iterators, and
 242 the resulting code may actually look cleaner as the user can inline
 243 the predicate. Thus, it's not clear whether this facility pulls its
 244 weight. It could be added to the Collections class at a later date
 245 (implemented atop Iterator), if it's deemed useful.</p>
 246 </li>
 247 <li><a name="a8" id="a8"><b>Why don't you provide a form of the
 248 addAll method that takes an Enumeration (or an Iterator)?</b></a>
 249 <p>Because we don't believe in using Enumerations (or Iterators) as
 250 "poor man's collections." This was occasionally done in prior
 251 releases, but now that we have the Collection interface, it is the
 252 preferred way to pass around abstract collections of objects.</p>
 253 </li>
 254 <li><a name="a9" id="a9"><b>Why don't the concrete implementations
 255 in the JDK have Enumeration (or Iterator) constructors?</b></a>
 256 <p>Again, this is an instance of an Enumeration serving as a "poor
 257 man's collection" and we're trying to discourage that. Note
 258 however, that we strongly suggest that all concrete implementations
 259 should have constructors that take a Collection (and create a new
 260 Collection with the same elements).</p>
 261 </li>
 262 <li><a name="a10" id="a10"><b>Why don't you provide an Iterator.add
 263 method?</b></a>
 264 <p>The semantics are unclear, given that the contract for Iterator
 265 makes no guarantees about the order of iteration. Note, however,
 266 that ListIterator does provide an add operation, as it does
 267 guarantee the order of the iteration.</p>
 268 </li>
 269 </ol>
 270 <hr />
 271 <h3>List Interface</h3>
 272 <ol>
 273 <li><a name="a11" id="a11"><b>Why don't you rename the List
 274 interface to Sequence; doesn't "list" generally suggest "linked
 275 list"? Also, doesn't it conflict with java.awt.List?</b></a>
 276 <p>People were evenly divided as to whether List suggests linked
 277 lists. Given the implementation naming convention,
 278 &lt;<em>Implementation</em>&gt;&lt;<em>Interface</em>&gt;, there
 279 was a strong desire to keep the core interface names short. Also,
 280 several existing names (AbstractSequentialList, LinkedList) would
 281 have been decidedly worse if we changed List to Sequence. The
 282 naming conflict can be dealt with by the following incantation:</p>
 283 <pre>
 284     import java.util.*;
 285     import java.awt.*;
 286     import java.util.List;   // Dictates interpretation of "List"
 287 </pre></li>
 288 <li><a name="a12" id="a12"><b>Why don't you rename List's set
 289 method to replace, to avoid confusion with Set.</b></a>
 290 <p>It was decided that the "set/get" naming convention was strongly
 291 enough enshrined in the language that we'd stick with it.</p>
 292 </li>
 293 </ol>
 294 <hr />
 295 <h3>Map Interface</h3>
 296 <ol>
 297 <li><a name="a14" id="a14"><b>Why doesn't Map extend
 298 Collection?</b></a>
 299 <p>This was by design. We feel that mappings are not collections
 300 and collections are not mappings. Thus, it makes little sense for
 301 Map to extend the Collection interface (or vice versa).</p>
 302 <p>If a Map is a Collection, what are the elements? The only
 303 reasonable answer is "Key-value pairs", but this provides a very
 304 limited (and not particularly useful) Map abstraction. You can't
 305 ask what value a given key maps to, nor can you delete the entry
 306 for a given key without knowing what value it maps to.</p>
 307 <p>Collection could be made to extend Map, but this raises the
 308 question: what are the keys? There's no really satisfactory answer,
 309 and forcing one leads to an unnatural interface.</p>
 310 <p>Maps can be <em>viewed</em> as Collections (of keys, values, or
 311 pairs), and this fact is reflected in the three "Collection view
 312 operations" on Maps (keySet, entrySet, and values). While it is, in
 313 principle, possible to view a List as a Map mapping indices to
 314 elements, this has the nasty property that deleting an element from
 315 the List changes the Key associated with every element before the
 316 deleted element. That's why we don't have a map view operation on
 317 Lists.</p>
 318 </li>
 319 </ol>
 320 <hr />
 321 <h3>Iterator Interface</h3>
 322 <ol>
 323 <li><a name="a18" id="a18"><b>Why doesn't Iterator extend
 324 Enumeration?</b></a>
 325 <p>We view the method names for Enumeration as unfortunate. They're
 326 very long, and very frequently used. Given that we were adding a
 327 method and creating a whole new framework, we felt that it would be
 328 foolish not to take advantage of the opportunity to improve the
 329 names. Of course we could support the new and old names in
 330 Iterator, but it doesn't seem worthwhile.</p>
 331 </li>
 332 <li><a name="a19" id="a19"><b>Why don't you provide an
 333 Iterator.peek method that allows you to look at the next element in
 334 an iteration without advancing the iterator?</b></a>
 335 <p>It can be implemented atop the current Iterators (a similar
 336 pattern to java.io.PushbackInputStream). We believe that its use
 337 would be rare enough that it isn't worth including in the interface
 338 that everyone has to implement.</p>
 339 </li>
 340 </ol>
 341 <hr />
 342 <h3>Miscellaneous</h3>
 343 <ol>
 344 <li><a name="a23" id="a23"><b>Why did you write a new collections
 345 framework instead of adopting JGL (a preexisting collections
 346 package from ObjectSpace, Inc.) into the JDK?</b></a>
 347 <p>If you examine the goals for our Collections framework (in the
 348 Overview), you'll see that we are not really "playing in the same
 349 space" as JGL. Quoting from the "Design Goals" Section of the Java
 350 Collections Overview: "Our main design goal was to produce an API
 351 that was reasonably small, both in size, and (more importantly) in
 352 'conceptual weight.'"</p>
 353 <p>JGL consists of approximately 130 classes and interfaces; its
 354 main goal was consistency with the C++ Standard Template Library
 355 (STL). This was <em>not</em> one of our goals. Java has
 356 traditionally stayed away from C++'s more complex features (e.g.,
 357 multiple inheritance, operator overloading). Our entire framework,
 358 including all infrastructure, contains approximately 25 classes and
 359 interfaces.</p>
 360 <p>While this may cause some discomfort for some C++ programmers,
 361 we feel that it will be good for Java in the long run. As the Java
 362 libraries mature, they inevitably grow, but we are trying as hard
 363 as we can to keep them small and manageable, so that Java continues
 364 to be an easy, fun language to learn and to use.</p>
 365 </li>
 366 <li><a name="a26" id="a26"><b>Why don't you eliminate all of the
 367 methods and classes that return "views" (Collections backed by
 368 other collection-like objects). This would greatly reduce
 369 aliasing.</b></a>
 370 <p>Given that we provide core collection interfaces behind which
 371 programmers can "hide" their own implementations, there will be
 372 aliased collections whether the JDK provides them or not.
 373 Eliminating all views from the JDK would greatly increase the cost
 374 of common operations like making a Collection out of an array, and
 375 would do away with many useful facilities (like synchronizing
 376 wrappers). One view that we see as being particularly useful is
 377 <a href=
 378 "../List.html#subList-int-int-">List.subList</a>.
 379 The existence of this method means that people who write methods
 380 taking List on input do not have to write secondary forms taking an
 381 offset and a length (as they do for arrays).</p>
 382 </li>
 383 <li><a name="a27" id="a27"><b>Why don't you provide for
 384 "observable" collections that send out Events when they're
 385 modified?</b></a>
 386 <p>Primarily, resource constraints. If we're going to commit to
 387 such an API, it has to be something that works for everyone, that
 388 we can live with for the long haul. We may provide such a facility
 389 some day. In the meantime, it's not difficult to implement such a
 390 facility on top of the public APIs.</p>
 391 </li>
 392 </ol>
 393 <hr />
 394 <p style="font-size:smaller">
 395 Copyright &copy; 1998, 2017, Oracle and/or its affiliates. 500 Oracle Parkway<br />
 396     Redwood Shores, CA 94065 USA. All rights reserved.</p>
 397 <!-- Body text ends here -->
 398 </body>
 399 </html>