> We successfully fixed this in one case by > creating a "Default Package", copying the ListWithCurrent and Node classes > into the default package, exporting those classes as .class files using the > option "use one directory" (I might be paraphrasing). This seemed to work. > > A little more detail: When you start up visual age you have to import your > java files into a package. If you create a package that you name yourself, > I think the package name gets attached to the class and netscape's version of > java gets confused. So the package that you import your classes into should > be a "Default Package" which is one of the options on the create package > window. > > I'm not sure if the "use one directory" option is neccessary.
Let me emphasize that the integration testing is not worth a great deal on this assignment. Just tell me what your experiences were with it: what problems you encountered, how you [tried to] fix them, etc. If things worked, tell me about what convinced you that everything was working.
If you pull down the Options menu in Netscape and select Show Java Console, you'll get a window that gives you more detailed error messages.
Why would we bother to put an isFull method into the class if even the fanciest implementation of it is not foolproof? Because we may change the implementation to something the really can get full and really can be checked for fullness, like an array. Because isFull was already in the interface to class ListWithCurrent, client code should already be using it, and so shouldn't have to change if we change the implementation of ListWithCurrent.
It is possible for a dynamic data structure to fill up: what if there is no more memory? You can try constructing a new node. If new fails, you can say that the ListWithCurrent's is full, otherwise it's not. However, this still isn't a perfect solution: Between calling isFull and calling an insert method, memory may fill up (or some memory may become available when none was previously). There's nothing you can do about that.
// The code inside this method may cause an "exception" to happen
// if something goes wrong during the input. The specific kind of
// exception is an "IOException". Whenever a method may cause an
// exception, you have two choices: handle it, or throw up your hands
// and pass the problem on to whoever called you. This code does
// the latter. The "throws IOException" part declares that this is so.
// Since this is the main method, there is no other method to handle
// an exception that it throws. If this happens, the whole program
// is stopped and an exception message is printed.
public static void main (String[] args) throws IOException {
// We construct an object of type DataInputStream, and make
// it ready to read from the standard input (the keyboard),
// which is what System.in refers to.
// "System" is a class defined in Java.lang.
// It has a static member called "in" which is an InputStream.
DataInputStream stdin = new DataInputStream(System.in);
// We can't read right into an int unfortunately.
// Instead, we read a whole line into a String.
String inputLine = stdin.readLine();
// Then we convert it to an integer by calling the static method
// parseInt, defined in the Integer class. It takes a string
// and gives back the corresponding int.
int num = Integer.parseInt(inputLine);
}
For more details on these classes and methods, see the online API documentation
(linked from the main 148 web page.)
There is no place in your class where you ever have to look inside an Object in your list.
What you cannot put into a ListWithCurrent is a primitive such as an int or boolean. However, every primitive type in Java was a "wrapper class" named after it. Eg: Integer, Boolean. These just store a value of the primitive type, but wrap a class around it. Thus, you can put an Integer (although not an int) into a ListWithCurrent.
Below is an example of a small main method that shows how you can put a String or an Integer into a ListWithCurrent:
public static void main(String[] args) {
ListWithCurrent l = new ListWithCurrent();
l.insertAtFront("hello");
l.insertAtFront("goodbye");
l.insertAtFront(new Integer(368));
l.print();
}
The body of System.out.println( [the Object that's inside a node] );
Note that you can do everything but the integration testing without knowing anything about Turing Machines.
In order to understand the methods, it's a good idea to imagine that you have a ListWithCurrent, and make up some method calls to it. You can just use letters like "a" and "b" to stand for the objects that go into the ListWithCurrent. Trace through the calls, following the specs to see what should happen. Do not at this point draw a doubly-linked list. That's just one possible implementation (although it is the one you must use). Instead, think of ListWithCurrent as an ADT, and draw it using some sort of picture that doesn't imply any particular ADT. Eg:
curr
--- --- --- ---
|a| |b| |c| |d|
--- --- --- ---
for a ListWithCurrent containing four objects a, b, c, and d, in
that order from the front, and with current at the b object.
The objects inside a ListWithCurrent are black boxes as far as it is concerned. This is analogous to you running a warehouse in which you store crates full of stuff. You don't need to know what's in the crates in order to stow them away and retrieve them later.
Of course, any program that creates its own ListWithCurrent will have particular kinds of object that it constructs and then inserts into the ListWithCurrent. But because every kind of object in Java is a descendent of the general Object class, it's okay to pass any specific kind of object to a method that's expecting an "Object".