package speiger.src.collections.PACKAGE.lists; import java.util.Arrays; #if TYPE_OBJECT import java.util.Comparator; #endif import java.util.Collection; import java.util.Iterator; import java.util.Objects; #if TYPE_OBJECT import java.util.function.Consumer; #endif import java.util.function.Predicate; import java.util.function.UnaryOperator; #if PRIMITIVES import java.util.function.JAVA_PREDICATE; import java.util.function.JAVA_UNARY_OPERATOR; #endif import speiger.src.collections.PACKAGE.collections.COLLECTION; #if !TYPE_OBJECT import speiger.src.collections.PACKAGE.collections.STACK; #endif import speiger.src.collections.PACKAGE.collections.ITERATOR; #if !TYPE_OBJECT import speiger.src.collections.PACKAGE.functions.COMPARATOR; import speiger.src.collections.PACKAGE.functions.CONSUMER; #endif import speiger.src.collections.PACKAGE.utils.ARRAYS; import speiger.src.collections.PACKAGE.utils.ITERATORS; #if TYPE_OBJECT import speiger.src.collections.utils.Stack; #else import speiger.src.collections.objects.utils.ObjectArrays; #endif import speiger.src.collections.PACKAGE.utils.IARRAY; import speiger.src.collections.utils.SanityChecks; #if TYPE_OBJECT /** * A Type-Specific Array-based implementation of list that is written to reduce (un)boxing * *

This implementation is optimized to improve how data is processed with interfaces like {@link IARRAY}, {@link Stack} * and with optimized functions that use type-specific implementations for primitives and optimized logic for bulkactions. */ public class ARRAY_LIST KEY_GENERIC_TYPE extends ABSTRACT_LIST KEY_GENERIC_TYPE implements IARRAY, Stack #else /** * A Type-Specific Array-based implementation of list that is written to reduce (un)boxing * *

