University of Virginia, Department of Computer Science
CS201J: Engineering Software, Fall 2003

Notes: Thursday 18 September 2003
Assignments Due

Answers to Java Questions

Vectors
The java.util.Vector datatype represents an ordered collection of objects. It is similar to an array, except it can grow to contain any number of objects, and access to those objects use method calls (instead of the array index operators). The elements of the Vector are of type Object. This means any object type can be stored in a Vector. A primitive type (e.g., int) cannot be placed in a Vector directly. Instead, it must be stored in an object type. The Java API provides object types corresponding to the primitive types (for example, java.lang.Integer).

The Vector datatype provides many methods. To use Vector you should put import java.util.Vector; at the beginning of your code file. See http://java.sun.com/j2se/1.4.1/docs/api/java/util/Vector.html for all of them. The ones you are likely to find most useful are shown in the specification below:

public class Vector {
  // OVERVIEW: A Vector is an ordered collection of objects.  A typical
  //    Vector is [ obj_0, obj_1, obj_2, ..., obj_n-1 ].

  public Vector () 
    // EFFECTS: Initializes this to an empty vector: [].
    
  boolean add(Object o)
    // MODIFIES: this
    // EFFECTS: Appends the specified element to the end of this
    //    Vector.  Always returns true.
    //    If this_pre = [ obj_0, obj_1, ..., obj_n-1 ] then
    //       this_post = [ obj_0, obj_1, ..., obj_n-1, o ]

  public Object get(int index) throws ArrayIndexOutOfBoundsException
    // EFFECTS: If the index is out of range (index < 0 or index >=
    //    number of elements in this) throws an
    //    ArrayIndexOutOfBoundsException.  Otherwise, returns the
    //    element in this at position index (where the index of the
    //    first element is 0).
    //    e.g., if this = [ obj_0, obj_1, obj_2 ] then
    //       get(1) would return obj_1
    //       get(3) would throw an ArrayIndexOutOfBoundsException

  public int size()
    // EFFECTS: Returns the number of elements in the vector.
    //    e.g., if this = [ obj_0, obj_1, obj_2 ] then
    //      size() would return 3.

  public Enumeration elements()
    // EFFECTS: Returns an enumeration of the elements of this in order.
    //    For example, to print all elements of a vector v: 
    //
    //       for (java.util.Enumeration e = v.elements() ; e.hasMoreElements() ;) {
    //          System.out.println(e.nextElement());
    //        }
    //     

  // See the Java API spec for more methods.
}
There are several ESC/Java annotations you can use to document invariants of a vector: The code below declares two vectors and documents the invariant that neither vector contains null, the elements of vs are String objects, the elements of vi are Integer objects, and vs and vi contains the same number of elements:
    private Vector vs, vi;
    //@invariant vs != null
    //@invariant vi != null
    //@invariant vs.containsNull == false
    //@invariant vi.containsNull == false
    //@invariant vs.elementType == \type(String)
    //@invariant vi.elementType == \type(Integer)
    //@invariant vs.elementCount == vi.elementCount
ESC/Java is not able to establish invariants of constructors correctly, so you will need to use set annotations at the end of the constructor (after convincing yourself the new vector does satisfy your invariants!) to prevent spurious warnings. For example,
   public Vecs () {
     vs = new Vector ();
     vi = new Vector ();
     //@set vs.containsNull = false
     //@set vi.containsNull = false
     //@set vs.elementType = \type(String)
     //@set vi.elementType = \type(Integer)
   }
Note that set annotations use the assignment operator (=) since that are assigning a value to a property, wheras invariant annotations use the equality operator (==) since they are stating a logical predicate.

Exceptions
We will cover exceptions more later in the course. A tutorial on Java exceptions is http://java.sun.com/docs/books/tutorial/essential/exceptions/. For now, you need to know the syntax for catching an exception:

     try {
        // code that might throw and exception
     } catch (<exception type 1> <exception var>) {
        // code to handle exception
     } catch (<exception type 2> <exception var>) {
        // code to handle exception
     }
There can be one or more catch blocks for a try. For example, here is a excerpt from the PS2 code:
        try {
            FileInputStream infile = new FileInputStream (filename);
	    ...
        } catch (FileNotFoundException e) {
            System.err.println ("Cannot find file: " + filename);
            System.exit (1);
        }
The FileInputStream constructor will throw the FileNotFoundException if the file does not exist. So, we need to put a try block around the call to FileInputStream() and catch the exception.

There are two kinds of exceptions in Java — regular exceptions and runtime exceptions (exceptions that are a subtype of RuntimeException). If your code calls a method that has throws Exception in its header, it must be inside a try block with a catch that catches the corresponding exception. ESC/Java will provide a warning for any code that could raise a runtime exception if it cannot prove that the exception would never occur.

