Introduction to containers
To me, container classes are one of the most powerful tools for raw development because they significantly increase your programming muscle. The Java 2 containers represent a thorough redesign[55] of the rather poor showings in Java 1.0 and 1.1. Some of the redesign makes things tighter and more sensible. It also fills out the functionality of the containers library, providing the behavior of linked lists, queues, and deques (double-ended queues, pronounced “decks”).
The design of a containers library is difficult (true of most library design problems). In C++, the container classes covered the bases with many different classes. This was better than what was available prior to the C++ container classes (nothing), but it didn’t translate well into Java. At the other extreme, I’ve seen a containers library that consists of a single class, “container,” which acts like both a linear sequence and an associative array at the same time. The Java 2 container library strikes a balance: the full functionality that you expect from a mature container library, but easier to learn and use than the C++ container classes and other similar container libraries. The result can seem a bit odd in places. Unlike some of the decisions made in the early Java libraries, these oddities were not accidents, but carefully considered decisions based on trade-offs in complexity. It might take you a little while to get comfortable with some aspects of the library, but I think you’ll find yourself rapidly acquiring and using these new tools.
The Java 2 container library takes the issue of “holding your objects” and divides it into two distinct concepts:
- Collection:
a group of individual elements, often with some rule applied to them. A
List must hold the elements in a particular sequence, and a Set
cannot have any duplicate elements. (A bag, which is not implemented in
the Java container library—since Lists provide you with enough of
that functionality—has no such rules.)
- Map: a group of key-value object pairs. At first glance, this might
seem like it ought to be a Collection of pairs, but when you try to
implement it that way the design gets awkward, so it’s clearer to make it
a separate concept. On the other hand, it’s convenient to look at portions
of a Map by creating a Collection to represent that portion. Thus,
a Map can return a Set of its keys, a Collection of its
values, or a Set of its pairs. Maps, like arrays, can easily be
expanded to multiple dimensions without adding new concepts; you simply make a
Map whose values are Maps (and the values of those
Maps can be Maps, etc.).