From 57a2d005a42021944992425b123315f6218d6133 Mon Sep 17 00:00:00 2001 From: mdb Date: Tue, 19 Feb 2002 03:38:58 +0000 Subject: [PATCH] An array backed List implementation that can be sorted without making two copies of the underlying elements array (which is what happens when one calls Collections.sort(ArrayList)). git-svn-id: https://samskivert.googlecode.com/svn/trunk@583 6335cc39-0255-0410-8fd6-9bcaacd3b74c --- .../samskivert/util/SortableArrayList.java | 178 ++++++++++++++++++ 1 file changed, 178 insertions(+) create mode 100644 projects/samskivert/src/java/com/samskivert/util/SortableArrayList.java diff --git a/projects/samskivert/src/java/com/samskivert/util/SortableArrayList.java b/projects/samskivert/src/java/com/samskivert/util/SortableArrayList.java new file mode 100644 index 00000000..5c22aa38 --- /dev/null +++ b/projects/samskivert/src/java/com/samskivert/util/SortableArrayList.java @@ -0,0 +1,178 @@ +// +// $Id: SortableArrayList.java,v 1.1 2002/02/19 03:38:58 mdb Exp $ +// +// samskivert library - useful routines for java programs +// Copyright (C) 2001 Michael Bayne +// +// This library is free software; you can redistribute it and/or modify it +// under the terms of the GNU Lesser General Public License as published +// by the Free Software Foundation; either version 2.1 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.samskivert.util; + +import java.util.AbstractList; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.Comparator; +import java.util.List; +import java.util.RandomAccess; + +import java.lang.reflect.Array; + +/** + * Extends the standard Java {@link ArrayList} functionality (which we'd + * do with normal object extension if those pig fuckers hadn't made the + * instance variables private) and provides a mechanism ({@link #sort}) + * for sorting the contents of the list that doesn't involve creating two + * object arrays. Two copies of the elements array are made if you called + * {@link Collections#sort} (the first is when the {@link + * Collections} class calls {@link #toArray} on the collection and the + * second is when {@link Arrays#sort} clones the supplied array so that it + * can do a merge sort). + */ +public class SortableArrayList extends AbstractList + implements List, RandomAccess, Cloneable +{ + /** + * Sorts the elements in this list using the quick sort algorithm + * (which does not involve any object allocation). The elements must + * implement {@link Comparable} and all be mutually comparable. + */ + public void sort () + { + sort(Comparators.COMPARABLE); + } + + /** + * Sorts the elements in this list with the supplied element + * comparator using the quick sort algorithm (which does not involve + * any object allocation). The elements must all be mutually + * comparable. + */ + public void sort (Comparator comp) + { + QuickSort.csort(_elements, 0, _size, comp); + } + + // documentation inherited from interface + public int size () + { + return _size; + } + + // documentation inherited from interface + public boolean isEmpty () + { + return (_size == 0); + } + + // documentation inherited from interface + public boolean contains (Object o) + { + return ListUtil.contains(_elements, o); + } + + // documentation inherited from interface + public Object[] toArray () + { + return toArray(new Object[_size]); + } + + // documentation inherited from interface + public Object[] toArray (Object[] target) + { + // create the target array if necessary + if (target.length < _size) { + target = (Object[])Array.newInstance( + target.getClass().getComponentType(), _size); + } + + // copy the elements + System.arraycopy(_elements, 0, target, 0, _size); + return target; + } + + // documentation inherited from interface + public boolean add (Object o) + { + _elements = ListUtil.add(_elements, _size, o); + _size++; + return true; + } + + // documentation inherited from interface + public boolean remove (Object o) + { + if (ListUtil.removeEqual(_elements, o) != null) { + _size--; + return true; + } + return false; + } + + // documentation inherited from interface + public Object get (int index) + { + if (index >= 0 && index < _size) { + return _elements[index]; + } else { + throw new IndexOutOfBoundsException(); + } + } + + // documentation inherited from interface + public Object set (int index, Object element) + { + if (index >= 0 && index < _size) { + Object old = _elements[index]; + _elements[index] = element; + return old; + } else { + throw new IndexOutOfBoundsException(); + } + } + + // documentation inherited from interface + public void add (int index, Object element) + { + if (index >= 0 && index < _size) { + _elements[index] = element; + } else { + throw new IndexOutOfBoundsException(); + } + } + + // documentation inherited from interface + public Object remove (int index) + { + return ListUtil.remove(_elements, index); + } + + // documentation inherited from interface + public int indexOf (Object o) + { + return ListUtil.indexOfEqual(_elements, o); + } + +// // documentation inherited from interface +// public int lastIndexOf (Object o) +// { +// } + + /** The array of elements in our list. */ + protected Object[] _elements; + + /** The number of elements in our list. */ + protected int _size; +}