package jds.collection; import java.util.Enumeration; import java.util.NoSuchElementException; import jds.Bag; import jds.Deque; import jds.util.DoubleLink; /** * LinkedList - collection based on a sequence of linked values; * for use with book * Classic Data Structures * in Java * by Timothy A Budd, * published by Addison-Wesley, 2001. * * @author Timothy A. Budd * @version 1.1 September 1999 * @see jds.Collection */ public class LinkedList implements Bag, Deque { /** * initialize newly created list */ public LinkedList () { firstLink = sentinel; } /* * pointers to first and last element */ protected DoubleLink firstLink; protected final DoubleLink sentinel = new Link(null); /* * count of number of elements in collection */ protected int elementCount = 0; // the Collection interface /** * Determines whether the collection is empty * * @return true if the collection is empty */ public boolean isEmpty () { return firstLink == sentinel; } /** * Determines number of elements in collection * * @return number of elements in collection as integer */ public int size () { return elementCount; } /** * Yields enumerator for collection * * @return an Enumeration that will yield the elements of the collection * @see java.util.Enumeration */ public Enumeration elements () { return new ListEnumeration(); } // the Deque interface /** * add a new value to front of the collection * * @param value element to be inserted into collection */ public void addFirst (Object newValue) { firstLink.insert(newValue); } /** * add a new value to end of the collection * * @param value element to be inserted into collection */ public void addLast (Object newValue) { sentinel.insert(newValue); } /** * access the first value in collection * * @return element at front of collection * @exception java.util.NoSuchElementException no matching value */ public Object getFirst () { if (isEmpty()) throw new NoSuchElementException(); return firstLink.value; } /** * remove first value in collection * * @exception java.util.NoSuchElementException no matching value */ public synchronized void removeFirst () { firstLink.remove(); } /** * access the last value in collection * * @return element at top of collection * @exception java.util.NoSuchElementException no matching value */ public Object getLast () { if (isEmpty()) throw new NoSuchElementException(); return sentinel.prev.value; } /** * remove last value in collection * * @exception java.util.NoSuchElementException no matching value */ public synchronized void removeLast () { if (isEmpty()) throw new NoSuchElementException(); sentinel.prev.remove(); } // the Bag interface /** * add a new value to the collection * * @param newValue element to be inserted into collection */ public synchronized void addElement (Object newValue) { sentinel.insert(newValue); } /** * see if collection contains value * * @param test element to be tested * @return true if collection contains value */ public boolean containsElement (Object test) { for (Enumeration e = elements(); e.hasMoreElements(); ) if (test.equals(e.nextElement())) return true; return false; } /** * find element that will test equal to value * * @param value element to be tested * @return first value that is equals to argument * @exception java.util.NoSuchElementException no matching value */ public Object findElement (Object test) { for (Enumeration e = elements(); e.hasMoreElements(); ) { Object testElement = e.nextElement(); if (test.equals(testElement)) return testElement; } throw new NoSuchElementException(test.toString()); } /** * remove a new value from the collection * * @param value element to be removed from collection * @exception java.util.NoSuchElementException no matching value */ public synchronized void removeElement (Object newValue) { for (DoubleLink ptr = firstLink; ptr != sentinel; ptr = ptr.next) if (newValue.equals(ptr.value)) { ptr.remove(); return; } throw new NoSuchElementException(newValue.toString()); } /** * LinkedList.Link - Link in a LinkedList; inner class for LinkedList * for use with book * Data Structures in Java, * A Visual and Explorational Approach * by Timothy A Budd, * published by Addison-Wesley, 1999. * * @author Timothy A. Budd * @version 1.1 September 1999 * @see LinkedList */ protected class Link extends DoubleLink { /** * initialize a new Link object * * @param v value of link * @param n next link in sequence * @param p previous link in sequence */ public Link (Object v) { super(v, null, null); } /** * insert a new link into the sequence * * @param newValue value held by new link */ public DoubleLink insert (Object newValue) { elementCount++; Link newLink = new Link(newValue); insertLink(newLink); if (newLink.prev == null) firstLink = newLink; return newLink; } /** * remove a link from the sequence */ public void remove () { if (next == null) // cannot remove last element throw new NoSuchElementException(); elementCount--; if (prev == null) firstLink = next; super.remove(); } } protected class ListEnumeration implements Enumeration { public DoubleLink current = firstLink; public boolean hasMoreElements () { return current != sentinel; } public Object nextElement () { Object result = current.value; current = current.next; return result; } } }