By Tony Bevis on Sunday, 15 October 2023
Category: Java

Java programming course: 11.1 Collections and maps

 In the previous lesson you learnt how to debug a class.

Collections and maps

The Java Collections Framework provides a set of classes and interfaces that let you manage groups of related objects in a more powerful way than arrays.

In this section you will learn:

The collections framework

In Section 6 you created the Pen class that defined an array to store a group of Animal objects. While arrays are efficient, you saw a particular downside in that after you have declared the number of elements the array will contain you cannot change that amount thereafter. The capacity of ten chosen for each pen in the zoo was completely arbitrary. While it may be sufficient to store the number of lions, the penguin pen is likely to need to be able to store several dozen.

Rather than having to guess a likely maximum and then have many null elements, a far more flexible approach is to make use of Java's collections framework. This incorporates several related classes and interfaces that enable you to store groups of objects, and which can dynamically expand or contract in size as required.

The root of the framework is an interface called Collection. If you look at the API for this interface you will see several methods, the most frequently used being:


The collection framework can be shown diagrammatically as in the following figure. Note that all the items shown are Java interfaces, and there are corresponding classes that implement the interfaces and which you actually use to hold the collection data: 

The main restriction of the collection classes is that they can only contain object references: primitives are not allowed. There is a simple workaround for this, however, since you can use the wrapper objects (Integer instead of int, for example), as described in Section 2.

The collections framework classes and interfaces are in the java.util package, so you will need to import this into the classes which make use of them.

Lists

The type of collection which most closely resembles an array is List, which contains several objects in the order in which they were added to the list. List is in fact another interface; the most used class that implements it is ArrayList. Here is an example of using ArrayList:


You should see the following output:

You will notice that lists store the objects in the order they were added, and that they can contain duplicate items, for example the word "be".

If you need to access a specific object in a list by its position, you can use the get() method passing the required index position. However, get() is defined in the List interface and not the Collection interface, so you would need to modify the declaration as follows:

You will now be able to invoke the get() method:

Since Java 7, it's unnecessary to include the type when instantiating a collection since it is inferred from the declaration. This means the declaration and instantiation of words can be as follows:

Note the empty angle-brackets that follow ArrayList.

You can also omit the types from the other collection types to be explained in subsequent sections, and we will do so for consistency.

Sets

A Set differs from a List in the following ways:


Replace the following statement:

With this:

The remainder of the code does not need to change. Your output may look like this:


If you want to ensure the objects are iterated using their natural ordering, specify a TreeSet rather than a HashSet. Because the set contains String objects, the natural ordering will be alphabetical:

The output should now be as follows:


Be aware that the HashSet class has better performance that TreeSet since it does not need to take steps to keep the objects in a particular order, so it is recommended that you only use TreeSet when you actually require the objects to be sorted.

Converting the Pen class to use a collection

You have seen that the collection classes offer greater flexibility than arrays when needing to store groups of objects. In terms of the Pen class that currently uses an array that can hold up to ten animals, the first decision that needs to be made is whether to use instead a List or a Set. To help answer this you can address the following questions:

  1. Does it make sense for the same animal to exist in the collection more than once?
  2. Does the sequence in which animals are added into the pen have any significance?
  3. Does it matter what sequence animals are retrieved from the pen?

It seems clear that that the answer to question 1 is that each individual animal can only exist once inside a pen. For question 2, there is no obvious significance to the order in which animals will be placed inside the pen, and likewise for question 3, there is no need to have to store them in any particular order. The conclusion, therefore, is that Set would be more appropriate than List, and that the Set does not need to be sorted. The best implementation class to achieve this would be HashSet. You are therefore now ready to start modifying the Pen class.

Because collections do not have an upper size limit you no longer need to specify an arbitrary capacity[1]. Remove the following statement from Pen:

[1] In a real pen there would, of course, be a maximum capacity based upon the physical dimensions of the pen and the animals it would contain. For simplicity, this will not be considered here.

The instance variable animals is currently declared to be an array of Animal objects, but it should now be a Collection of Animal objects. Change the declaration statement so it reads as follows:

You no longer need the instance variable to hold the next element index since collections will manage this internally. Remove the following declaration:

Change the constructor to instantiate the animals collection as a new unsorted set:

The add() method now simply needs to forward to the add() method of the collection object:

It is generally a good idea when providing an add() method to also provide a remove() method. Insert the new method below so that an Animal object can be removed from the pen:

The getAnimals() method currently returns an array, but it should instead return a collection. Change the method signature and the body to return the whole collection:

The getCount() method needs to be changed to return the size of the collection (i.e., the number of objects it currently contains):

It will prove useful later on for each animal to "know" what pen it is in. Add the following instance variable inside the Animal class:

Define a getter and setter method for the pen field:

It will be useful for the natural ordering of a Pen object to be alphabetically by the pen's name, so implement the Comparable interface:

And provide the required compareTo() method code:

In the next lesson we will make use of the Pen class in ZooAdministrator.

Next lesson: 11.2 Making use of Pen in ZooAdministrator 

Related Posts

Leave Comments