Overview
The collections covered previously (Set, SortedSet, and List) do not map a key to an object. Such a capability is often required by applications that must quickly locate an object.
The following table is provided as a quick review of the behavior of the various interfaces of the Java Collections API :
Interface name
Ordered
Allows duplicates
Maps key to object
Collection
no
yes
no
List
yes
yes
no
Map
no
no
yes
Set
no
no
no
SortedMap
yes
no
yes
SortedSet
yes
no
no
In this lesson, the Map and SortedMap interfaces are presented.
The Map interface
Does NOT extend the Collection interface because its behavior is fundamentally different from that of a simple collection. It maps a key to a unique object within its collection.
Indicates the behavior of a collection of objects that is unsorted and does not allow duplicate objects. Some implementations allow an element within the collection to be a null object reference (such as HashMap). Others do not (such as Hashtable). The implementing classes will be covered shortly.
Has a number of required methods. The following are the most frequently used:
Method
Usage
clear()
Removes all objects from the collection
containsKey()
Returns true if a specified object is a key within the collection
containsValue()
Returns true if a specified object is a value within the collection
get()
Retrieves the object to which the specified key is mapped within the collection
isEmpty()
Returns true if the collection has no elements
keySet()
Returns a Set view of the keys within this collection
put()
Adds the specified object having the specified key value to the collection
remove()
Removes the object to which the specified key value is mapped from the collection
size()
Returns the number of elements in the collection
Many methods return a boolean value that indicates whether the operation was successful. Consult the Java API documentation for more details.
Example: This program uses a Map implemented as a HashMap to store some String objects in a collection and then permits the user to access individual elements directly.
import java.util.*;
public class App {
public static void main(String[] args) {
// Use a Map implemented as a HashMap (the actual location of each
// object will be determined by an internal algorithm).
Map myObjects = new HashMap();
// Loop to store String objects in the collection.
for (int i = 1; i <= 5; i++) {
myObjects.put(new Integer(i), new String("This is object " + i));
}
// Variables used for loop control and the object number to be read.
char again = 'y';
int objectNumber;
// Loop to look up one object.
lookUp:
do {
// Prompt for and read the object number.
System.out.print("Object number (1 to " + myObjects.size() + "): ");
objectNumber = Keyboard.readInt();
// If the object number is within the collection, display it.
// Otherwise, display an error message and continue the loop.
if (objectNumber >= 1 && objectNumber <= myObjects.size()) {
System.out.println("\tObject " + objectNumber + ": " +
(String) myObjects.get(new Integer(objectNumber)));
}
else {
System.out.println("\tInvalid object number");
continue lookUp;
}
// Ask the user if they want to look up another object.
System.out.print("Again? (Y/N): ");
again = Keyboard.readChar();
} while (again == 'Y' || again == 'y'); // Loop ask requested.
}
}Notes:
The HashMap implemented in this sample permits the storage of both a null key and a null object. If the implementing class was changed to a Hashtable, the program will run as before but a null key and a null object would not be permitted. It is not necessary to know the other internal differences between these two implementing classes.
The put() method requires two objects as parameters. The first object is the key and the second object is the value to which that key will be mapped within the collection.
The get() method requires a single object as a parameter. It is the key used to retrieve the unique object to which it is mapped within the the collection. When the object is retrieved, it is a generic Object and must be re-cast.
This sample takes great care to ensure that an invalid key is never used to retrieve an object. If an invalid key was used, the program would be terminated with an exception. We will cover exception handling in a later lesson.
The SortedMap interface
Is an extension of the Map interface to provide for an ordered collection.
Indicates the behavior of a collection of objects in which a key value is mapped to each object, duplicate objects are not allowed, and objects are maintained in ascending key sequence. Neither the key value or the object to which it is mapped may be null.
Has many useful methods. The most frequently used are as follows (with those in red being methods that expand upon those of the inherited Map interface):
Method
Usage
clear()
Removes all objects from the collection
containsKey()
Returns true if a specified object is a key within the collection
containsValue()
Returns true if a specified object is a value within the collection
firstKey()
Returns the first (lowest) key within this collection
get()
Retrieves the object to which the specified key is mapped within the collection
isEmpty()
Returns true if the collection has no elements
keySet()
Returns a Set view of the keys within this collection
lastKey()
Returns the last (highest) key within this collection
put()
Adds the specified object having the specified key value to the collection
remove()
Removes the object to which the specified key value is mapped from the collection
size()
Returns the number of elements in the collection
Many methods return a boolean value that indicates whether the operation was successful. Consult the Java API documentation for more details.
Example: This program uses a SortedMap implemented as a TreeMap to store some String objects in a collection, list them in ascending key sequence, and then permits the user to access individual elements directly.
import java.util.*;
public class App {
public static void main(String[] args) {
// Use a SortedMap implemented as a TreeMap (object values will be
// stored according to an internal algorithm and key values will be
// maintained in ascending key sequence).
SortedMap myObjects = new TreeMap();
// Loop to store String objects in the collection.
for (int i = 5; i >= 1; i--) {
myObjects.put(new Integer(i), new String("This is object " + i));
}
// Instantiate an Iterator on the collection's key set and use it
// to display all objects in the order of their keys.
Iterator pointer = myObjects.keySet().iterator();
System.out.println("The collection has these objects: ");
while (pointer.hasNext()) {
System.out.println("\t" + (String) myObjects.get(pointer.next()));
}
// Variables used for loop control and the object number to be read.
char again = 'y';
int objectNumber;
// Loop to look up one object.
lookUp:
do {
// Prompt for and read the object number.
System.out.print("Object number (1 to " + myObjects.size() + "): ");
objectNumber = Keyboard.readInt();
// If the object number is within the collection, display it.
// Otherwise, display an error message and continue the loop.
if (objectNumber >= 1 && objectNumber <= myObjects.size()) {
System.out.println("\tObject " + objectNumber + ": " +
(String) myObjects.get(new Integer(objectNumber)));
}
else {
System.out.println("\tInvalid object number");
continue lookUp;
}
// Ask the user if they want to look up another object.
System.out.print("Again? (Y/N): ");
again = Keyboard.readChar();
} while (again == 'Y' || again == 'y'); // Loop ask requested.
}
}Notes:
The TreeMap implemented in this sample will automatically maintain the key values of the collection in ascending key sequence.
The loop that loads the collection is coded to add objects in reverse key sequence. This is done to demonstrate that a SortedMap (such as TreeMap) automatically sorts the keys into ascending order whenever a new object is added.
To display all the collection's objects in ascending key sequence, an Iterator is constructed from the Set view of the collection's keys (obtained by calling the keySet() method). The Iterator is then used to traverse the set of keys and look up each object.
Some final thoughts on the Java Collections API
At this point, you will have a difficult time appreciating how powerful these tools really are. Later in the semester, we will revisit them to learn how an entire collection may be serialized (copied) to and from a disk file. A collection can also be serialized to and from a database (that is beyond the scope of this course). A collection can even be serialized as a packet of data in a client/server, networking environment.
Lab exercise for Ferris students
E-mail your answers to this assignment no later than the due date listed in the class schedule.
Review questions
True or False: A Map can be implemented as a TreeMap as shown by the statement
Map myMap = new TreeMap();
True
False
Assume that aPart is the reference of a Part object having an instance method named binNum() that returns the bin number of the part as an int value. If inventory is the reference of a Map collection, which one of the following statements would add aPart to the collection?
inventory.put(aPart, new Integer(aPart.binNum()));
inventory.add(new Integer(aPart.binNum()), aPart);
inventory.put(new Integer(aPart.binNum()), aPart);
inventory.add(aPart, new Integer(aPart.binNum()));
inventory.put(aPart.binNum(), aPart);
Assume that aPart is the reference of a Part object. If inventory is the reference of a Map collection, which one of the following statements would retrieve the Part object having a key value of 17 and assign it to aPart?
aPart = inventory.get(new Integer(17));
aPart = (Part) inventory.get(new Integer(17));
aPart = inventory.get(17);
aPart = (Part) inventory.get(17);
inventory.get(aPart, 17);
True or False: An Iterator can be used with an unsorted Map collection?
True
False