This implementation is optimized to improve how data is processed with interfaces like {@link IARRAY}, {@link STACK} * and with optimized functions that use type-specific implementations for primitives and optimized logic for bulkactions. */ public class ARRAY_LIST KEY_GENERIC_TYPE extends ABSTRACT_LIST KEY_GENERIC_TYPE implements IARRAY, STACK #endif { static final int DEFAULT_ARRAY_SIZE = 10; /** The backing array */ protected transient KEY_TYPE[] data; /** The current size of the elements stored in the backing array */ protected int size = 0; /** * Creates a new ArrayList with a Empty array. */ public ARRAY_LIST() { data = EMPTY_KEY_ARRAY; } /** * Creates a new ArrayList with the specific requested size */ public ARRAY_LIST(int size) { data = NEW_KEY_ARRAY(size); } /** * Creates a new ArrayList a copy with the contents of the Collection. */ public ARRAY_LIST(Collection c) { this(c.size()); size = ITERATORS.unwrap(data, c.iterator()); } /** * Creates a new ArrayList a copy with the contents of the Collection. */ public ARRAY_LIST(COLLECTION KEY_GENERIC_TYPE c) { this(c.size()); size = ITERATORS.unwrap(data, c.iterator()); } /** * Creates a new ArrayList a copy with the contents of the List. */ public ARRAY_LIST(LIST KEY_GENERIC_TYPE l) { this(l.size()); size = l.size(); l.getElements(0, data, 0, size); } /** * Creates a new ArrayList with a Copy of the array */ public ARRAY_LIST(KEY_TYPE[] a) { this(a, 0, a.length); } /** * Creates a new ArrayList with a Copy of the array with a custom length */ public ARRAY_LIST(KEY_TYPE[] a, int length) { this(a, 0, length); } /** * Creates a new ArrayList with a Copy of the array with in the custom range. */ public ARRAY_LIST(KEY_TYPE[] a, int offset, int length) { this(length); SanityChecks.checkArrayCapacity(a.length, offset, length); System.arraycopy(a, offset, data, 0, length); size = length; } /** * Creates a wrapped arraylist that uses the array as backing array * @param a elements that should be wrapped * @return a Wrapped list using the input array */ public static GENERIC_KEY_BRACES ARRAY_LIST KEY_GENERIC_TYPE wrap(KEY_TYPE... a) { return wrap(a, a.length); } /** * Creates a wrapped arraylist that uses the array as backing array and a custom fillsize * @param a elements that should be wrapped * @param length the size of the elements within the array * @return a Wrapped list using the input array */ public static GENERIC_KEY_BRACES ARRAY_LIST KEY_GENERIC_TYPE wrap(KEY_TYPE[] a, int length) { SanityChecks.checkArrayCapacity(a.length, 0, length); ARRAY_LIST KEY_GENERIC_TYPE list = new ARRAY_LISTBRACES(); list.data = a; list.size = length; return list; } #if TYPE_OBJECT /** * Creates a new ArrayList with a EmptyObject array of the Type requested * @param c the type of the array * @return a typed List */ public static GENERIC_KEY_BRACES ARRAY_LIST KEY_GENERIC_TYPE of(Class c) { ARRAY_LIST KEY_GENERIC_TYPE list = new ARRAY_LISTBRACES(); list.data = (KEY_TYPE[])ObjectArrays.newArray(c.getClass().getComponentType(), 0); return list; } #endif /** * Appends the specified element to the end of this list. * * @param e element to be appended to this list * @return true (as specified by {@link Collection#add}) */ @Override public boolean add(KEY_TYPE e) { grow(size + 1); data[size++] = e; return true; } /** * Appends the specified element to the end of this Stack. * @param e element to be appended to this Stack */ @Override public void PUSH(KEY_TYPE e) { add(e); } /** * Appends the specified element to the index of the list * @param index the index where to append the element to * @param e the element to append to the list * @throws IndexOutOfBoundsException if index is outside of the lists range */ @Override public void add(int index, KEY_TYPE e) { checkAddRange(index); grow(size + 1); if(index != size) System.arraycopy(data, index, data, index+1, size - index); data[index] = e; size++; } /** * Appends the specified elements to the index of the list. * This function may delegate to more appropiate function if nessesary * @param index the index where to append the elements to * @param c the elements to append to the list * @throws IndexOutOfBoundsException if index is outside of the lists range * @deprecated if type is primitive */ @Override @Primitive public boolean addAll(int index, Collection c) { if(c instanceof COLLECTION) return addAll(index, (COLLECTION KEY_GENERIC_TYPE)c); int add = c.size(); if(add <= 0) return false; grow(size + add); if(index != size) System.arraycopy(data, index, data, index+add, size - index); size+=add; Iterator iter = c.iterator(); while(add != 0) data[index++] = OBJ_TO_KEY(iter.next()); return true; } /** * Appends the specified elements to the index of the list. * This function may delegate to more appropiate function if nessesary * @param index the index where to append the elements to * @param c the elements to append to the list * @throws IndexOutOfBoundsException if index is outside of the lists range * @deprecated if type is primitive */ @Override public boolean addAll(int index, COLLECTION KEY_GENERIC_TYPE c) { if(c instanceof LIST) return addAll(index, (LIST KEY_GENERIC_TYPE)c); int add = c.size(); if(add <= 0) return false; grow(size + add); if(index != size) System.arraycopy(data, index, data, index+add, size - index); size+=add; ITERATOR KEY_GENERIC_TYPE iter = c.iterator(); while(add-- != 0) data[index++] = iter.NEXT(); return true; } /** * Appends the specified elements to the index of the list. * @param index the index where to append the elements to * @param c the elements to append to the list * @throws IndexOutOfBoundsException if index is outside of the lists range * @deprecated if type is primitive */ @Override public boolean addAll(int index, LIST KEY_GENERIC_TYPE c) { int add = c.size(); if(add <= 0) return false; checkAddRange(index); grow(size + add); if(index != size) System.arraycopy(data, index, data, index+add, size - index); size+=add; c.getElements(0, data, index, c.size()); return true; } /** * Appends the specified array elements to the index of the list. * @param from the index where to append the elements to * @param a the elements to append to the list * @param offset where to start ino the array * @param length the amount of elements to insert * @throws IndexOutOfBoundsException if index is outside of the lists range * @deprecated if type is primitive */ @Override public void addElements(int from, KEY_TYPE[] a, int offset, int length) { if(length <= 0) return; checkAddRange(from); grow(size + length); if(from != size) System.arraycopy(data, from, data, from+length, size - length); size+=length; System.arraycopy(a, offset, data, from, length); } /** * A function to fast fetch elements from the list * @param from index where the list should be fetching elements from * @param a the array where the values should be inserted to * @param offset the startIndex of where the array should be written to * @param length the number of elements the values should be fetched from * @return the inputArray * @throws NullPointerException if the array is null * @throws IndexOutOfBoundsException if from is outside of the lists range * @throws IllegalStateException if offset or length are smaller then 0 or exceed the array length */ @Override public KEY_TYPE[] getElements(int from, KEY_TYPE[] a, int offset, int length) { SanityChecks.checkArrayCapacity(size, offset, length); System.arraycopy(data, from, a, offset, length); return a; } /** * a function to fast remove elements from the list. * @param from the start index of where the elements should be removed from (inclusive) * @param to the end index of where the elements should be removed to (exclusive) */ @Override public void removeElements(int from, int to) { checkRange(from); checkAddRange(to); int length = to - from; if(length <= 0) return; if(to != size) System.arraycopy(data, to, data, from, size - to); #if TYPE_OBJECT for(int i = 0;i K[] extractElements(int from, int to, Class type) { checkRange(from); checkAddRange(to); int length = to - from; K[] a = ARRAYS.newArray(type, length); if(length <= 0) return a; System.arraycopy(data, from, a, 0, length); if(to != size) System.arraycopy(data, to, data, from, size - to); for(int i = 0;i=0;i--) if(data[i] == null) return i; return -1; } #else if(o == null) return -1; #endif for(int i = size - 1;i>=0;i--) { if(EQUALS_KEY_TYPE(data[i], o)) return i; } return -1; } #if TYPE_OBJECT /** * Sorts the elements specified by the Natural order either by using the Comparator or the elements * @param c the sorter of the elements, can be null * @see List#sort(Comparator) * @see ARRAYS#stableSort(KEY_TYPE[], Comparator) */ @Override public void sort(Comparator c) { if(c != null) ARRAYS.stableSort(data, size, c); else ARRAYS.stableSort((Comparable[])data, size); } /** * Sorts the elements specified by the Natural order either by using the Comparator or the elements using a unstable sort * @param c the sorter of the elements, can be null * @see List#sort(Comparator) * @see ARRAYS#unstableSort(KEY_TYPE[], Comparator) */ @Override public void unstableSort(Comparator c) { if(c != null) ARRAYS.unstableSort(data, size, c); else ARRAYS.unstableSort((Comparable[])data, size); } #else /** * A Type Specific implementation of the Collection#contains function. * @param e the element that is searched for. * @return if the element was found */ @Override public boolean contains(KEY_TYPE e) { return indexOf(e) != -1; } /** * A Type-Specific function to find the index of a given element * @param e the element that is searched for * @return the index of the element if found. (if not found then -1) */ @Override public int indexOf(KEY_TYPE e) { for(int i = 0;i=0;i--) { if(KEY_EQUALS(data[i], e)) return i; } return -1; } /** * Sorts the elements specified by the Natural order either by using the Comparator or the elements * @param c the sorter of the elements, can be null * @see List#sort(Comparator) * @see ARRAYS#stableSort(KEY_TYPE[], COMPARATOR) */ @Override public void sort(COMPARATOR c) { if(c != null) ARRAYS.stableSort(data, size, c); else ARRAYS.stableSort(data, size); } /** * Sorts the elements specified by the Natural order either by using the Comparator or the elements using a unstable sort * @param c the sorter of the elements, can be null * @see List#sort(Comparator) * @see ARRAYS#unstableSort(KEY_TYPE[], COMPARATOR) */ @Override public void unstableSort(COMPARATOR c) { if(c != null) ARRAYS.unstableSort(data, size, c); else ARRAYS.unstableSort(data, size); } #endif /** * A Type-Specific get function to reduce (un)boxing * @param index the index of the element to fetch * @return the value of the requested index * @throws IndexOutOfBoundsException if the index is out of range */ @Override public KEY_TYPE GET_KEY(int index) { checkRange(index); return data[index]; } /** * Provides the Selected Object from the stack. * Top to bottom * @param index of the element that should be provided * @return the element that was requested * @throws ArrayIndexOutOfBoundsException if the index is out of bounds * @see Stack#peek(int) */ @Override public KEY_TYPE PEEK(int index) { checkRange((size() - 1) - index); return data[(size() - 1) - index]; } /** * Provides the Underlying Array in the Implementation * @return underlying Array * @throws ClassCastException if the return type does not match the underlying array. (Only for Object Implementations) */ @Override public KEY_TYPE[] elements() { return data; } /** * A Type Specific foreach function that reduces (un)boxing * * @implSpec *

