/******************************************************************************* * Copyright (c) 2009 MATERNA Information & Communications. All rights reserved. * This program and the accompanying materials are made available under the * terms of the Eclipse Public License v1.0 which accompanies this distribution, * and is available at http://www.eclipse.org/legal/epl-v10.html. For further * project-related information visit http://www.ws4d.org. The most recent * version of the JMEDS framework can be obtained from * http://sourceforge.net/projects/ws4d-javame. ******************************************************************************/ package org.ws4d.java.structures; public class ArrayList extends List { private final static int CAPACITY_DEFAULT = 10; final int capacityIncrement; Object[] elements; /** * Constructor. */ public ArrayList() { this(CAPACITY_DEFAULT); } /** * Constructor. * * @param data */ public ArrayList(DataStructure data) { this(data.size(), 0); addAll(data); } /** * Constructor. * * @param initialCapacity */ public ArrayList(final int initialCapacity) { this(initialCapacity, 0); } /** * Constructor. * * @param initialCapacity * @param capacityIncrement */ public ArrayList(final int initialCapacity, final int capacityIncrement) { this.elements = new Object[initialCapacity]; this.capacityIncrement = capacityIncrement; } /** * Constructor. * * @param it */ public ArrayList(Iterator it) { this(CAPACITY_DEFAULT, 0); while (it.hasNext()) { this.add(it.next()); } } // --------------------------- METHODS -------------------------- public void add(int index, Object obj) { if (index < 0 || index > size) { throw new IndexOutOfBoundsException("Index: " + index + ", Size: " + size); } changes++; checkCapacity(size + 1); System.arraycopy(elements, index, elements, index + 1, size - index); elements[index] = obj; size++; } public boolean add(Object obj) { changes++; checkCapacity(size + 1); elements[size++] = obj; return true; } private void checkBounds(int index) { if (index >= size) { throw new IndexOutOfBoundsException("Index: " + index + ", Size: " + size); } } private void checkCapacity(final int minCapacity) { int oldCapacity = elements.length; if (minCapacity > oldCapacity) { Object[] oldElements = elements; int newCapacity = (capacityIncrement <= 0 ? (oldCapacity << 1) + 1 : oldCapacity + capacityIncrement); if (newCapacity < minCapacity) { newCapacity = minCapacity; } elements = new Object[newCapacity]; System.arraycopy(oldElements, 0, elements, 0, oldElements.length); } } public void clear() { for (int i = 0; i < size; i++) { elements[i] = null; } size = 0; changes++; } public boolean contains(Object obj) { return indexOf(obj) >= 0; } public Object get(int index) { checkBounds(index); return elements[index]; } public int indexOf(Object o) { if (o == null) { for (int i = 0; i < size; i++) if (elements[i] == null) return i; } else { for (int i = 0; i < size; i++) if (o.equals(elements[i])) return i; } return -1; } public int lastIndexOf(Object o) { if (o == null) { for (int i = size - 1; i >= 0; i--) if (elements[i] == null) return i; } else { for (int i = size - 1; i >= 0; i--) if (o.equals(elements[i])) return i; } return -1; } public Object remove(int index) { checkBounds(index); Object oldValue = elements[index]; remove0(index); return oldValue; } public boolean remove(Object o) { if (o == null) { for (int index = 0; index < size; index++) if (elements[index] == null) { remove0(index); return true; } } else { for (int index = 0; index < size; index++) if (o.equals(elements[index])) { remove0(index); return true; } } return false; } private void remove0(final int index) { int numMoved = size - index - 1; if (numMoved > 0) { System.arraycopy(elements, index + 1, elements, index, numMoved); } elements[--size] = null; changes++; } /** * Optimizing ArrayList.removeAll (see * http://ahmadsoft.org/articles/removeall/index.html) */ public boolean removeAll(DataStructure data) { int oldHi = 0, newHi = 0, top = 0; for (int i = 0; i < size; ++i) { if (data.contains(elements[i])) { changes++; oldHi = newHi; newHi = i; // at the end of this loop newHi will be the non-inclusive // upper limit of the range to delete. // while (++newHi < size && data.contains(elements[newHi])) { changes++; } final int length = i - oldHi; System.arraycopy(elements, oldHi, elements, top, length); i = newHi; top += length; } } if (newHi > 0) { final int k = size - newHi; System.arraycopy(elements, newHi, elements, top, k); final int n = top + k; for (int i = n; i < size; i++) { elements[i] = null; } size = n; return true; } else { return false; } } public Object set(int index, Object obj) { checkBounds(index); Object oldObj = elements[index]; elements[index] = obj; return oldObj; } public Object[] toArray() { Object[] array = new Object[size]; System.arraycopy(elements, 0, array, 0, size); return array; } public Object[] toArray(Object[] array) { if (array.length < size) { return toArray(); } System.arraycopy(elements, 0, array, 0, size); if (array.length > size) { for (int i = 0; i < array.length; i++) { array[i] = null; } } return array; } }