CompSci-61B Lecture Topic 2
Lists As Data Structures

Instructor: Prof. Robert Burns

Ref: Carrano ch.4, 5, 6, and App. A

Lists
collection of like data values (like an array)
  so data type has to be specified
starts empty, values get added and removed
  values get searched, counted, processed
an analogy: to-do list
  usually at end of list, but not always
  remove from anywhere & close gap
  look at/for matching values
  count, check for empty or, if possible, full
  print all items

A Java List "Interface"
specifies all the accessors and mutators expected
  to be in the public interface
for a list of String values:
public boolean add(String value) // at end
public boolean add(int index, String value)
public String remove(int index)
public void clear() // remove all
public boolean replace(int index, String value)
public String getEntry(int index)
public boolean contains(String value)
public int size()
public boolean isEmpty()
public boolean isFull()
booleans return success as true
zero-based indexing

implementation in a ".java" file
  with incomplete methods: headers only

public interface MyStringList
{
  public boolean add(String value);
  ...
}
compile and jar, but do not run

A Very Simple List Class
simple: storage for only one value!
  avoids complication of array vs linked list
private data members: a String value, #of values (0 or 1)
implement the list interface: implements MyStringList
  promises that methods will be supplied
index validation & object assertion
tracing statements for debugging and testing
null return values
garbage collection in clear
toString: special Java accessor
  supplied by Java if you don't write it!

public interface validation and unit testing

A List Class For Strings
public class MyStrings implements MyStringList
expanding to handle multiple values
use array of initial size 10: new data member
requires default constructor
add checks for array expansion

if (nValues == data.length)
{
  String[] newData = new String[2 * data.length];
  System.arraycopy(data, 0, newData, 0, data.length);
  data = newData;
}
add checks for array shifting
for (int i = nValues; i > index; i--)
  data[i] = data[i - 1]; // move right
data[index] = the newly added value
remove checks for array shifting and gc
for (int i = index + 1; i < nValues; i++)
  data[i - 1] = data[i]; // move left
data[--nValues] = null; // to release object for gc
clear resets the array to its original size

declaration: MyStringList a = new MyStrings();

Java Generics
makes data structure suitable for objects other than Strings
copies C++ template syntax with angle brackets:
append <T> to class name:
  public interface MyList<T>
  public class MyGenerics<T> implements MyList<T>
replace String data type with T

declaration has <{data type}>:
MyList<Integer> a = new MyGenerics<Integer>();

Array-Based Lists
using array of T
  cannot do new T[...] to create array
  instead use(T[]) new Object[...]
    ...using "type casting"

Identification Interfaces
implementing java.io.Serializable flags class so that
  its objects can be "serialized" for O-O I/O
we will flag classes as array-based or using linked lists
interfaces: MyArrayBasedDataStructure
  and MyLinkedDataStructure
  with no method specifications
using the instanceof logical operator

Linked Lists
linked structures use "nodes" instead of arrays
a node is an object with 2 data items:
  a value and a link to another node
some details:
  need a separate link to 1st node
  last node's link value is null

The private inner class Node
2 private data members: T value and Node next
no accessors or mutators: owning class can access
  private members directly

data structure member: Node head;, initially null
  instead of array

Adding To A Linked List
if new value is to be first in list (index zero):
  Node node = new Node();
  node.value = the newly added value
  node.next = head;
  head = node;
if new value is to be in the middle of the list (some index):
  Node prev = head;
  for (int i = 0; i < (index - 1); i++)
    prev = prev.next;
  Node node = new Node();
  node.value = the newly added value
  node.next = prev.next;
  prev.next = node;
if new value is to be last in list:
  set index = nValues
  then do above code block!
finish with ++nValues;

A getNodeAt(int index) Private Method

private Node getNodeAt(int index)
{
  Node result = null;

  if (0 <= index && index < nValues) // validate
  {
    result = head;
    for (int i = 0; i < index; i++)
      result = result.next;
  }
  return result; // can be null
} 
removing From A Linked List
removing the first value (index zero):
  Node node = head;
  head = head.next
removing any other value (some index):
  Node prev = getNodeAt(index - 1);
  Node node = prev.next;
  Node prev.next = node.next;
finish with --nValues;
node contains value to be returned

The contains(T value) Method

public boolean contains(T value)
{
  boolean found = false;

  for (Node node = head; node != null 
    && !found; node = node.next)
    found = value.equals(node.value);

  return found;
}

The toString() Method
inside, if not empty:

int i = 0;
String buf = getClass().getName();
for (Node p = head; p != null; p = p.next)
  buf += "\n value[" + i++ + "] = " + p.value;

Serializing an object: reading it from a disk file:
MyList<Integer> a = new MyArrayList<Integer>();
...
Object obj = new ObjectInputStream(new FileInputStream("myobject.data")).readObject();
if (obj instanceof MyList)
{
  a = (MyList<Integer>)obj;
}

Serializing an object: writing it to a disk file:
MyList<Integer> a = new MyArrayList<Integer>();
...
new ObjectOutputStream(new FileOutputStream("myobject.data")).writeObject(a);

[ Home | Contact Prof. Burns ]