/** * Copyright 2010 JogAmp Community. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are * permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of * conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list * of conditions and the following disclaimer in the documentation and/or other materials * provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * The views and conclusions contained in the software and documentation are those of the * authors and should not be interpreted as representing official policies, either expressed * or implied, of JogAmp Community. */ package com.jogamp.common.util; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.ListIterator; /** * Hashed ArrayList implementation of the List and Collection interface. * * Implementation properties are: *
* Returns {@code false} if {@code null} is not a valid value, * here {@link #remove(E)} and {@link #getOrAdd(Object)} are optimized operations. *
* @see #ArrayHashSet(boolean, int, float) */ public final boolean supportsNullValue() { return supportNullValue; } // // Cloneable // /** * @return a shallow copy of this ArrayHashSet, elements are not copied. */ @Override public final Object clone() { return new ArrayHashSet* {@inheritDoc} *
* * @return true if the element was added to this list, * otherwise false (already contained). * @throws NullPointerException if {@code element} is {@code null} but {@link #supportsNullValue()} == {@code false} */ @Override public final boolean add(final E element) throws NullPointerException { if( !supportNullValue ) { checkNull(element); } if( !map.containsKey(element) ) { // !exists if(null != map.put(element, element)) { // slips a valid null .. throw new InternalError("Already existing, but checked before: "+element); } if(!data.add(element)) { throw new InternalError("Couldn't add element: "+element); } return true; } return false; } /** * Remove element from this list. ** {@inheritDoc} *
* * @return true if the element was removed from this list, * otherwise false (not contained). * @throws NullPointerException if {@code element} is {@code null} but {@link #supportsNullValue()} == {@code false} */ @Override public final boolean remove(final Object element) throws NullPointerException { if( supportNullValue ) { if( map.containsKey(element) ) { // exists map.remove(element); if ( !data.remove(element) ) { throw new InternalError("Couldn't remove prev mapped element: "+element); } return true; } } else { checkNull(element); if ( null != map.remove(element) ) { // exists if ( !data.remove(element) ) { throw new InternalError("Couldn't remove prev mapped element: "+element); } return true; } } return false; } /** * Add all elements of given {@link java.util.Collection} at the end of this list. ** {@inheritDoc} *
* * @return true if at least one element was added to this list, * otherwise false (completely container). */ @Override public final boolean addAll(final Collection extends E> c) { boolean mod = false; for (final E o : c) { mod |= add(o); } return mod; } /** * Test for containment ** {@inheritDoc} *
* * @return true if the given element is contained by this list using fast hash map, * otherwise false. */ @Override public final boolean contains(final Object element) { return map.containsKey(element); } /** * Test for containment of given {@link java.util.Collection} ** {@inheritDoc} *
* * @return true if the given Collection is completly contained by this list using hash map, * otherwise false. */ @Override public final boolean containsAll(final Collection> c) { for (final Object o : c) { if (!this.contains(o)) { return false; } } return true; } /** * Remove all elements of given {@link java.util.Collection} from this list. ** {@inheritDoc} *
* * @return true if at least one element of this list was removed, * otherwise false. */ @Override public final boolean removeAll(final Collection> c) { boolean mod = false; for (final Object o : c) { mod |= this.remove(o); } return mod; } /** * Retain all elements of the given {@link java.util.Collection} c, ie * remove all elements not contained by the given {@link java.util.Collection} c. ** {@inheritDoc} *
* * @return true if at least one element of this list was removed, * otherwise false. */ @Override public final boolean retainAll(final Collection> c) { boolean mod = false; for (final Object o : c) { if (!c.contains(o)) { mod |= this.remove(o); } } return mod; } /** * This is an O(n) operation. ** {@inheritDoc} *
* * @return true if arrayHashSet is of type ArrayHashSet and all entries are equal * Performance: arrayHashSet(1) */ @Override public final boolean equals(final Object arrayHashSet) { if ( !(arrayHashSet instanceof ArrayHashSet) ) { return false; } return data.equals(((ArrayHashSet>)arrayHashSet).data); } /** * This is an O(n) operation over the size of this list. ** {@inheritDoc} *
* * @return the hash code of this list as define in {@link java.util.List#hashCode()}, * ie hashing all elements of this list. */ @Override public final int hashCode() { return data.hashCode(); } @Override public final boolean isEmpty() { return data.isEmpty(); } @Override public final Iterator* {@inheritDoc} *
* * @throws IllegalArgumentException if the given element was already contained * @throws NullPointerException if {@code element} is {@code null} but {@link #supportsNullValue()} == {@code false} */ @Override public final void add(final int index, final E element) throws IllegalArgumentException, NullPointerException { if( !supportNullValue ) { checkNull(element); } if ( map.containsKey(element) ) { throw new IllegalArgumentException("Element "+element+" is already contained"); } if(null != map.put(element, element)) { // slips a valid null .. throw new InternalError("Already existing, but checked before: "+element); } // !exists data.add(index, element); } /** ** {@inheritDoc} *
* @throws UnsupportedOperationException */ @Override public final boolean addAll(final int index, final Collection extends E> c) throws UnsupportedOperationException { throw new UnsupportedOperationException("Not supported yet."); } /** ** {@inheritDoc} *
*/ @Override public final E set(final int index, final E element) { final E old = remove(index); if(null!=old) { add(index, element); } return old; } /** * Remove element at given index from this list. ** {@inheritDoc} *
* * @return the removed object */ @Override public final E remove(final int index) { final E o = get(index); if( null!=o && remove(o) ) { return o; } return null; } /** * Since this list is unique, equivalent to {@link #indexOf(java.lang.Object)}. ** {@inheritDoc} *
* * @return index of element, or -1 if not found */ @Override public final int lastIndexOf(final Object o) { return indexOf(o); } @Override public final ListIteratorkey
hash code,
* or null if not contained
*/
public final E get(final Object element) {
return map.get(element);
}
/**
* Identity method allowing to get the identical object, using the internal hash map.element
is not yet contained, add it.
* key
hash code,
* or add the given key
and return it.
* @throws NullPointerException if {@code element} is {@code null} but {@link #supportsNullValue()} == {@code false}
*/
public final E getOrAdd(final E element) throws NullPointerException {
if( supportNullValue ) {
if( map.containsKey(element) ) {
// existent
return map.get(element);
}
} else {
checkNull(element);
final E identity = map.get(element);
if(null != identity) {
// existent
return identity;
}
}
// !existent
if(!this.add(element)) {
throw new InternalError("Element not mapped, but contained in list: "+element);
}
return element;
}
/**
* Test for containment
*