Summary: This laboratory provides some experience with doubly linked lists and with several capabilities of Java.
File ~walker/152/java-examples/DoubleOrderedList.java contains methods that comprise the beginning of a class that implements doubly-linked lists. Specifically, following the discussion from class, the DoubleOrderedList class contains the following methods:
This DoubleOrderedList class is very close to what was described in class, except that testing has been added in a main method.
The behavior you observed in step 1 is achieved by the try and catch statements located through the code. The basic idea is this:
The remove method of DoubleOrderedList provides a nice example. Within the remove method, a loop searches through the list to find the desired element. If the element is found, normal processing continues. However, if the element is not found, special action is needed. This is achieved with the statements:
if (current==null)
throw new NoSuchElementException
(item.toString()+" is not in the list!");
if (current.data.compareTo(item)>0)
throw new NoSuchElementException
(item.toString()+" is not in the list!");
The first of these tests indicates the item is not present, since the search continued through the entire list without finding the desired item. The second of these tests determines that searching went beyond where the desired item could possibly be found. In either case, the desired item is not present, and the code must signal normal processing cannot continue.
The signaling itself is accomplished with the statement
throw new NoSuchElementException
(item.toString()+" is not in the list!");
Here, the throw new indicates that a signal is needed. The Java langauge includes many built-in such signals, and the NoSuchElementException illustrates one of these built-in capabilities. As this code illustrates, an exception may take a parameter (a string), which will be passed along to the exception handler.
The main method illustrates how such thrown exceptions are handled. Specifically, within the switch statement, several list methods are utilized, and we know some of them may raise exceptions. Thus, we place the entire switch statement within a try block. This try block tells the machine that some events might occur in what follows. If an exception is raised, processing should jump out the block to what immediately follows: one or more catch statements.
Each catch statement specifies a possible exception and indicates what processing should do to recover. In this case, a message is printed, although the code could seek to correct the error. This example also illustrates how to retrieve the message connected to the thrown exception. In each case, a variable exc was declared in the catch statement, and that variable is used with a getMessage method.
While Java contains a large number of built-in exceptions, a programmer rarely uses very many.
Note that main does incomplete testing for this program, because not all methods in the class are checked.
In yesterday's class session, we discussed class hierarchies. This part of the lab presents an example of using one class to define another. In the jargon of object-oriented properties, the new class is called a subclass of the existing class, the old class is a superclass of the new class, and the new class inherits fields and methods from its superclass.
Class /home/walker/152/java-examples/MyFirstDoubleList.java is defined as a subclass of DoubleOrderedLlist using an extends clause at the start of the class defintion. That is, all data and methods of DoubleOrderedLlist extend to MyFirstDoubleList -- except where explicit changes or additions are made. In this case, method add is adjusted to allow the list to store duplicate elements, and a last method is added to print out the last item on the list. Also, since we want main to test DoubleOrderedLlist rather than DoubleOrderedLlist, the main method is adjusted slightly.
This document is available on the World Wide Web as
http://www.cs.grinnell.edu/~walker/courses/152.sp01/lab-doubly-linked-lists.html