2020-11-16 02:55:33 +01:00
|
|
|
package speiger.src.collections.PACKAGE.lists;
|
|
|
|
|
2020-11-26 22:56:15 +01:00
|
|
|
import java.util.Arrays;
|
2020-11-16 02:55:33 +01:00
|
|
|
import java.util.Collection;
|
|
|
|
import java.util.Iterator;
|
|
|
|
|
|
|
|
import speiger.src.collections.PACKAGE.collections.COLLECTION;
|
2020-11-28 15:05:28 +01:00
|
|
|
#if !TYPE_OBJECT
|
|
|
|
import speiger.src.collections.PACKAGE.collections.STACK;
|
|
|
|
#endif
|
2020-11-16 02:55:33 +01:00
|
|
|
import speiger.src.collections.PACKAGE.collections.ITERATOR;
|
2020-11-26 22:56:15 +01:00
|
|
|
import speiger.src.collections.PACKAGE.utils.ARRAYS;
|
2020-11-28 15:05:28 +01:00
|
|
|
import speiger.src.collections.PACKAGE.utils.ITERATORS;
|
|
|
|
#if TYPE_OBJECT
|
|
|
|
import speiger.src.collections.utils.Stack;
|
|
|
|
#endif
|
|
|
|
import speiger.src.collections.utils.IArray;
|
2020-11-26 22:56:15 +01:00
|
|
|
import speiger.src.collections.utils.SanityChecks;
|
2020-11-16 02:55:33 +01:00
|
|
|
|
2020-11-28 15:05:28 +01:00
|
|
|
#if TYPE_OBJECT
|
|
|
|
public class ARRAY_LIST KEY_GENERIC_TYPE extends ABSTRACT_LIST KEY_GENERIC_TYPE implements IArray, Stack<KEY_TYPE>
|
|
|
|
#else
|
|
|
|
public class ARRAY_LIST KEY_GENERIC_TYPE extends ABSTRACT_LIST KEY_GENERIC_TYPE implements IArray, STACK
|
|
|
|
#endif
|
2020-11-16 02:55:33 +01:00
|
|
|
{
|
2020-11-26 22:56:15 +01:00
|
|
|
static final int DEFAULT_ARRAY_SIZE = 10;
|
|
|
|
|
|
|
|
protected transient KEY_TYPE[] data;
|
|
|
|
protected int size = 0;
|
2020-11-16 02:55:33 +01:00
|
|
|
|
2020-11-28 15:05:28 +01:00
|
|
|
public ARRAY_LIST() {
|
|
|
|
#if TYPE_OBJECT
|
|
|
|
data = (KEY_TYPE[])ARRAYS.EMPTY_ARRAY;
|
|
|
|
#else
|
|
|
|
data = ARRAYS.EMPTY_ARRAY;
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
public ARRAY_LIST(int size) {
|
2020-11-16 02:55:33 +01:00
|
|
|
#if TYPE_OBJECT
|
|
|
|
data = (KEY_TYPE[])new Object[size];
|
|
|
|
#else
|
|
|
|
data = new KEY_TYPE[size];
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2020-11-28 15:05:28 +01:00
|
|
|
public ARRAY_LIST(Collection<? extends CLASS_TYPE> c) {
|
|
|
|
this(c.size());
|
|
|
|
size = ITERATORS.unwrap(data, c.iterator());
|
|
|
|
}
|
|
|
|
|
|
|
|
public ARRAY_LIST(COLLECTION KEY_GENERIC_TYPE c) {
|
|
|
|
this(c.size());
|
|
|
|
size = ITERATORS.unwrap(data, c.iterator());
|
|
|
|
}
|
|
|
|
|
|
|
|
public ARRAY_LIST(LIST KEY_GENERIC_TYPE l) {
|
|
|
|
this(l.size());
|
|
|
|
size = l.size();
|
|
|
|
l.getElements(0, data, 0, size);
|
|
|
|
}
|
|
|
|
|
|
|
|
public ARRAY_LIST(KEY_TYPE[] a) {
|
|
|
|
this(a, 0, a.length);
|
|
|
|
}
|
|
|
|
|
|
|
|
public ARRAY_LIST(KEY_TYPE[] a, int length) {
|
|
|
|
this(a, 0, length);
|
|
|
|
}
|
|
|
|
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
|
|
|
public static GENERIC_BRACES ARRAY_LIST KEY_GENERIC_TYPE wrap(KEY_TYPE[] a) {
|
|
|
|
return wrap(a, a.length);
|
|
|
|
}
|
|
|
|
|
|
|
|
public static GENERIC_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;
|
|
|
|
}
|
|
|
|
|
2020-11-16 02:55:33 +01:00
|
|
|
@Override
|
2020-11-26 22:56:15 +01:00
|
|
|
public void add(int index, CLASS_TYPE element) {
|
2020-11-16 02:55:33 +01:00
|
|
|
checkAddRange(index);
|
2020-11-26 22:56:15 +01:00
|
|
|
grow(size + 1);
|
2020-11-16 02:55:33 +01:00
|
|
|
if(index != size) System.arraycopy(data, index, data, index+1, size - index);
|
|
|
|
data[index] = OBJ_TO_KEY(element);
|
|
|
|
size++;
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
2020-11-26 22:56:15 +01:00
|
|
|
public boolean add(KEY_TYPE e) {
|
|
|
|
grow(size + 1);
|
2020-11-16 02:55:33 +01:00
|
|
|
data[size++] = e;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
#if !TYPE_OBJECT
|
|
|
|
@Override
|
2020-11-26 22:56:15 +01:00
|
|
|
public void add(int index, KEY_TYPE e) {
|
2020-11-16 02:55:33 +01:00
|
|
|
checkAddRange(index);
|
2020-11-26 22:56:15 +01:00
|
|
|
grow(size + 1);
|
2020-11-16 02:55:33 +01:00
|
|
|
if(index != size) System.arraycopy(data, index, data, index+1, size - index);
|
|
|
|
data[index] = e;
|
|
|
|
size++;
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif
|
|
|
|
@Override
|
2020-11-26 22:56:15 +01:00
|
|
|
public boolean addAll(int index, Collection<? extends CLASS_TYPE> c) {
|
|
|
|
if(c instanceof COLLECTION) return addAll(index, (COLLECTION KEY_GENERIC_TYPE)c);
|
2020-11-16 02:55:33 +01:00
|
|
|
int add = c.size();
|
|
|
|
if(add <= 0) return false;
|
2020-11-26 22:56:15 +01:00
|
|
|
grow(size + add);
|
2020-11-16 02:55:33 +01:00
|
|
|
if(index != size) System.arraycopy(data, index, data, index+add, size - index);
|
|
|
|
size+=add;
|
|
|
|
Iterator<? extends CLASS_TYPE> iter = c.iterator();
|
|
|
|
while(add != 0) data[index++] = OBJ_TO_KEY(iter.next());
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
2020-11-26 22:56:15 +01:00
|
|
|
public boolean addAll(int index, COLLECTION KEY_GENERIC_TYPE c) {
|
|
|
|
if(c instanceof LIST) return addAll(index, (LIST KEY_GENERIC_TYPE)c);
|
2020-11-16 02:55:33 +01:00
|
|
|
int add = c.size();
|
|
|
|
if(add <= 0) return false;
|
2020-11-26 22:56:15 +01:00
|
|
|
grow(size + add);
|
2020-11-16 02:55:33 +01:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2020-11-26 22:56:15 +01:00
|
|
|
@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, size);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
@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);
|
|
|
|
}
|
|
|
|
|
|
|
|
@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;
|
|
|
|
}
|
|
|
|
|
|
|
|
@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<length;i++)
|
|
|
|
data[i+to] = null;
|
2020-11-16 02:55:33 +01:00
|
|
|
#endif
|
2020-11-26 22:56:15 +01:00
|
|
|
size -= length;
|
|
|
|
}
|
2020-11-16 02:55:33 +01:00
|
|
|
|
2020-11-26 22:56:15 +01:00
|
|
|
#if TYPE_OBJECT
|
2020-11-16 02:55:33 +01:00
|
|
|
@Override
|
2020-11-26 22:56:15 +01:00
|
|
|
public KEY_TYPE[] extractElements(int from, int to, Class<KEY_TYPE> type) {
|
|
|
|
checkRange(from);
|
|
|
|
checkAddRange(to);
|
|
|
|
int length = to - from;
|
|
|
|
KEY_TYPE[] 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<length;i++)
|
|
|
|
data[i+to] = null;
|
|
|
|
size -= length;
|
|
|
|
return a;
|
2020-11-16 02:55:33 +01:00
|
|
|
}
|
2020-11-26 22:56:15 +01:00
|
|
|
|
|
|
|
#else
|
2020-11-16 02:55:33 +01:00
|
|
|
@Override
|
2020-11-26 22:56:15 +01:00
|
|
|
public KEY_TYPE[] extractElements(int from, int to) {
|
|
|
|
int length = to - from;
|
|
|
|
if(length <= 0) return ARRAYS.EMPTY_ARRAY;
|
|
|
|
KEY_TYPE[] a = new KEY_TYPE[length];
|
|
|
|
System.arraycopy(data, from, a, 0, length);
|
|
|
|
if(to != size) System.arraycopy(data, to, data, from, size - to);
|
|
|
|
size -= length;
|
|
|
|
return a;
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif
|
|
|
|
@Override
|
|
|
|
public KEY_TYPE GET_KEY(int index) {
|
|
|
|
checkRange(index);
|
2020-11-16 02:55:33 +01:00
|
|
|
return data[index];
|
|
|
|
}
|
2020-11-28 15:05:28 +01:00
|
|
|
|
2020-11-16 02:55:33 +01:00
|
|
|
@Override
|
2020-11-26 22:56:15 +01:00
|
|
|
public KEY_TYPE set(int index, KEY_TYPE e) {
|
|
|
|
checkRange(index);
|
2020-11-16 02:55:33 +01:00
|
|
|
KEY_TYPE old = data[index];
|
|
|
|
data[index] = e;
|
|
|
|
return old;
|
|
|
|
}
|
2020-11-28 15:05:28 +01:00
|
|
|
|
2020-11-16 02:55:33 +01:00
|
|
|
@Override
|
2020-11-26 22:56:15 +01:00
|
|
|
public KEY_TYPE REMOVE(int index) {
|
|
|
|
checkRange(index);
|
2020-11-16 02:55:33 +01:00
|
|
|
KEY_TYPE old = data[index];
|
|
|
|
if(index != size) System.arraycopy(data, index+1, data, index, size - index);
|
|
|
|
#if TYPE_OBJECT
|
|
|
|
data[size] = null;
|
|
|
|
#endif
|
|
|
|
size--;
|
|
|
|
return old;
|
|
|
|
}
|
2020-11-26 22:56:15 +01:00
|
|
|
|
2020-11-16 02:55:33 +01:00
|
|
|
@Override
|
2020-11-26 22:56:15 +01:00
|
|
|
public int size() {
|
2020-11-16 02:55:33 +01:00
|
|
|
return size;
|
|
|
|
}
|
|
|
|
|
2020-11-28 15:05:28 +01:00
|
|
|
@Override
|
|
|
|
public void size(int size) {
|
|
|
|
if(size > data.length)
|
|
|
|
data = Arrays.copyOf(data, size);
|
|
|
|
else if(size < size() && size >= 0)
|
|
|
|
Arrays.fill(data, size, size(), EMPTY_VALUE);
|
|
|
|
}
|
|
|
|
|
2020-11-16 02:55:33 +01:00
|
|
|
@Override
|
2020-11-26 22:56:15 +01:00
|
|
|
public void clear() {
|
2020-11-16 02:55:33 +01:00
|
|
|
#if TYPE_OBJECT
|
|
|
|
for(int i = 0;i<size;data[i] = null,i++);
|
|
|
|
#endif
|
|
|
|
size = 0;
|
|
|
|
}
|
|
|
|
|
2020-11-28 15:05:28 +01:00
|
|
|
@Override
|
|
|
|
public void trim(int size) {
|
|
|
|
if(size > size() || size() == data.length) return;
|
|
|
|
int value = Math.min(size, size());
|
|
|
|
#if TYPE_OBJECT
|
|
|
|
data = value == 0 ? (KEY_TYPE[])ARRAYS.EMPTY_ARRAY : Arrays.copyOf(data, value);
|
|
|
|
#else
|
|
|
|
data = value == 0 ? ARRAYS.EMPTY_ARRAY : Arrays.copyOf(data, value);
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void ensureCapacity(int size) {
|
|
|
|
grow(size);
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void PUSH(KEY_TYPE e) {
|
|
|
|
add(e);
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public KEY_TYPE POP() {
|
|
|
|
return REMOVE(size() - 1);
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public KEY_TYPE PEEK(int index) {
|
|
|
|
checkRange((size() - 1) - index);
|
|
|
|
return data[(size() - 1) - index];
|
|
|
|
}
|
|
|
|
|
2020-11-26 22:56:15 +01:00
|
|
|
protected void grow(int capacity)
|
2020-11-16 02:55:33 +01:00
|
|
|
{
|
2020-11-26 22:56:15 +01:00
|
|
|
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));
|
2020-11-16 02:55:33 +01:00
|
|
|
}
|
|
|
|
|
2020-11-26 22:56:15 +01:00
|
|
|
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);
|
2020-11-16 02:55:33 +01:00
|
|
|
}
|
|
|
|
}
|