More work on ArrayLists. Adding new functions.

This commit is contained in:
Speiger 2020-11-26 22:56:15 +01:00
parent 5cc4f35407
commit 737c87daca
9 changed files with 212 additions and 81 deletions

View File

@ -1,17 +0,0 @@
package speiger.src.collections.utils;
import java.util.Iterator;
public interface BidirectionalIterator<E> extends Iterator<E>
{
public E previous();
public boolean hasPrevious();
public default int back(int amount) {
if(amount < 0) throw new IllegalStateException("Can't go forward");
int i = 0;
for(;i<amount && hasPrevious();previous(),i++);
return i;
}
}

View File

@ -2,6 +2,8 @@ package speiger.src.collections.utils;
public class SanityChecks
{
public static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
public static byte castToByte(int value)
{
if(value > Byte.MAX_VALUE || value < Byte.MIN_VALUE) throw new IllegalStateException("Value ["+value+"] out of Byte[-128,127] range");
@ -27,4 +29,11 @@ public class SanityChecks
if(value < -Float.MAX_VALUE || value > Float.MAX_VALUE) throw new IllegalStateException("Value ["+value+"] out of Float range");
return (float)value;
}
public static void checkArrayCapacity(int arraySize, int offset, int accessSize)
{
if(offset < 0) throw new IllegalStateException("Offset is negative ("+offset+")");
else if(accessSize < 0) throw new IllegalStateException("Size is negative ("+accessSize+")");
else if(arraySize < offset + accessSize) throw new IndexOutOfBoundsException("Index (" + offset + accessSize + ") is not in size (" + arraySize + ")");
}
}

View File

