Part 1: Using the Hash Map
The Data
Using Hash Map
Understanding Hash Map
Part 2: Introducing JUnit
Stack, Queue, Priority Queue, Linked List; Vector
Version: 5.2.1

Lab 11

©2012 Felleisen, Proulx, et. al.

Working with HashMap: Overriding ’equals’

Goals: The goal of this lab is to learn to use the professional test harness JUnit. It is completely separated from the application code. It is designed to report not only the cases when the result of the test differs from the expected value, but also to report any exceptions the program would throw. The slight disadvantage is that it uses the Java equals method that by default only checks for the instance identity. To use the JUnit for the method tests similar to those we have done before we need to override the equals any time we wish to compare two instances of a class in a manner different from the strict instance identity.

However, each time we override the equals method we should make sure that the hashCode method is changed in a compatible way. That means that if two instances are equal under our definition of equals then the hashCode method for both instances must produce the same value.

We start with learning to use HashMap class. We then see how we can override the needed hashCode method. Finally, we also override the equals method to implement the equality comparison that best suits our problem.

You will use the work you do in this lab for the final assignment that deals with graph algorithms — to find a path from one city to another.

Part 1: Using the HashMap

Our goal is to design a program that would show us on a map the locations of the capitals of all 48 contiguous US states and show us how we can travel from any capital to another.

This problem can be abstracted to finding a path in a network of nodes connected with links — known in the combinatorial mathematics as a graph traversal problem. It is similar to finding out who will come to a party given by one person in a social network.

The Data

To provide real examples of data the provided code includes the (incomplete) definitions of the class City and the class State.

We now have all the data we need to proceed with learning about hash codes, equals, and JUnit.

Using HashMap

The class USmap contains only one field and a constructor. The field is defined as:

HashMap<City, State> states = new HashMap<City, State>();

The HashMap is designed to store the values of the type State, each corresponding to a unique key, an instance of a City — its capital.

Note: In reality this would not be a good choice to the keys for a HashMap — we do it to illustrate the problems that may come up.

Understanding HashMap

We will now experiment with HashMap to understand how changes in the equals method and the hashCode method affect its behavior.

Note: Read in "Effective Java" a detailed tutorial on overriding equals and hashCode.

Part 2: Introducing JUnit

You will now rewrite all your tests using the JUnit4. In the File menu select New then JUnitTestCase. The tests for each of the methods will then become one test case similar to this one:

/**

 * Testing the method toString

 */

public void testToString(){

    assertEquals("Hello: 1\n", this.hello1.toString());

    assertEquals("Hello: 3\n", this.hello3.toString());

}

We see that assertEquals calls are basically the same as the test methods for our test harnesses, they just don’t include the names of the tests. Try to see what happens when some of the tests fail, when a test throws an exception, and finally, make sure that at the end all tests succeed.

Ask for help, try things — make sure you can use JUnit, so you will not run into problems when working on the assignment and the final project.

Warning

Try to get as much as possible during the lab. Ask questions when you do not understand something. You will need what you learned in this lab for your final project.

Stack, Queue, Priority Queue, LinkedList; Vector

Look up the documentation for the following Java classes and interfaces: Stack, Queue, PriorityQueue, List, LinkedList, and Vector. Identify which of them represent interfaces, which represent abstract classes, and which provide a complete implementation that you can use in your program. Draw a class diagram that shows the relationship between these classes and interfaces.