The default implementation behaves as if: *

{@code
     *     for(int i = 0;i
     *
     * @param action The action to be performed for each element
     * @throws java.util.NullPointerException if the specified action is null
     * @see Iterable#forEach(Consumer)
     */
	@Override
	public void forEach(CONSUMER KEY_SUPER_GENERIC_TYPE action) {
		Objects.requireNonNull(action);
		for(int i = 0;i o) {
#if PRIMITIVES
		Objects.requireNonNull(o);
#if TYPE_BYTE || TYPE_SHORT || TYPE_CHAR || TYPE_FLOAT
		REPLACE(T -> OBJ_TO_KEY(o.apply(KEY_TO_OBJ(SanityChecks.SANITY_CAST(T)))));
#else
		REPLACE(T -> OBJ_TO_KEY(o.apply(KEY_TO_OBJ(T))));
#endif
#else
		Objects.requireNonNull(o);
		for(int i = 0;i c) {
		if(c.isEmpty()) return false;
		boolean modified = false;
		int j = 0;
		for(int i = 0;i c) {
		if(c.isEmpty()) {
			boolean modifed = size > 0;
			clear();
			return modifed;
		}
		boolean modified = false;
		int j = 0;
		for(int i = 0;i filter) {
		Objects.requireNonNull(filter);
		boolean modified = false;
		int j = 0;
		for(int i = 0;i 0;
			clear();
			return modifed;
		}
		boolean modified = false;
		int j = 0;
		for(int i = 0;i E[] toArray(E[] a) {
		if(a == null) a = (E[])new Object[size];
		else if(a.length < size) a = (E[])ObjectArrays.newArray(a.getClass().getComponentType(), size);
		for(int i = 0;i data.length)
			data = Arrays.copyOf(data, size);
		else if(size < size() && size >= 0)
			Arrays.fill(data, size, size(), EMPTY_KEY_VALUE);
		this.size = size;
	}
	
	/**
	 * A function to clear all elements in the list.
	 */
	@Override
	public void clear() {
#if TYPE_OBJECT
		for(int i = 0;i size() || size() == data.length) return false;
		int value = Math.max(size, size());
		data = value == 0 ? EMPTY_KEY_ARRAY : Arrays.copyOf(data, value);
		return true;
	}
	
	/**
	 * Increases the capacity of this implementation instance, if necessary,
	 * to ensure that it can hold at least the number of elements specified by
	 * the minimum capacity argument.
	 *
	 * @param size the desired minimum capacity
	 */
	@Override
	public void ensureCapacity(int size) {
		grow(size);
	}
	
	protected void grow(int capacity) {
		if(capacity < data.length) return;
		data = Arrays.copyOf(data, data == ARRAYS.EMPTY_ARRAY ? DEFAULT_ARRAY_SIZE : (int)Math.max(Math.min((long)data.length + (data.length >> 1), SanityChecks.MAX_ARRAY_SIZE), capacity));		
	}
	
	protected void checkRange(int index) {
		if (index < 0 || index >= size)
			throw new IndexOutOfBoundsException("Index: " + index + ", Size: " + size);
	}
	
	protected void checkAddRange(int index) {
		if (index < 0 || index > size)
			throw new IndexOutOfBoundsException("Index: " + index + ", Size: " + size);
	}
}