Once you start to work with databases, you quickly come face to face with a seemingly simple problem: retrieving many rows. The problem arises when you don't know ahead of time how many rows you're going to retrieve. So, where do you put the data? Should you allocate a new row object for each row read in from the database? This can be unwieldy, not to say difficult, to code. Clearly, if you opt for a manual allocation solution, you'll be faced with complex potentially error-prone coding. Also, doing it this way seems a bit old-fashioned and reminiscent of the early days of C++ when you had to worry about dynamic allocation of arrays.
Similar issues arise when you are reading large quantities of data from a network interface. Wouldn't it be nice if you could just retrieve as much data as you like from the database and the containers into which you store it just grew as required? In both cases using Java collections, you can elegantly solve this problem.
A Java collection is a class that stores objects and, as you'll see, this abstraction provides powerful techniques for database interaction. Java collections work extremely well with iterators and help to solve our stated problem of unconstrained data retrieval. This article describes both collections and iterators and, because we will be relying on the classes to automatically increase the allocation, I'll describe some of the efficiency issues along the way.
Collection<T> and the Java Collection Framework
I won't spend too long on the theory of the Java collection framework. There are many Java books that cover this topic very well. Suffice to say that Java collections are part of a framework that provides an abstraction for the storage and manipulation of different types of objects. The highest level of the Java collection framework is an interface called Collection<T>. The T element can be any class that implements the Collection<T> interface.
There's nothing quite like a concrete example, so let's have a look at one of them: the ArrayList.