ESC/Java Procedure Annotations
The ESC/Java procedure annotations must come before the { that opens the implementation of a procedure. They can come before or after the procedure header.

The procedure annotations you will use are:

The term in an ESC/Java annotation is similar to a Java expression, except it may not use method calls. The special syntax \result is used in an ensures term to refer to the return value of the procedure. The special syntax \old(var) is use to refer to the value of var before entering the method. Hence, in an ESC/Java ensures term, v means v_post and \old(v) means v_pre.
Graph Implementation
Code from the Graph implementations:
import java.util.Vector;
import java.util.Enumeration;

class Edge {
    // OVERVIEW: Record type for representing an edge.
    /*@non_null@*/ String node1;
    /*@non_null@*/ String node2;
    
    Edge (/*@non_null@*/ String n1, /*@non_null@*/ String n2) 
    { node1 = n1; node2 = n2; }
}

public class Graph {
    // OVERVIEW: A Graph is a mutable type that represents an undirected
    //   graph.  It consists of nodes that are named by Strings, and
    //   edges that connect a pair of nodes.  A typical Graph is: < Nodes, Edges >
    //       where Nodes = { n1, n2, , nm }
    //             Edges = { {from_1, to_1}, ..., {from_n, to_n} }
    // Rep:
    Vector nodes; // Vector of String objects
    Vector edges; // Vector of Edge objects

    // RI (c) =    c.nodes != null && c.edges != null
    //          && !c.nodes.containsNull && !c.edges.containsNull
    //          && elements of c.nodes are String objects
    //          && elements of c.edges are Edge objects
    //          && no duplicates in c.nodes
    //                  No duplicate edges, node1/node2 are interchangable:
    //          && ((c.edges[i].node1 = c.edges[j].node1
    //               && c.edges[i].node2 = c.edges[j].node2)
    //              || (c.edges[i].node1 = c.edges[j].node2
    //                  && c.edges[i].node2 = c.edges[j].node1)) 
    //             ==> i == j
    //          && every node mentioned in c.edges is also in c.nodes
    //@invariant nodes != null
    //@invariant edges != null
    //@invariant nodes.containsNull == false
    //@invariant edges.containsNull == false
    //@invariant nodes.elementType == \type(String)
    //@invariant edges.elementType == \type(Edge)

    // Abstraction Function:
    // AF (c) = < Nodes, Edges > where
    //     Nodes = { c.nodes[i] | 0 <= i < c.nodes.size () } 
    //     Edges = { { c.edges[i].node1, c.edges[i].node2 }  | 0 <= i < c.edges.size () } 
    
    public Graph () { 
	// EFFECTS: Initializes this to a graph with no nodes or edges: < {}, {} >.
	nodes = new Vector ();
	edges = new Vector ();
    } //@nowarn Invariant 
    // ESC/Java is not able to establish the invariant here, but we know its true, so we use
    // nowarn to suppress the warning.
	
    // Mutators
    public void addNode (String name) 
        //@requires name != null
	// REQUIRES: name is not the name of a node in this
	// MODIFIES: this
	// EFFECTS: adds a node named name to this:
	//     this_post = < this_pre.nodes U { name }, this_pre.edges >
    { nodes.addElement (name); }

    public void addEdge (String fnode, String tnode) 
	//@requires fnode != null ;
	//@requires tnode != null ;
	// REQUIRES: fnode and tnode are names of nodes in this.
	// MODIFIES: this
	// EFFECTS: Adds an edge from fnode to tnode to this:
	//       this_post = < this_pre.nodes, this_pre.edges U { {fnode, tnode} } >
    { edges.addElement (new Edge (fnode, tnode)); }

    // ... hasNode and nodes elided

    public StringSet getNeighbors (String node) {
	// REQUIRES: node is a node in this
	// EFFECTS: Returns the StringSet consisting of all nodes in this
	//      that are directly connected to node:
	//         \result =  { n | {node, n} is in this.edges }
	StringSet res = new StringSet ();
	Enumeration edgeenum = edges.elements ();
	while (edgeenum.hasMoreElements ()) {
	    Edge e = (Edge) edgeenum.nextElement ();
	    if (e.node1.equals (node)) { res.insert (e.node2); } 
	    else if (e.node2.equals (node)) { res.insert (e.node1); }
	}
	return res;
    }

    public String toString () {
	// EFFECTS: Returns a string representation of this.
	String res = "Graph:<Nodes: { ";
	boolean firstone = true;

	for (Enumeration e = nodes.elements (); e.hasMoreElements (); ) {
	    if (firstone) { firstone = false; } else { res += ", "; }
	    res += (String) e.nextElement ();
	}
	res += "}, Edges: { ";
	firstone = true;

	for (Enumeration e = edges.elements (); e.hasMoreElements (); ) {
	    if (firstone) { firstone = false; } else { res += ", "; }
	    Edge edge = (Edge) e.nextElement ();
	    res += edge.node1 + " <-> " + edge.node2;
	}	
	res += "}>";
	return res;
    }
}

CS201J University of Virginia
Department of Computer Science
CS 201J: Engineering Software
Sponsored by the
National Science Foundation
cs201j-staff@cs.virginia.edu