/** * Copyright (c) 2005-2011 by Appcelerator, Inc. All Rights Reserved. * Licensed under the terms of the Eclipse Public License (EPL). * Please see the license.txt included with this distribution for details. * Any modifications to this file must keep this entire header intact. */ package org.python.pydev.core.structure; import java.util.Collection; import java.util.Iterator; import java.util.List; import java.util.ListIterator; /** * An array list that has a null array backing it when created and cleared. * * @author Fabio */ public class LowMemoryArrayList<E> implements List<E> { private transient E[] data; private int size; public LowMemoryArrayList() { } public int size() { return size; } public boolean isEmpty() { return size == 0; } public boolean contains(Object o) { return indexOf(o) >= 0; } public Iterator<E> iterator() { return new Iterator() { private int curr; public boolean hasNext() { if (data == null) { return false; } return curr < size; } public Object next() { E e = data[curr]; curr++; return e; } public void remove() { throw new UnsupportedOperationException(); } }; } public Object[] toArray() { Object[] result = new Object[size]; if (data != null) { System.arraycopy(data, 0, result, 0, size); } return result; } public <T> T[] toArray(T[] a) { if (a.length < size) { a = (T[]) java.lang.reflect.Array.newInstance(a.getClass().getComponentType(), size); } if (data != null) { System.arraycopy(data, 0, a, 0, size); } if (a.length > size) { a[size] = null; } return a; } public void ensureCapacity(int minCapacity) { if (data == null) { if (minCapacity < 3) { minCapacity = 3; } data = (E[]) new Object[minCapacity]; return; } int oldCapacity = data.length; if (minCapacity > oldCapacity) { Object oldData[] = data; int newCapacity = (oldCapacity * 3) / 2 + 1; if (newCapacity < minCapacity) { newCapacity = minCapacity; } data = (E[]) new Object[newCapacity]; System.arraycopy(oldData, 0, data, 0, size); } } public boolean add(E o) { ensureCapacity(size + 1); // Increments modCount!! data[size++] = o; return true; } public boolean remove(Object o) { if (data == null) { return false; } if (o == null) { for (int index = 0; index < size; index++) if (data[index] == null) { fastRemove(index); return true; } } else { for (int index = 0; index < size; index++) if (o.equals(data[index])) { fastRemove(index); return true; } } return false; } /* * Private remove method that skips bounds checking and does not * return the value removed. */ private void fastRemove(int index) { int numMoved = size - index - 1; if (numMoved > 0) System.arraycopy(data, index + 1, data, index, numMoved); data[--size] = null; // Let gc do its work } public boolean containsAll(Collection<?> c) { throw new RuntimeException("Not implemented"); } public boolean addAll(Collection<? extends E> c) { Object[] a = c.toArray(); int numNew = a.length; ensureCapacity(size + numNew); // Increments modCount System.arraycopy(a, 0, data, size, numNew); size += numNew; return numNew != 0; } public boolean addAll(int index, Collection<? extends E> c) { throw new RuntimeException("Not implemented"); } public boolean removeAll(Collection<?> c) { throw new RuntimeException("Not implemented"); } public boolean retainAll(Collection<?> c) { throw new RuntimeException("Not implemented"); } public void clear() { if (data == null) { return; } data = null; //Let the GC work! size = 0; } private void RangeCheck(int index) { if (index >= size) throw new IndexOutOfBoundsException("Index: " + index + ", Size: " + size); } public E get(int index) { RangeCheck(index); //No need to check for null here! return data[index]; } public E set(int index, E element) { throw new RuntimeException("Not implemented"); } public void add(int index, E element) { if (index > size || index < 0) { throw new IndexOutOfBoundsException("Index: " + index + ", Size: " + size); } ensureCapacity(size + 1); // Increments modCount!! System.arraycopy(data, index, data, index + 1, size - index); data[index] = element; size++; } public E remove(int index) { RangeCheck(index); E oldValue = data[index]; int numMoved = size - index - 1; if (numMoved > 0) { System.arraycopy(data, index + 1, data, index, numMoved); } data[--size] = null; // Let gc do its work return oldValue; } public int indexOf(Object elem) { if (data == null) { return -1; } if (elem == null) { for (int i = 0; i < size; i++) if (data[i] == null) return i; } else { for (int i = 0; i < size; i++) if (elem.equals(data[i])) return i; } return -1; } public int lastIndexOf(Object elem) { if (data == null) { return -1; } if (elem == null) { for (int i = size - 1; i >= 0; i--) if (data[i] == null) return i; } else { for (int i = size - 1; i >= 0; i--) if (elem.equals(data[i])) return i; } return -1; } public ListIterator<E> listIterator() { throw new RuntimeException("Not implemented"); } public ListIterator<E> listIterator(int index) { throw new RuntimeException("Not implemented"); } public List<E> subList(int fromIndex, int toIndex) { throw new RuntimeException("Not implemented"); } }