6. Simulation, Digital Logic and Operators

Part of CS:2820 Object Oriented Software Development Notes, Spring 2019
by Douglas W. Jones
THE UNIVERSITY OF IOWA Department of Computer Science

 

Back to the road-network example

In earlier lectures, we came up with code looking something like this for describing road networks:

import java.util.LinkedList;

/** Roads are one-way streets linking intersections
 *  @see Intersection
 */
class Road {
    float travelTime;         //measured in seconds
    Intersection destination; //where the road goes
    Intersection source;      //where the comes from
    // name of road is source-destination
}

/** Intersections join roads
 *  @see Road
 */
class Intersection {
    String name;
    LinkedList <Road> outgoing = new LinkedList <Road> ();
    LinkedList <Road> incoming = new LinkedList <Road> ();
    // Bug: multiple types of intersections (uncontrolled, stoplight)
}

It's time to start working on initializing a road network. In theory we could build the road-network description in many ways. For example, we could build a graphical user interface where users could point and click to drag and drop intersections and roads into place.

GUIs are marvelously fun to use, interesting to design, and worthy of an entire course, but this is not that course, so we will pursue a simpler approach, reading the description of a road network from a text file. Consider, for example, a file structured as follows:

intersection ...
intersection ...
intersection ...
road ...
road ...
road ...
road ...
road ...

Each line of the file begins with a keyword, either road or intersection, followed by the attributes of that road or intersection. We will expand on this description of the text file after we make some progress toward reading it.

Access to the text file

Java provides a very useful class for reading text files, the scanner. To quote the official definition of this class: "A Scanner breaks its input into tokens using a delimiter pattern, which by default matches whitespace. The resulting tokens may then be converted into values of different types using the various next methods." The setup for calling a scanner is as follows:

import java.io.File;
import java.util.Scanner;

/** RoadNetwork, the main class to build a network of roads and intersections.
 *  @see Road
 *  @see Intersection
 */
public class RoadNetwork {
    public static void main(String[] args) {
        // Bug:  Must add code to see if there is a file name
        Scanner sc = new Scanner(new File(args[0]));
        // Bug:  What if the file doesn't exist?
    }
}

The main class of the program must be declared as public class and the class name must match the file name. The main method must be declared as a public static void method with the name main, and it must take an un-dimensioned array of strings as an argument. By convention, this parameter is called args because it holds the arguments that were used to launch the program. The conventions for main are inherited from C++ which inherited them from C, a language that was developed in the late 1960s in the context of the Unix system and is strongly coupled to the Unix command line user interface.

Aside: This mix of required text and traditional text is called boilerplate. The concept of boilerplate text comes from legal documents, where boilerplate text is text that has been tested in court for generations and is therefore known to be resistant to challenge (like armor plate or the plate steel used to make steam boilers). Lawyers copy boilerplate from lawbooks instead of writing creatively in order to avoid the risk that they might overlook some detail that creates text that is vulnerable in court. Any text that you copy from a standard form instead of writing creatively has come to be knwn as boilerplate.

The above code creates a scanner called sc that reads from a file whose name is give by the first command line argument passed when launching the main program.

Consider running your program with this command:

[HawkID@serv15 ~/project]$ java RoadNetwork IowaCity.txt

This launches RoadNetwork.class, the file created by compiling RoadNetwork.java. Inside the main method of this class, you will find that args[0] has been set to the value "IowaCity.txt", so the call to the initializer

        Scanner sc = new Scanner(new File(args[0]));

is equivalent to

        Scanner sc = new Scanner(new File("IowaCity.txt"));

There are a number of different initializers for class Scanner, but the one we are calling here expects an open file as a parameter, and the initializer we are using for class File takes the file name, as a string, as a parameter.

Of course, the skeletal definition given above has some bugs. The code ought to check that there is a command line argument before using it, and it ought to output a sensible error message if the file does not exist or cannot be read. We need to fix the latter to make this file compile, and we will do this in the next class.