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

org.graphstream.util.set.FixedArrayList Maven / Gradle / Ivy

/*
 * This file is part of GraphStream .
 * 
 * GraphStream is a library whose purpose is to handle static or dynamic
 * graph, create them from scratch, file or any source and display them.
 * 
 * This program is free software distributed under the terms of two licenses, the
 * CeCILL-C license that fits European law, and the GNU Lesser General Public
 * License. You can  use, modify and/ or redistribute the software under the terms
 * of the CeCILL-C license as circulated by CEA, CNRS and INRIA at the following
 * URL  or under the terms of the GNU LGPL as published by
 * the Free Software Foundation, either version 3 of the License, or (at your
 * option) any later version.
 * 
 * This program 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 program.  If not, see .
 * 
 * The fact that you are presently reading this means that you have had
 * knowledge of the CeCILL-C and LGPL licenses and that you accept their terms.
 */

/**
 * @since 2011-07-22
 * 
 * @author Guilhelm Savin 
 * @author Hicham Brahimi 
 */
package org.graphstream.util.set;

import java.util.ArrayList;
import java.util.Collection;
import java.util.NoSuchElementException;
import java.util.RandomAccess;

/**
 * Array list with immutable element indices.
 * 
 * 

* A fixed array list is like an array list, but it ensures the property that * each element will always stay at the same index, even if elements are removed * in between. The counterpart of this property is that the array handles by * itself the insertion of new elements (since when an element is removed in the * middle, this position can be reused), and therefore indices cannot be chosen * (i.e. only the {@link #add(Object)} and {@link #addAll(Collection)} methods * are usable to insert new elements in the array). *

* *

* This is the reason why this does not implement the List interface, because * the add(int,E) method cannot be implemented. *

* *

* Furthermore, this array cannot contain null values, because it marks unused * positions within the array using the null value. *

* * @author Antoine Dutot * @since 20040912 */ public class FixedArrayList implements Collection, RandomAccess { // Attributes /** * List of elements. */ protected ArrayList elements = new ArrayList(); /** * List of free indices. */ protected ArrayList freeIndices = new ArrayList(); /** * Last inserted element index. */ protected int lastIndex = -1; // Constructors public FixedArrayList() { elements = new ArrayList(); freeIndices = new ArrayList(16); } public FixedArrayList(int capacity) { elements = new ArrayList(capacity); freeIndices = new ArrayList(16); } // Accessors /** * Number of elements in the array. * * @return The number of elements in the array. */ public int size() { return elements.size() - freeIndices.size(); } /** * Real size of the array, counting elements that have been erased. * * @see #unsafeGet(int) */ public int realSize() { return elements.size(); } public boolean isEmpty() { return (size() == 0); } /** * I-th element. * * @param i * The element index. * @return The element at index i. */ public E get(int i) { E e = elements.get(i); if (e == null) throw new NoSuchElementException("no element at index " + i); return e; } /** * I-th element. Like the {@link #get(int)} method but it does not check the * element does not exists at the given index. * * @param i * The element index. * @return The element at index i. */ public E unsafeGet(int i) { return elements.get(i); } public boolean contains(Object o) { int n = elements.size(); for (int i = 0; i < n; ++i) { E e = elements.get(i); if (e != null) { if (e == o) return true; if (elements.equals(o)) return true; } } return false; } public boolean containsAll(Collection c) { for (Object o : c) { if (!contains(o)) return false; } return true; } @Override @SuppressWarnings("unchecked") public boolean equals(Object o) { if (o instanceof FixedArrayList) { FixedArrayList other = (FixedArrayList) o; int n = size(); if (other.size() == n) { for (int i = 0; i < n; ++i) { E e0 = elements.get(i); E e1 = other.elements.get(i); if (e0 != e1) { if (e0 == null && e1 != null) return false; if (e0 != null && e1 == null) return false; if (!e0.equals(e1)) return false; } } return true; } } return false; } public java.util.Iterator iterator() { return new FixedArrayIterator(); } /** * Last index used by the {@link #add(Object)} method. * * @return The last insertion index. */ public int getLastIndex() { return lastIndex; } /** * The index that will be used in case of a next insertion in this array. * * @return */ public int getNextAddIndex() { int n = freeIndices.size(); if (n > 0) return freeIndices.get(n - 1); else return elements.size(); } public Object[] toArray() { int n = size(); int m = elements.size(); int j = 0; Object a[] = new Object[n]; for (int i = 0; i < m; ++i) { E e = elements.get(i); if (e != null) a[j++] = e; } assert (j == n); return a; } public T[] toArray(T[] a) { // TODO throw new RuntimeException("not implemented yet"); } // Commands /** * Add one element in the array. The index used for inserting the * element is then available using {@link #getLastIndex()}. * * @see #getLastIndex() * @param element * The element to add. * @return Always true. * @throws NullPointerException * If a null value is inserted. */ public boolean add(E element) throws java.lang.NullPointerException { if (element == null) throw new java.lang.NullPointerException("this array cannot contain null value"); int n = freeIndices.size(); if (n > 0) { int i = freeIndices.remove(n - 1); elements.set(i, element); lastIndex = i; } else { elements.add(element); lastIndex = elements.size() - 1; } return true; } public boolean addAll(Collection c) throws UnsupportedOperationException { java.util.Iterator k = c.iterator(); while (k.hasNext()) { add(k.next()); } return true; } /** * Remove the element at index i. * * @param i * Index of the element to remove. * @return The removed element. */ public E remove(int i) { int n = elements.size(); if (i < 0 || i >= n) throw new ArrayIndexOutOfBoundsException("index " + i + " does not exist"); if (n > 0) { if (elements.get(i) == null) throw new NullPointerException("no element stored at index " + i); if (i == (n - 1)) { return elements.remove(i); } else { E e = elements.get(i); elements.set(i, null); freeIndices.add(i); return e; } } throw new ArrayIndexOutOfBoundsException("index " + i + " does not exist"); } protected void removeIt(int i) { remove(i); } /** * Remove the element e. * * @param e * The element to remove. * @return True if removed. */ public boolean remove(Object e) { int n = elements.size(); for (int i = 0; i < n; ++i) { if (elements.get(i) == e) { elements.remove(i); return true; } } return false; } public boolean removeAll(Collection c) { throw new UnsupportedOperationException("not implemented yet"); } public boolean retainAll(Collection c) { throw new UnsupportedOperationException("not implemented yet"); } public void clear() { elements.clear(); freeIndices.clear(); } // Nested classes protected class FixedArrayIterator implements java.util.Iterator { int i; public FixedArrayIterator() { i = -1; } public boolean hasNext() { int n = elements.size(); for (int j = i + 1; j < n; ++j) { if (elements.get(j) != null) return true; } return false; } public E next() { int n = elements.size(); for (int j = i + 1; j < n; ++j) { E e = elements.get(j); if (e != null) { i = j; return e; } } throw new NoSuchElementException("no more elements in iterator"); } public void remove() throws UnsupportedOperationException { // throw new UnsupportedOperationException( "not implemented yet" ); if (i >= 0 && i < elements.size() && elements.get(i) != null) { removeIt(i); // A parent class method cannot be called if it has // the same name as one in the inner class // (normal), but even if they have distinct // arguments types. Hence this strange removeIt() // method... } else { throw new IllegalStateException("no such element"); } } } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy