Some Last Thoughts
This chapter has gone on quite long enough, and I hope that what has come so far has con-
vinced you that the collections in Java are one of the good parts of the library. But before we
go on to something else, I need to mention a couple of things.
The first can be seen if we look at the signature of a method we used in our last formatting
examples, the addAll() method of TreeSet . Like all of the collections, TreeSet is generic,
but this method is generic in a somewhat odd way, with a signature of:
boolean addAll(Collection<? extends E> c)
The argument declaration is something that we haven't discussed thus far: a wildcard para-
meter. This parameter says that the argument being fed into the addAll() method has to be a
collection, and that collection must be made up of objects that have a type that extends the de-
clared type used to parameterize the TreeSet . In our case, this means that the TreeSet<Play-
er> that we declared can have sets of objects that extend the interface <Player> as well as
objects that simply implement exactly that interface. This is because the subtyping relation
that holds between classes does not transfer to collections of those classes. To get something
like that requires extra syntax in the generics systems. I won't go into all of the possibilities
here, but if you are going to implement a generic collection (as opposed to using such a col-
lection), you will need to consult more advanced writings to understand how this works.
Finally, I should note the possible use of one of the more peculiar exception classes in the
collections. This is the java.lang.UnsupportedOperationException , a runtime exception
that was introduced specially for the collections classes.
The motive for introducing this exception had to do with a common problem when designing
collection classes. There are all kinds of interrelationships between various kinds of collec-
tions that get used for specialized reasons. The obvious example is a standard Set , which al-
lows you to add, remove, and query for objects, along with a read-only Set (that allows query,
but no add or remove), the remove-only Set (that is created with some set of objects that can
be queried or removed, but never has new objects added), and the add-only Set (objects can
check in, but they can never check out).
Trying to model such variation in the type hierarchy of the collections can lead to a very messy
type system, if it can work at all. You can end up with lots of interfaces that have only a single
method, or class hierarchies that are deep and complex. Again, we run into the expressive lim-