//package taojava.util; import java.util.ArrayList; import java.util.Iterator; public class Main{ public static void main(String[] argv){ SortedArrayList l = new SortedArrayList(); l.add("b"); l.add("c"); l.add("a"); System.out.println(l); } } /** * Sorted lists implemented with Java's array lists. As one * might expect, the iteration and index operations are fairly * fast, the insert and remove elements are relatively slow. * * @author Samuel A. Rebelsky */ class SortedArrayList<T extends Comparable<T>> { // +--------+---------------------------------------------------------- // | Fields | // +--------+ /** * The underlying ArrayList. */ ArrayList<T> core; // +--------------+---------------------------------------------------- // | Constructors | // +--------------+ /** * Create a new sorted list. */ public SortedArrayList() { this.core = new ArrayList<T>(); } // SortedArrayList() // +-------------------------+----------------------------------------- // | Internal Helper Methods | // +-------------------------+ /** * Determine if val appears at the given index. */ boolean valAppearsAt(T val, int index) { // If the index is too large, it clearly doesn't appear if (index >= this.core.size()) return false; // Compare to the value at the index T tmp = this.core.get(index); return ((tmp != null) && (val.compareTo(tmp) == 0)); } // appearsAt /** * Find the index of val. If val is not in the array, returns the * index of where val should go (either the index of the first value * greater than val, if there is such an index, or length, if there * is no such index). */ int findIndex(T val) { int lb = 0; int ub = this.core.size(); // Invariant: // +-------+------+-------+ // | < val | ? | > val | // +-------+------+-------+ // 0 lb ub length while (lb < ub) { // Find the midpoint in a relatively safe way (assuming // the lb and ub are positive integers). int mid = lb + (ub - lb) / 2; T midval = this.core.get(mid); if (val.compareTo(midval) == 0) return mid; else if (val.compareTo(midval) > 0) lb = mid + 1; else ub = mid; } // while // If we've reached this point we know that // +-------+-------+ // | < val | > val | // +-------+-------+ // 0 lb,ub length // We therefore need to add an element at lb. return lb; } // findIndex(T) // +-----------------------+------------------------------------------- // | Methods from Iterable | // +-----------------------+ /** * Return an iterator that steps through the values of the list from * smallest to largest. */ public Iterator<T> iterator() { // We use a wrapper/adapter class, even though we currently // don't do any adaptations, because we might eventually // find it useful to adapt. return new Iterator<T>() { // An underlying iterator. Iterator<T> core = SortedArrayList.this.core.iterator(); public T next() { return core.next(); } // next() public boolean hasNext() { return core.hasNext(); } // hasNext() public void remove() { core.remove(); } // remove() }; // new Iterator<T> } // iterator() // +------------------------+------------------------------------------ // | Methods from SimpleSet | // +------------------------+ /** * Add a value to the set. * * @post contains(val) * @post For all lav != val, if contains(lav) held before the call * to add, contains(lav) continues to hold. */ public void add(T val) { // Find the index int index = this.findIndex(val); // If the value is already at the index, do nothing if (this.valAppearsAt(val, index)) return; // Shift everything down and put the value at the index. this.core.add(index, val); } // add(T val) /** * Determine if the set contains a particular value. */ public boolean contains(T val) { int index = this.findIndex(val); return this.valAppearsAt(val, index); } // contains(T) /** * Remove an element from the set. * * @post !contains(val) * @post For all lav != val, if contains(lav) held before the call * to remove, contains(lav) continues to hold. */ public void remove(T val) { int index = this.findIndex(val); if (this.valAppearsAt(val, index)) this.core.remove(index); } // remove(T) // +--------------------------+---------------------------------------- // | Methods from SemiIndexed | // +--------------------------+ /** * Get the element at index i. * * @throws IndexOutOfBoundsException * if the index is out of range (index < 0 || index >= length) */ public T get(int i) { return this.core.get(i); } // get(int) /** * Determine the number of elements in the collection. */ public int length() { return this.core.size(); } // length() @Override public String toString() { return "SortedArrayList [core=" + core + "]"; } } // class SortedArrayList<T>