Collections Data Structure Java

/*
 * Copyright 2005 MBARI
 *
 * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE, Version 2.1 
 * (the "License"); you may not use this file except in compliance 
 * with the License. You may obtain a copy of the License at
 *
 * http://www.gnu.org/copyleft/lesser.html
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
//package org.mbari.util;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
//~--- classes ----------------------------------------------------------------
/**
 * 

ArrayList with sorted contents. Each Object added to the list is added in
 * the order determined by Collections.sort(obj)


 *
 * @author  : $Author: hohonuuli $
 * @version : $Revision: 332 $
 *
 */
public class SortedArrayList extends ArrayList {
    /**
     * 
     */
    private static final long serialVersionUID = -1131961127138657379L;
    //~--- fields -------------------------------------------------------------
    /**
   * @uml.property  name="comparator"
   */
    private Comparator comparator;
    //~--- constructors -------------------------------------------------------
    /**
     * Constructs ...
     *
     */
    public SortedArrayList() {
        super();
    }
    /**
     * Constructs a list containing the elements of the specified
     * collection, in the order they are returned by the collection's
     * iterator.  The ArrayList instance has an initial capacity of
     * 110% the size of the specified collection.
     *
     * @param c the collection whose elements are to be placed into this list.
     */
    public SortedArrayList(Collection c) {
        addAll(c);
    }
    /**
     * Constructs ...
     *
     *
     * @param comparator
     */
    public SortedArrayList(Comparator comparator) {
        setComparator(comparator);
    }
    /**
     * Constructs an empty list with the specified initial capacity.
     *
     * @param   initialCapacity   the initial capacity of the list.
     */
    public SortedArrayList(int initialCapacity) {
        super(initialCapacity);
    }
    /**
     * Constructs ...
     *
     *
     * @param c
     * @param comparator
     */
    public SortedArrayList(Collection c, Comparator comparator) {
        addAll(c);
        setComparator(comparator);
    }
    /**
     * Constructs ...
     *
     *
     * @param initialCapacity
     * @param comparator
     */
    public SortedArrayList(int initialCapacity, Comparator comparator) {
        super(initialCapacity);
        setComparator(comparator);
    }
    //~--- methods ------------------------------------------------------------
    /**
     * Inserts the specified element in order into the list.
     *
     *
     * @param obj
     * @return true (as per the general contract of Collection.add).
     */
    public boolean add(Object obj) {
//        return addObject(obj) < 0 ? false : true;
        // I changed this so that it returns true if
        // the return from addObject is less than zero
        // which means the object was inserted and so
        // the array was modified
        return (addObject(obj) < 0) ? true : false;
    }
    /**
     * @deprecated use addAll(Arrays.asList(items)) instead
     * @param items
     * @return
     * @since Apr 29, 2003
     */
    public boolean add(Object[] items) {
        for (int i = 0; i < items.length; i++) {
            addObject(items[i]);
        }
        return true;
    }
    /**
     * Throws UnsupportedOperationException!! Insertinion at a specified index
     * is not allowed.
     *
     * Inserts the specified element at the specified position in this
     * list. Shifts the element currently at that position (if any) and
     * any subsequent elements to the right (adds one to their indices).
     *
     * @param index index at which the specified element is to be inserted.
     * @param item
     */
    public void add(int index, Object item) {
        throw new UnsupportedOperationException(
                "Specifying index not allowed. " +
                    "List maintains sorted ordering.");
    }
    /**
     * Inserts all of the elements in the specified Collection into the list in the order
     * specified by Collections.binarySearch(). The behavior of this operation is
     * undefined if the specified Collection is modified while the operation
     * is in progress.  (This implies that the behavior of this call is
     * undefined if the specified Collection is this list, and this
     * list is nonempty.)
     *
     *
     * @param collection
     * @return true if this list changed as a result of the call.
     */
    public boolean addAll(Collection collection) {
        removeAll(collection);
        boolean result = super.addAll(collection);
        Collections.sort(this, comparator);
        return result;
    }
    /**
     * Inserts all of the elements in the specified Collection into the list in the order
     * specified by Collections.binarySearch(). The behavior of this operation is
     * undefined if the specified Collection is modified while the operation
     * is in progress.  (This implies that the behavior of this call is
     * undefined if the specified Collection is this list, and this
     * list is nonempty.)
     *
     *
     *
     * @param index index at which to insert first element
     *          from the specified collection. This argument is ignored.
     * @param collection
     * @return true if this list changed as a result of the call.
     */
    public boolean addAll(int index, Collection collection) {
        // Ignore index argument
        return addAll(collection);
    }
    /**
     * TBD: Negative return value means the item is already in the list
     * @deprecated Prefered use is to call add(item). If index needs to be
     *             returned use addObject(item)
     *
     * @param item
     *
     * @return
     */
    public int addItem(Object item) {
        return addObject(item);
    }
    /**
     * Add an Object and return it's index. It's prefered that a user use
     * 

     *  List list = new SortedArrayList();
     *  list.add(obj);
     *  int i = list.indexOf(obj);
     * 

     * but if you need to insert an object and keep track of its index a call to
     * addObject() is faster. NOTE: Duplicates of an object
     * will not be inserted. instead the index of the Object already in thelist will
     * be returned. 
     *
     * @param obj The object to be inserted.
     * @return index of the search key, if it is contained in the list;
     *         otherwise, (-(insertion point) - 1).  The
     *         insertion point is defined as the point at which the
     *         key would be inserted into the list: the index of the first
     *         element greater than the key, or list.size(), if all
     *         elements in the list are less than the specified key.  Note
     *         that this guarantees that the return value will be >= 0 if
     *         and only if the key is found.
     * @since Apr 29, 2003
     * @see java.util.Collections#binarySearch
     */
    public int addObject(Object obj) {
        /*
         * Find the index at which to insert new item. The insertion index is
         * negative if the item doesn't already exist.
         */
        int insertionIndex = Collections.binarySearch(this, obj, comparator);
        // Do not add if obj is already in the list
        if (insertionIndex < 0) {
            /*
             *  Flip the insertion index sign
             *             insertionIndex = -insertionIndex - 1;
             *             super.add(insertionIndex, obj);
             * TODO - Verify with Brian but changed this
             * so that it does not modify the insertionIndex
             * that is returned.  If left as the way above,
             * the method will never return a negative number
             * so it will be as if the collection is changed
             */
            super.add((-insertionIndex - 1), obj);
        }
        return insertionIndex;
    }
    //~--- get methods --------------------------------------------------------
    /**
   * @return
   * @uml.property  name="comparator"
   */
    public Comparator getComparator() {
        return comparator;
    }
    //~--- set methods --------------------------------------------------------
    /**
   * 


   * @param  comparator
   * @uml.property  name="comparator"
   */
    public void setComparator(Comparator comparator) {
        this.comparator = comparator;
        Collections.sort(this, comparator);
    }
}