Since this is the first exercise, we’ll keep it simple. You will take the code from the previous section and swap the implementation; that is, you will replace the LinkedList with an ArrayList. Because the code programs to an interface, you will be able to swap the implementation by changing a single line and adding an
Start by setting up your development environment. For all of the exercises, you will need to be able to compile and run Java code. I developed the examples using Java SE Development Kit 7. If you are using a more recent version, everything should still work. If you are using an older version, you might find some incompatibilities.
I recommend using an interactive development environment (IDE) that provides syntax checking, auto-completion, and source code refactoring. These features help you avoid errors or find them quickly. However, if you are preparing for a technical interview, remember that you will not have these tools during the interview, so you might also want to practice writing code without them.
If you have not already downloaded the code for this book, see the instructions in Section 0.1.
In the directory named code, you should find these files and directories:
- build.xml is an Ant file that makes it easier to compile and run the code.
- lib contains the libraries you’ll need (for this exercise, just JUnit).
- src contains the source code.
If you navigate into src/com/allendowney/thinkdast, you’ll find the source code for this exercise:
- ListClientExample.java contains the code from the previous section.
- ListClientExampleTest.java contains a JUnit test for ListClientExample.
Review ListClientExample and make sure you understand what it does. Then compile and run it. If you use Ant, you can navigate to the code directory and run ant ListClientExample.
You might get a warning like
List is a raw type. References to generic type List<E> should be parameterized.
To keep the example simple, I didn’t bother to specify the type of the elements in the list. If this warning bothers you, you can fix it by replacing each List or LinkedList with List<Integer> or LinkedList<Integer>.
Review ListClientExampleTest. It runs one test, which creates a ListClientExample, invokes getList, and then checks whether the result is an ArrayList. Initially, this test will fail because the result is a LinkedList, not an ArrayList.
Run this test and confirm that it fails.
This test makes sense for this exercise, but it is not a good example of a test. Good tests should check whether the class under test satisfies the requirements of the interface; they should not depend on the details of the implementation.
In the ListClientExample, replace LinkedList with ArrayList. You might have to add an
import statement. Compile and run ListClientExample. Then run the test again. With this change, the test should now pass.
To make this test pass, you only had to change LinkedList in the constructor; you did not have to change any of the places where List appears. What happens if you do? Go ahead and replace one or more appearances of List with ArrayList. The program should still work correctly, but now it is “overspecified”. If you change your mind in the future and want to swap the interface again, you would have to change more code.
In the ListClientExample constructor, what happens if you replace ArrayList with List? Why can’t you instantiate a List?