All Downloads are FREE. Search and download functionalities are using the official Maven repository.

javax.media.j3d.UnorderList Maven / Gradle / Ivy

The newest version!
/*
 * Copyright 1999-2008 Sun Microsystems, Inc.  All Rights Reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Sun designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Sun in the LICENSE file that accompanied this code.
 *
 * This code 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 General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
 * CA 95054 USA or visit www.sun.com if you need additional information or
 * have any questions.
 *
 */

package javax.media.j3d;
import java.util.Arrays;

/**
 * A strongly type unorder array list.
 * The operation add(Object o) & remove(int i) take O(1) time.
 * The class is designed to optimize speed. So many reductance
 * procedures call and range check as found in ArrayList are
 * removed.
 *
 * 

* Use the following code to iterate through an array. * *

 *  UnorderList  list = new UnorderList(YourClass.class);
 *  // add element here
 *
 *  YourClass[] arr = (YourClass []) list.toArray();
 *  int size = list.arraySize();
 *  for (int i=0; i < size; i++) {
 *      YourClass obj = arr[i];
 *      ....
 *  }
 * 
* *

* Note: *

    * 1) The array return is a copied of internal array.
    * 2) Don't use arr.length , use list.arraySize();
    * 3) No need to do casting for individual element as in * ArrayList.
    * 4) UnorderList is thread safe. *
*/ class UnorderList implements Cloneable, java.io.Serializable { /** * The array buffer into which the elements of the ArrayList are stored. * The capacity of the ArrayList is the length of this array buffer. * * It is non-private to enable compiler do inlining for get(), * set(), remove() when -O flag turn on. */ transient Object elementData[]; /** * Clone copy of elementData return by toArray(true); */ transient Object cloneData[]; // size of the above clone objec. transient int cloneSize; transient boolean isDirty = true; /** * Component Type of individual array element entry */ Class componentType; /** * The size of the ArrayList (the number of elements it contains). * * We make it non-private to enable compiler do inlining for * getSize() when -O flag turn on. */ int size; /** * Constructs an empty list with the specified initial capacity. * and the class data Type * * @param initialCapacity the initial capacity of the list. * @param componentType class type of element in the list. */ UnorderList(int initialCapacity, Class componentType) { this.componentType = componentType; this.elementData = (Object[])java.lang.reflect.Array.newInstance( componentType, initialCapacity); } /** * Constructs an empty list. * @param componentType class type of element in the list. */ UnorderList(Class componentType) { this(10, componentType); } /** * Constructs an empty list with the specified initial capacity. * * @param initialCapacity the initial capacity of the list. */ UnorderList(int initialCapacity) { this(initialCapacity, Object.class); } /** * Constructs an empty list. * componentType default to Object. */ UnorderList() { this(10, Object.class); } /** * Returns the number of elements in this list. * * @return the number of elements in this list. */ final int size() { return size; } /** * Returns the size of entry use in toArray() number of elements * in this list. * * @return the number of elements in this list. */ final int arraySize() { return cloneSize; } /** * Tests if this list has no elements. * * @return true if this list has no elements; * false otherwise. */ final boolean isEmpty() { return size == 0; } /** * Returns true if this list contains the specified element. * * @param o element whose presence in this List is to be tested. */ synchronized final boolean contains(Object o) { if (o != null) { // common case first for (int i=size-1; i >= 0; i--) if (o.equals(elementData[i])) return true; } else { for (int i=size-1; i >= 0; i--) if (elementData[i]==null) return true; } return false; } /** * Add Object into the list if it is not already exists. * * @param o an object to add into the list * @return true if object successfully add, false if duplicate found */ synchronized final boolean addUnique(Object o) { if (!contains(o)) { add(o); return true; } return false; } /** * Searches for the last occurence of the given argument, testing * for equality using the equals method. * * @param o an object. * @return the index of the first occurrence of the argument in this * list; returns -1 if the object is not found. * @see Object#equals(Object) */ synchronized final int indexOf(Object o) { if (o != null) { // common case first for (int i=size-1; i >= 0; i--) if (o.equals(elementData[i])) return i; } else { for (int i=size-1; i >= 0; i--) if (elementData[i]==null) return i; } return -1; } /** * Returns a shallow copy of this ArrayList instance. (The * elements themselves are not copied.) * * @return a clone of this ArrayList instance. */ @Override synchronized protected final Object clone() { try { UnorderList v = (UnorderList)super.clone(); v.elementData = (Object[])java.lang.reflect.Array.newInstance( componentType, size); System.arraycopy(elementData, 0, v.elementData, 0, size); isDirty = true; // can't use the old cloneData reference return v; } catch (CloneNotSupportedException e) { // this shouldn't happen, since we are Cloneable throw new InternalError(); } } /** * Returns an array containing all of the elements in this list. * The size of the array may longer than the actual size. Use * arraySize() to retrieve the size. * The array return is a copied of internal array. if copy * is true. * * @return an array containing all of the elements in this list */ synchronized final Object[] toArray(boolean copy) { if (copy) { if (isDirty) { if ((cloneData == null) || cloneData.length < size) { cloneData = (Object[])java.lang.reflect.Array.newInstance( componentType, size); } System.arraycopy(elementData, 0, cloneData, 0, size); cloneSize = size; isDirty = false; } return cloneData; } else { cloneSize = size; return elementData; } } /** * Returns an array containing all of the elements in this list. * The size of the array may longer than the actual size. Use * arraySize() to retrieve the size. * The array return is a copied of internal array. So another * thread can continue add/delete the current list. However, * it should be noticed that two call to toArray() may return * the same copy. * * @return an array containing all of the elements in this list */ synchronized final Object[] toArray() { return toArray(true); } /** * Returns an array containing elements starting from startElement * all of the elements in this list. A new array of exact size * is always allocated. * * @param startElement starting element to copy * * @return an array containing elements starting from * startElement, null if element not found. * */ synchronized final Object[] toArray(Object startElement) { int idx = indexOf(startElement); if (idx < 0) { return (Object[])java.lang.reflect.Array.newInstance(componentType, 0); } int s = size - idx; Object data[] = (Object[])java.lang.reflect.Array.newInstance(componentType, s); System.arraycopy(elementData, idx, data, 0, s); return data; } // copy element to objs and clear the array synchronized final void toArrayAndClear(Object[] objs) { System.arraycopy(elementData, 0, objs, 0, size); Arrays.fill(elementData, 0, size, null); size = 0; isDirty = true; } /** * Trims the capacity of this ArrayList instance to be the * list's current size. An application can use this operation to minimize * the storage of an ArrayList instance. */ synchronized final void trimToSize() { if (elementData.length > size) { Object oldData[] = elementData; elementData = (Object[])java.lang.reflect.Array.newInstance( componentType, size); System.arraycopy(oldData, 0, elementData, 0, size); } } // Positional Access Operations /** * Returns the element at the specified position in this list. * * @param index index of element to return. * @return the element at the specified position in this list. * @throws IndexOutOfBoundsException if index is out of range (index * < 0 || index >= size()). */ synchronized final Object get(int index) { return elementData[index]; } /** * Replaces the element at the specified position in this list with * the specified element. * * @param index index of element to replace. * @param element element to be stored at the specified position. * @return the element previously at the specified position. * @throws IndexOutOfBoundsException if index out of range * (index < 0 || index >= size()). */ synchronized final void set(int index, Object element) { elementData[index] = element; isDirty = true; } /** * Appends the specified element to the end of this list. * It is the user responsible to ensure that the element add is of * the same type as array componentType. * * @param o element to be appended to this list. */ synchronized final void add(Object o) { if (elementData.length == size) { Object oldData[] = elementData; elementData = (Object[])java.lang.reflect.Array.newInstance( componentType, (size << 1)); System.arraycopy(oldData, 0, elementData, 0, size); } elementData[size++] = o; isDirty = true; } /** * Removes the element at the specified position in this list. * Replace the removed element by the last one. * * @param index the index of the element to removed. * @throws IndexOutOfBoundsException if index out of range (index * < 0 || index >= size()). */ synchronized final void remove(int index) { elementData[index] = elementData[--size]; elementData[size] = null; isDirty = true; /* if ((cloneData != null) && (index < cloneData.length)) { cloneData[index] = null; // for gc } */ } /** * Removes the element at the specified position in this list. * The order is keep. * * @param index the index of the element to removed. * @throws IndexOutOfBoundsException if index out of range (index * < 0 || index >= size()). */ synchronized final void removeOrdered(int index) { size--; if (index < size) { System.arraycopy(elementData, index+1, elementData, index, size-index); } // gc for last element elementData[size] = null; isDirty = true; } /** * Removes the element at the last position in this list. * @return The element remove * @throws IndexOutOfBoundsException if array is empty */ synchronized final Object removeLastElement() { Object elm = elementData[--size]; elementData[size] = null; isDirty = true; /* if ((cloneData != null) && (size < cloneData.length)) { cloneData[size] = null; // for gc } */ return elm; } // Shift element of array from positin idx to position 0 // Note that idx < size, otherwise ArrayIndexOutOfBoundsException // throws. The element remove are copy to objs. synchronized final void shift(Object objs[], int idx) { int oldsize = size; System.arraycopy(elementData, 0, objs, 0, idx); size -= idx; if (size > 0) { System.arraycopy(elementData, idx, elementData, 0, size); } Arrays.fill(elementData, size, oldsize, null); } /** * Removes the specified element in this list. * Replace the removed element by the last one. * * @param o the element to removed. * @return true if object remove * @throws IndexOutOfBoundsException if index out of range (index * < 0 || index >= size()). */ synchronized final boolean remove(Object o) { size--; if (o != null) { for (int i=size; i >= 0; i--) { if (o.equals(elementData[i])) { elementData[i] = elementData[size]; elementData[size] = null; /* if ((cloneData != null) && (i < cloneData.length)) { cloneData[i] = null; // for gc } */ isDirty = true; return true; } } } else { for (int i=size; i >= 0; i--) if (elementData[i]==null) { elementData[i] = elementData[size]; elementData[size] = null; /* if ((cloneData != null) && (i < cloneData.length)) { cloneData[i] = null; // for gc } */ isDirty = true; return true; } } size++; // fail to remove return false; } /** * Removes all of the elements from this list. The list will * be empty after this call returns. */ synchronized final void clear() { if (size > 0) { Arrays.fill(elementData, 0, size, null); size = 0; isDirty = true; } } synchronized final void clearMirror() { if (cloneData != null) { Arrays.fill(cloneData, 0, cloneData.length, null); } cloneSize = 0; isDirty = true; } final Class getComponentType() { return componentType; } @Override synchronized public String toString() { StringBuffer sb = new StringBuffer("Size = " + size + "\n["); int len = size-1; Object obj; for (int i=0; i < size; i++) { obj = elementData[i]; if (obj != null) { sb.append(elementData[i].toString()); } else { sb.append("NULL"); } if (i != len) { sb.append(", "); } } sb.append("]\n"); return sb.toString(); } /** * Save the state of the ArrayList instance to a stream (that * is, serialize it). * * @serialData The length of the array backing the ArrayList * instance is emitted (int), followed by all of its elements * (each an Object) in the proper order. */ private synchronized void writeObject(java.io.ObjectOutputStream s) throws java.io.IOException{ // Write out element count, and any hidden stuff s.defaultWriteObject(); // Write out array length s.writeInt(elementData.length); // Write out all elements in the proper order. for (int i=0; iArrayList instance from a stream (that is, * deserialize it). */ private synchronized void readObject(java.io.ObjectInputStream s) throws java.io.IOException, ClassNotFoundException { // Read in size, and any hidden stuff s.defaultReadObject(); // Read in array length and allocate array int arrayLength = s.readInt(); elementData = (Object[])java.lang.reflect.Array.newInstance( componentType, arrayLength); // Read in all elements in the proper order. for (int i=0; i




© 2015 - 2024 Weber Informatics LLC | Privacy Policy