| /* |
| * Copyright 2007 Google Inc. |
| * |
| * Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0 |
| * |
| * 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 java.util; |
| |
| import com.google.gwt.lang.Array; |
| |
| import java.io.Serializable; |
| |
| /** |
| * Resizeable array implementation of the List interface. <a |
| * href="http://java.sun.com/j2se/1.5.0/docs/api/java/util/ArrayList.html">[Sun |
| * docs]</a> |
| * |
| * <p> |
| * This implementation differs from JDK 1.5 <code>ArrayList</code> in terms of |
| * capacity management. There is no speed advantage to pre-allocating array |
| * sizes in JavaScript, so this implementation does not include any of the |
| * capacity and "growth increment" concepts in the standard ArrayList class. |
| * Although <code>ArrayList(int)</code> accepts a value for the initial |
| * capacity of the array, this constructor simply delegates to |
| * <code>ArrayList()</code>. It is only present for compatibility with JDK |
| * 1.5's API. |
| * </p> |
| * |
| * @param <E> the element type. |
| */ |
| public class ArrayList<E> extends AbstractList<E> implements List<E>, |
| Cloneable, RandomAccess, Serializable { |
| |
| private static native void setCapacity(Object[] array, int newSize) /*-{ |
| array.length = newSize; |
| }-*/; |
| |
| private static native void splice(Object[] array, int index, int deleteCount) /*-{ |
| array.splice(index, deleteCount); |
| }-*/; |
| |
| private static native void splice(Object[] array, int index, int deleteCount, |
| Object value) /*-{ |
| array.splice(index, deleteCount, value); |
| }-*/; |
| |
| private static native void spliceArray(Object[] array, int index, |
| int deleteCount, Object[] values) /*-{ |
| Array.prototype.splice.apply(array, [index, deleteCount].concat(values)); |
| }-*/; |
| |
| /** |
| * This field holds a JavaScript array. |
| */ |
| private transient E[] array = (E[]) new Object[0]; |
| |
| /** |
| * Ensures that RPC will consider type parameter E to be exposed. It will be |
| * pruned by dead code elimination. |
| */ |
| @SuppressWarnings("unused") |
| private E exposeElement; |
| |
| /** |
| * The size of the array. |
| */ |
| private int size = 0; |
| |
| public ArrayList() { |
| } |
| |
| public ArrayList(Collection<? extends E> c) { |
| // Avoid calling overridable methods from constructors |
| spliceArray(array, 0, 0, c.toArray()); |
| size = array.length; |
| } |
| |
| public ArrayList(int initialCapacity) { |
| // Avoid calling overridable methods from constructors |
| assert (initialCapacity >= 0); |
| setCapacity(array, initialCapacity); |
| } |
| |
| @Override |
| public boolean add(E o) { |
| array[size++] = o; |
| return true; |
| } |
| |
| @Override |
| public void add(int index, E o) { |
| if (index < 0 || index > size) { |
| indexOutOfBounds(index, size); |
| } |
| splice(array, index, 0, o); |
| ++size; |
| } |
| |
| @Override |
| public boolean addAll(Collection<? extends E> c) { |
| Object[] cArray = c.toArray(); |
| int len = cArray.length; |
| if (len == 0) { |
| return false; |
| } |
| spliceArray(array, size, 0, cArray); |
| size += len; |
| return true; |
| } |
| |
| public boolean addAll(int index, Collection<? extends E> c) { |
| if (index < 0 || index > size) { |
| indexOutOfBounds(index, size); |
| } |
| Object[] cArray = c.toArray(); |
| int len = cArray.length; |
| if (len == 0) { |
| return false; |
| } |
| spliceArray(array, index, 0, cArray); |
| size += len; |
| return true; |
| } |
| |
| @Override |
| public void clear() { |
| array = (E[]) new Object[0]; |
| size = 0; |
| } |
| |
| public Object clone() { |
| return new ArrayList<E>(this); |
| } |
| |
| @Override |
| public boolean contains(Object o) { |
| return (indexOf(o) != -1); |
| } |
| |
| public void ensureCapacity(int capacity) { |
| if (capacity > size) { |
| setCapacity(array, capacity); |
| } |
| } |
| |
| @Override |
| public E get(int index) { |
| checkIndex(index, size); |
| return array[index]; |
| } |
| |
| @Override |
| public int indexOf(Object o) { |
| return indexOf(o, 0); |
| } |
| |
| @Override |
| public boolean isEmpty() { |
| return size == 0; |
| } |
| |
| @Override |
| public int lastIndexOf(Object o) { |
| return lastIndexOf(o, size() - 1); |
| } |
| |
| @Override |
| public E remove(int index) { |
| E previous = get(index); |
| splice(array, index, 1); |
| --size; |
| return previous; |
| } |
| |
| @Override |
| public boolean remove(Object o) { |
| int i = indexOf(o); |
| if (i == -1) { |
| return false; |
| } |
| remove(i); |
| return true; |
| } |
| |
| @Override |
| public E set(int index, E o) { |
| E previous = get(index); |
| array[index] = o; |
| return previous; |
| } |
| |
| @Override |
| public int size() { |
| return size; |
| } |
| |
| @Override |
| public Object[] toArray() { |
| return Array.cloneSubrange(array, 0, size); |
| } |
| |
| /* |
| * Faster than the iterator-based implementation in AbstractCollection. |
| */ |
| @SuppressWarnings("unchecked") |
| @Override |
| public <T> T[] toArray(T[] out) { |
| if (out.length < size) { |
| out = Array.createFrom(out, size); |
| } |
| for (int i = 0; i < size; ++i) { |
| out[i] = (T) array[i]; |
| } |
| if (out.length > size) { |
| out[size] = null; |
| } |
| return out; |
| } |
| |
| public void trimToSize() { |
| setCapacity(array, size); |
| } |
| |
| @Override |
| protected void removeRange(int fromIndex, int endIndex) { |
| checkIndex(fromIndex, size); |
| if (endIndex < fromIndex || endIndex > size) { |
| indexOutOfBounds(endIndex, size); |
| } |
| int count = endIndex - fromIndex; |
| splice(array, fromIndex, count); |
| size -= count; |
| } |
| |
| /** |
| * Used by Vector. |
| */ |
| int capacity() { |
| return array.length; |
| } |
| |
| /** |
| * Used by Vector. |
| */ |
| int indexOf(Object o, int index) { |
| for (; index < size; ++index) { |
| if (Utility.equalsWithNullCheck(o, array[index])) { |
| return index; |
| } |
| } |
| return -1; |
| } |
| |
| /** |
| * Used by Vector. |
| */ |
| int lastIndexOf(Object o, int index) { |
| for (; index >= 0; --index) { |
| if (Utility.equalsWithNullCheck(o, array[index])) { |
| return index; |
| } |
| } |
| return -1; |
| } |
| |
| /** |
| * Used by Vector. |
| */ |
| void setSize(int newSize) { |
| setCapacity(array, newSize); |
| size = newSize; |
| } |
| } |