Review UML Class Diagram and Basics of dslib Emphasizing Lists References: Tremblay and Cheston: 3.4, 3.5, 7, 8 Horstmann (Big Java): 12.3, Appendix M Tool for drawing UML diagrams: http://www.umlet.com/ UML Class diagram notation inheritance (extends and implements) Aggregation and association Members of an interface or class Recall that constructors and members of a class can be public, protected, private, or have no access modifier. They can also be static or not. Ball and socket relationship Probably seldom used in this class Two versions of the same construct Simple List ADT I. Name List<G> II. Sets L = set of all lists containing items of type G G = set of all items that can be placed in the list B = {true, false} III. Signatures newList<G>: L L.isEmpty: B L.insertFirst: G L L.firstItem: ↛ G L.deleteFirst: ↛ L IV. Preconditions For all l L, g G pre-newList<G>() ::= true pre-l.isEmpty() ::= true pre-l.insertFirst(g) ::= true pre-l.firstItem() ::= not l.isEmpty() pre-l.deleteFirst() ::= not l.isEmpty() V. Semantics (axiomatic) (a) Build operations newList insertFirst (b) Axioms newList().isEmpty() = true l.insertFirst(g).isEmpty() = false l.insertFirst(g).firstItem() = g l.insertFirst(g).deleteFirst() = l /** * A simple list interface with methods to access, insert and delete * items at the front of the list. It also has a test for an empty list. */ public interface SimpleList<I> { /** @return is the data structure empty? */ public boolean isEmpty(); /** @return is the data structure full? */ public boolean isFull(); /** * Insert x as the first element in the list. * @precond !isFull() * @param x item to be inserted in the list * @postcond !isEmpty() && firstItem() == x */ public void insertFirst(I x); /** * @precond !isEmpty() * @return the first item. */ public I firstItem(); /** * Delete the first item from the list. * @precond !isEmpty() */ public void deleteFirst(); } UML for SimpleList: notation from Tremblay and Cheston (printed) UML for SimpleList: notation to be used in CMPT 280 Javadoc A tool to automatically produce documentation in html from code. The Java API is documented with this tool. http://java.sun.com/javase/6/docs/api/ To have comments for classes, fields, constructors, and methods included in the documentation, the comments must use the form /** * This is a comment. */ In these comments, Javadoc tags can be used. @param var what this variable stores Always include @return what is returned from this method Always include @author @version Custom Javadoc tags. @precond the precondition for this constructor/method @postcond the postcondition for this constructor/method @timing the time requirements for this constructor/method Specifying custom tags using Eclipse. In the Options window that appears, add an argument like the following: -tag precond:cm:”Precondition:” Part of ArrayedSimpleList<I>: public class ArrayedSimpleList<I> implements SimpleList<I> { /** Internal representation for this list, where the first * item is stored in location count-1, and last in location 0. */ protected I[ ] rep; /** The number of items in the list. */ protected int count; /** Construct a new empty list with capacity cap. * @param cap the capacity of the new list * @precond cap >= 0 * @postcond isEmpty() && capacity() = cap * @timing Time = O(cap) */ @SuppressWarnings("unchecked") public ArrayedSimpleList(int cap) { if (cap < 0) throw new IllegalArgumentException("The cap parameter cannot be negative." + "It is " + cap); rep = (I[ ]) new Object[cap]; count = 0; } Selection of the representation of lists in an array is important. Ordered first to last of the list at the start of the array: poor Ordered last to first of the list at the start of the array: OK, used in dslib Ordered first to last of the list at the end of the array: OK Ordered first to last of the list with wrap-around at the end of the array: used for queues Verify that each precondition holds, and throw a RuntimeException if it fails. Some common RuntimeExceptions for use in precondition failure are IllegalArgumentException IllegalStateException UnsupportedOperationException Generic types can be used in the normal places for a type, except creation. Normally, an instance of a generic type cannot be created. An array of a generic type can be created rep = (I[ ]) new Object[cap]; Creates an array of null references Cast is safe as there are no actual objects The warning that is obtained is hidden via the Java annotation @SuppressWarnings("unchecked") Other annotations Override Use this whenever a method is being overridden. Depreciated /** Insert x as the first item of the list. * @param x item to be inserted at the front of the list * @precond !isFull() * @postcond !isEmpty() && firstItem() == x * @timing Time = O(1) */ public void insertFirst(I x) { if (isFull()) throw new IllegalStateException("Cannot insert into a full list"); rep[count] = x; count++; } /** @precond !isEmpty() * @return the first item in the list. * @timing Time = O(1) */ public I firstItem() { if (isEmpty()) throw new IllegalStateException("Cannot obtain an item from an empty list"); return rep[count-1]; } Use of ArraySimpleList<I> ArrayedSimpleList<String> a = new ArrayedSimpleList<String>(4); a.insertFirst("a"); String s = a.firstItem(); ArrayedSimpleList<Integer> b = new ArrayedSimpleList<Integer>(10); b.insertFirst(17); int i = b.firstItem(); When an instance of a generic class is created, you cannot specify a primitive type to be used for a generic type, because generics assume reference types. Hence, you must use the corresponding wrapper class. int:Integer, long:Long, float:Float, double:Double, char:Character, boolean:Boolean, As of version 5 of Java, Java does automatic conversion (when it is obvious). Part of LinkedSimpleList<I>: /** * A SimpleList class implemented using LinkedNodes. Items can be * inserted and deleted at the front of the list only. */ public class LinkedSimpleList<I> implements SimpleList<I> { /** The first node of the list. */ protected LinkedNode<I> firstNode; /** Construct an empty list. * @timing Time = O(1) * @postcond isEmpty() */ public LinkedSimpleList() { firstNode = null; } /** Insert x as the first element of the list. * @param x item to be inserted at the front of the list * @timing Time = O(1) * @postcond !isEmpty() && firstItem() == x */ public void insertFirst(I x) { LinkedNode<I> cur = new LinkedNode<I>(x); cur.setNextNode(firstNode); setFirstNode(cur); } public class OrderedSimpleList<I extends Comparable<? super I>> extends LinkedSimpleList<I> { /** The node previous to the current node. */ private LinkedNode<I> prev; /** The current node storing the current item. */ private LinkedNode<I> cur; /** Create an empty ordered list. * @postcond isEmpty() * @timing Time = O(1) */ public OrderedSimpleList() { super(); prev = null; cur = null; } /** @return is there a current item? * @timing Time = O(1) */ public boolean itemExists() { return cur != null; } /** @precond itemExists() * @return the current item. * @timing Time = O(1) */ public I item() { if (!itemExists()) throw new IllegalStateException("A current item must exist."); return cur.item(); } /** Move to x or else off the list. * @param x the item being sought by the search * @postcond (itemExists() && item() == x) || !itemExists() * @timing Time = O(n) worst case, n = size of the list */ public void search(I x) { goToLocation(x); // move the cursor to first occurrence of x // or the position where it would be if (!itemExists() || (x.compareTo(item()) != 0)) { prev = null; cur = null; } } /**A Book that can be compared to another Book by comparing their isbn * numbers. The class defines the infix operators <, <=, > and >=. */ public class ComparableBook extends Book implements Comparable<ComparableBook> { /**constructor */ public ComparableBook(String t, String a, String i) { super(t, a, i); } /**Is the current Book less than `other'? * @timing Time = O(1) */ /** Is the current Book equal to Book 'other'? * @timing Time = O(1) */ public boolean equals(Object other) { if (other instanceof ComparableBook) return compareTo((ComparableBook) other) == 0; else return false; } /** The hash code for the book. * @timing Time = O(1) */ public int hashCode() Iteration abstraction Hide the implementation of a container Allow the items of the container to be accessed one at a time Basic operations access the first item access the next item test whether at the end, i.e., all items have been accessed Note that this implies an ordering of the items that can be implementation dependent. Cursor positions (version from dslib) before, first item, interior, last item, after /** A basic iterator interface for moving through a collection of items linearly. It utilizes a cursor to * keep track of the current item in the sequence. */ public interface LinearIteratorUos<I> { /**Is there a current item? */ public boolean itemExists(); /**The current item. @precond itemExists() */ public I item(); /**Is the current position before the start of the structure? */ public boolean before(); /**Is the current position after the end of the structure? */ public boolean after(); Use of an iterator Suppose c is a container that implements the LinearIteratorUos interface. c.goFirst(); while (c.itemExists()) { … // process c.item() // note that c.item() obtains the current item, but does not advance the cursor c.goForth(); Non-keyed dictionaries Fundamental dictionary operations: Insert an item Test whether an item is in the dictionary Obtain a specific item from the dictionary Delete an item Item comparison Object reference comparision Use == and != in Java Object content comparison Use equals() in Java equals() is defined in the Object class to compare references Keyed dictionaries In a keyed dictionary, Each item is associated with a unique key The key is used to access the item In dslib, Keys are required to be Comparable so that efficient searches can be used Interfaces for keyed dictionaries in the library BasicKeyedDictUos, KeyedDictUos, BasicPKeyedDictUos, and PKeyedDictUos Note Keyed and PKeyed dictionaries In a Keyed dictionary, the item type must implement KeyedUos<I> The key of an item can be obtained from the item via method key() public interface KeyedUos<K extends Comparable<? super K>> { /**Key of the item */ public K key(); } public interface KeyedBasicDictUos<K extends Comparable<? super K>, I extends KeyedUos<K>> … In a PKeyed dictionary, the key of an item is inserted with the item