/*
* 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);
}
}