Goal:To learn more advanced techniques for container classes, and to learn generics, a compile-time check of object type.
Tutorial
Two very useful containers (collections of objects) are: API: ArrayList and API: HashMap
The ArrayList is similar to a Vector in that it can be treated as an array (in the sense indexing) or as a list (in the sense of insert/delete). HashMap is an implementation of a hash table, from a Data Structures course, that is, an object can be stored based on a key. Later, the object can be retrieved with the same key. You might recall the two implementations to take care of collisions (hash function returns the same index for different keys): probe for an empty spot in the table or maintain a linked list of the collisions. But it really doesn't matter: the HashMap class hides these details, we just care about put() and get() of our objects.
Recall the Person class from Ex1: Person.java
and the testing program from Ex5 on Vectors: VectorTest.java
Here is the equivalent program using an ArrayList: ArrayListTest.java
They are much the same with 3 main differences:
Here is a Generics Introduction and more details in a Generics Tutorial
As a reminder:
private Vector<Person> stack = new Vector<Person>(); // if homogeneous, only Persons private Vector<Object> stack = new Vector<Object>(); // if heterogeneous, any Object
The above is tested with a demo
Assignment
Copy Stack.java using Vector from Ex5: cp ../ex5/Stack.java .
Modify the code by replacing the Vector with an ArrayList. The ArrayListTest.java and API: ArrayList should help with the necessary method calls. Also, your ArrayList should use generics of <Person>. Because this is specifically for type Persons, push()/pop() can be either Person or Object. Your choice.
After that works, declare a HashMap in Stack.java, along with generics of <Person>. But note that API: HashMap has two fields: HashMap<K, V> where K is the type of Object that will be used as the key, and V is the type of value to be stored with the key. In our case: K=String (but it could be other Objects in other applications) and V=Person.
Now modify Stack.java to always put() into the HashMap for every push() and to remove() on every pop(). That is, besides maintaining a LIFO list (ArrayList), the Stack is also providing a direct indexing mechanism via HashMap. Although this is unusual for a Stack, it does illustrate the power of built-in classes like ArrayList and HashMap. And for a Person, what do you think the key would be?
Add two methods to your Stack class:
public Iterator arrayIterator() public Iterator hashIterator()
There are two data structures inside your Stack data structure: array list and a hash table. It is possible to request from these structures that they give you an Iterator. That is what the above methods should do. It is easy for an array list. Look at API: HashMap again. Hint: get a Collection, and then get an Iterator.
Now make a testing main(). Here is what the output should look like:
Iteration of the Stack's Array Name 1 10 Name 2 20 Name 3 30 Iteration of the Stack's Hash Name 2 20 Name 1 10 Name 3 30 Pop the Stack Name 3 30 Name 2 20 Name 1 10
Turn-In: Stack.java, including a commented-out listing of the resultant output.