@ -4,6 +4,8 @@ package speiger.src.collections.PACKAGE.collections;
import java.util.Collection;
#endif
import java.util.AbstractCollection;
import speiger.src.collections.PACKAGE.collections.COLLECTION;
#if !TYPE_OBJECT
import speiger.src.collections.PACKAGE.utils.ITERATORS;
#endif
@ -18,8 +20,9 @@ public abstract class ABSTRACT_COLLECTION KEY_GENERIC_TYPE extends AbstractColle
@Deprecated
public boolean add(CLASS_TYPE e) { return COLLECTION.super.add(e); }
#endif
@Override
public boolean addAll(COLLECTION c) {
public boolean addAll(COLLECTION KEY_GENERIC_TYPE c) {
boolean modified = false;
for(KEY_TYPE e : c) {
modified |= add(e);
@ -27,6 +30,7 @@ public abstract class ABSTRACT_COLLECTION KEY_GENERIC_TYPE extends AbstractColle
return modified;
}
#if !TYPE_OBJECT
@Override
@Deprecated
public boolean contains(Object e) { return COLLECTION.super.contains(e); }

View File

@ -5,11 +5,11 @@ import speiger.src.collections.objects.collections.ObjectBidirectionalIterator;
public interface BI_ITERATOR KEY_GENERIC_TYPE extends ITERATOR KEY_GENERIC_TYPE, ObjectBidirectionalIterator<CLASS_TYPE>
#else
import speiger.src.collections.utils.BidirectionalIterator;
public interface BI_ITERATOR KEY_GENERIC_TYPE extends ITERATOR KEY_GENERIC_TYPE, BidirectionalIterator<CLASS_TYPE>
public interface BI_ITERATOR KEY_GENERIC_TYPE extends ITERATOR KEY_GENERIC_TYPE
#endif
{
public boolean hasPrevious();
public KEY_TYPE PREVIOUS();
#if !TYPE_OBJECT
@ -24,5 +24,12 @@ public interface BI_ITERATOR KEY_GENERIC_TYPE extends ITERATOR KEY_GENERIC_TYPE,
{
return ITERATOR.super.skip(amount);
}
#endif
public default int back(int amount) {
if(amount < 0) throw new IllegalStateException("Can't go forward");
int i = 0;
for(;i<amount && hasPrevious();previous(),i++);
return i;
}
}

View File

@ -11,8 +11,10 @@ public interface COLLECTION KEY_GENERIC_TYPE extends Collection<CLASS_TYPE>, ITE
#if !TYPE_OBJECT
public boolean add(KEY_TYPE o);
public boolean addAll(COLLECTION c);
#endif
public boolean addAll(COLLECTION KEY_GENERIC_TYPE c);
#if !TYPE_OBJECT
public boolean contains(KEY_TYPE o);
public boolean containsAll(COLLECTION c);

View File

@ -4,9 +4,7 @@ import java.util.Collection;
import java.util.Objects;
import speiger.src.collections.PACKAGE.collections.ABSTRACT_COLLECTION;
#if !TYPE_OBJECT
import speiger.src.collections.PACKAGE.collections.COLLECTION;
#endif
import speiger.src.collections.PACKAGE.collections.ITERATOR;
public abstract class ABSTRACT_LIST KEY_GENERIC_TYPE extends ABSTRACT_COLLECTION KEY_GENERIC_TYPE implements LIST KEY_GENERIC_TYPE
@ -157,7 +155,6 @@ public abstract class ABSTRACT_LIST KEY_GENERIC_TYPE extends ABSTRACT_COLLECTION
return true;
}
#if !TYPE_OBJECT
@Override
public boolean addAll(int index, COLLECTION KEY_GENERIC_TYPE c) {
checkAddRange(index);
@ -168,7 +165,6 @@ public abstract class ABSTRACT_LIST KEY_GENERIC_TYPE extends ABSTRACT_COLLECTION
return true;
}
#endif
@Override
public boolean addAll(int index, LIST KEY_GENERIC_TYPE c) {
checkAddRange(index);
@ -179,6 +175,48 @@ public abstract class ABSTRACT_LIST KEY_GENERIC_TYPE extends ABSTRACT_COLLECTION
return true;
}
@Override
public void addElements(int from, KEY_TYPE[] a, int offset, int length) {
checkRange(from);
l.addElements(from + this.offset, a, offset, length);
size += length;
}
@Override
public KEY_TYPE[] getElements(int from, KEY_TYPE[] a, int offset, int length) {
checkRange(from);
return l.getElements(from + this.offset, a, offset, length);
}
@Override
public void removeElements(int from, int to) {
checkRange(from);
checkRange(to);
l.removeElements(from + offset, to + offset);
size -= to - from;
}
#if TYPE_OBJECT
@Override
public KEY_TYPE[] extractElements(int from, int to, Class<KEY_TYPE> clz) {
checkRange(from);
checkRange(to);
KEY_TYPE[] a = l.extractElements(from + offset, to + offset, clz);
size -= to - from;
return a;
}
#else
@Override
public KEY_TYPE[] extractElements(int from, int to) {
checkRange(from);
checkRange(to);
KEY_TYPE[] a = l.extractElements(from + offset, to + offset);
size -= to - from;
return a;
}
#endif
@Override
public KEY_TYPE GET_KEY(int index) {
checkRange(index);

View File

@ -1,17 +1,20 @@
package speiger.src.collections.PACKAGE.lists;
import java.util.Arrays;
import java.util.Collection;
import java.util.Iterator;
#if !TYPE_OBJECT
import speiger.src.collections.PACKAGE.collections.COLLECTION;
import speiger.src.collections.PACKAGE.collections.ITERATOR;
#endif
import speiger.src.collections.PACKAGE.utils.ARRAYS;
import speiger.src.collections.utils.SanityChecks;
public class ARRAY_LIST KEY_GENERIC_TYPE extends ABSTRACT_LIST KEY_GENERIC_TYPE
{
transient KEY_TYPE[] data;
private int size = 0;
static final int DEFAULT_ARRAY_SIZE = 10;
protected transient KEY_TYPE[] data;
protected int size = 0;
public ARRAY_LIST(int size)
{
@ -23,29 +26,26 @@ public class ARRAY_LIST KEY_GENERIC_TYPE extends ABSTRACT_LIST KEY_GENERIC_TYPE
}
@Override
public void add(int index, CLASS_TYPE element)
{
public void add(int index, CLASS_TYPE element) {
checkAddRange(index);
ensureCapacity(size + 1);
grow(size + 1);
if(index != size) System.arraycopy(data, index, data, index+1, size - index);
data[index] = OBJ_TO_KEY(element);
size++;
}
@Override
public boolean add(KEY_TYPE e)
{
ensureCapacity(size + 1);
public boolean add(KEY_TYPE e) {
grow(size + 1);
data[size++] = e;
return true;
}
#if !TYPE_OBJECT
@Override
public void add(int index, KEY_TYPE e)
{
public void add(int index, KEY_TYPE e) {
checkAddRange(index);
ensureCapacity(size + 1);
grow(size + 1);
if(index != size) System.arraycopy(data, index, data, index+1, size - index);
data[index] = e;
size++;
@ -53,14 +53,11 @@ public class ARRAY_LIST KEY_GENERIC_TYPE extends ABSTRACT_LIST KEY_GENERIC_TYPE
#endif
@Override
public boolean addAll(int index, Collection<? extends CLASS_TYPE> c)
{
#if !TYPE_OBJECT
if(c instanceof COLLECTION) return addAll((COLLECTION)c);
#endif
public boolean addAll(int index, Collection<? extends CLASS_TYPE> c) {
if(c instanceof COLLECTION) return addAll(index, (COLLECTION KEY_GENERIC_TYPE)c);
int add = c.size();
if(add <= 0) return false;
ensureCapacity(size + add);
grow(size + add);
if(index != size) System.arraycopy(data, index, data, index+add, size - index);
size+=add;
Iterator<? extends CLASS_TYPE> iter = c.iterator();
@ -68,14 +65,12 @@ public class ARRAY_LIST KEY_GENERIC_TYPE extends ABSTRACT_LIST KEY_GENERIC_TYPE
return true;
}
#if !TYPE_OBJECT
@Override
public boolean addAll(int index, COLLECTION KEY_GENERIC_TYPE c)
{
if(c instanceof LIST) return addAll((LIST)c);
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;
ensureCapacity(size + add);
grow(size + add);
if(index != size) System.arraycopy(data, index, data, index+add, size - index);
size+=add;
ITERATOR KEY_GENERIC_TYPE iter = c.iterator();
@ -83,34 +78,95 @@ public class ARRAY_LIST KEY_GENERIC_TYPE extends ABSTRACT_LIST KEY_GENERIC_TYPE
return true;
}
#endif
@Override
public boolean addAll(int index, LIST KEY_GENERIC_TYPE c)
{
return false;
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 KEY_TYPE GET_KEY(int index)
{
if (index >= size) throw new IndexOutOfBoundsException("Index (" + index + ") is not in lists size (" + size + ")");
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;
#endif
size -= length;
}
#if TYPE_OBJECT
@Override
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;
}
#else
@Override
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);
return data[index];
}
@Override
public KEY_TYPE set(int index, KEY_TYPE e)
{
if (index >= size) throw new IndexOutOfBoundsException("Index (" + index + ") is not in lists size (" + size + ")");
public KEY_TYPE set(int index, KEY_TYPE e) {
checkRange(index);
KEY_TYPE old = data[index];
data[index] = e;
return old;
}
@Override
public KEY_TYPE REMOVE(int index)
{
if (index >= size) throw new IndexOutOfBoundsException("Index (" + index + ") is not in lists size (" + size + ")");
public KEY_TYPE REMOVE(int index) {
checkRange(index);
KEY_TYPE old = data[index];
if(index != size) System.arraycopy(data, index+1, data, index, size - index);
#if TYPE_OBJECT
@ -121,27 +177,31 @@ public class ARRAY_LIST KEY_GENERIC_TYPE extends ABSTRACT_LIST KEY_GENERIC_TYPE
}
@Override
public int size()
{
public int size() {
return size;
}
@Override
public void clear()
{
public void clear() {
#if TYPE_OBJECT
for(int i = 0;i<size;data[i] = null,i++);
#endif
size = 0;
}
protected void ensureCapacity(int capacity)
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 checkAddRange(int index)
{
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);
}
}

View File

@ -10,9 +10,9 @@ public interface LIST KEY_GENERIC_TYPE extends COLLECTION KEY_GENERIC_TYPE, List
public void add(int index, KEY_TYPE e);
public boolean addAll(int index, COLLECTION c);
#endif
public boolean addAll(int index, COLLECTION KEY_GENERIC_TYPE c);
public boolean addAll(LIST KEY_GENERIC_TYPE c);
public boolean addAll(int index, LIST KEY_GENERIC_TYPE c);
@ -28,6 +28,24 @@ public interface LIST KEY_GENERIC_TYPE extends COLLECTION KEY_GENERIC_TYPE, List
public int lastIndexOf(KEY_TYPE e);
#endif
public default void addElements(int from, KEY_TYPE[] a) { addElements(from, a, 0, a.length); }
public void addElements(int from, KEY_TYPE[] a, int offset, int length);
public default KEY_TYPE[] getElements(int from, KEY_TYPE[] a) { return getElements(from, a, 0, a.length); }
public KEY_TYPE[] getElements(int from, KEY_TYPE[] a, int offset, int length);
public void removeElements(int from, int to);
#if TYPE_OBJECT
public KEY_TYPE[] extractElements(int from, int to, Class<KEY_TYPE> type);
#else
public KEY_TYPE[] extractElements(int from, int to);
#endif
@Override
public LIST_ITERATOR KEY_GENERIC_TYPE listIterator();

View File

@ -3,6 +3,8 @@ package speiger.src.collections.PACKAGE.utils;
public class ARRAYS
{
#if !TYPE_OBJECT
public static final KEY_TYPE[] EMPTY_ARRAY = new KEY_TYPE[0];
public static CLASS_TYPE[] wrap(KEY_TYPE[] a) {
CLASS_TYPE[] result = new CLASS_TYPE[a.length];
for(int i = 0,m=a.length;i<m;i++)
@ -16,5 +18,13 @@ public class ARRAYS
result[i] = OBJ_TO_KEY(a[i]);
return result;
}
#else
public static final Object[] EMPTY_ARRAY = new Object[0];
public static KEY_GENERIC_TYPE KEY_TYPE[] newArray(Class<KEY_TYPE> clz, int length) {
if(clz == Object.class) return (KEY_TYPE[])new Object[length];
return (KEY_TYPE[]) java.lang.reflect.Array.newInstance(clz, length);
}
#endif
}