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 class SanityChecks
{ {
public static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
public static byte castToByte(int value) 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"); 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"); if(value < -Float.MAX_VALUE || value > Float.MAX_VALUE) throw new IllegalStateException("Value ["+value+"] out of Float range");
return (float)value; 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; import java.util.Collection;
#endif #endif
import java.util.AbstractCollection; import java.util.AbstractCollection;
import speiger.src.collections.PACKAGE.collections.COLLECTION;
#if !TYPE_OBJECT #if !TYPE_OBJECT
import speiger.src.collections.PACKAGE.utils.ITERATORS; import speiger.src.collections.PACKAGE.utils.ITERATORS;
#endif #endif
@ -18,8 +20,9 @@ public abstract class ABSTRACT_COLLECTION KEY_GENERIC_TYPE extends AbstractColle
@Deprecated @Deprecated
public boolean add(CLASS_TYPE e) { return COLLECTION.super.add(e); } public boolean add(CLASS_TYPE e) { return COLLECTION.super.add(e); }
#endif
@Override @Override
public boolean addAll(COLLECTION c) { public boolean addAll(COLLECTION KEY_GENERIC_TYPE c) {
boolean modified = false; boolean modified = false;
for(KEY_TYPE e : c) { for(KEY_TYPE e : c) {
modified |= add(e); modified |= add(e);
@ -27,6 +30,7 @@ public abstract class ABSTRACT_COLLECTION KEY_GENERIC_TYPE extends AbstractColle
return modified; return modified;
} }
#if !TYPE_OBJECT
@Override @Override
@Deprecated @Deprecated
public boolean contains(Object e) { return COLLECTION.super.contains(e); } 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> public interface BI_ITERATOR KEY_GENERIC_TYPE extends ITERATOR KEY_GENERIC_TYPE, ObjectBidirectionalIterator<CLASS_TYPE>
#else #else
import speiger.src.collections.utils.BidirectionalIterator; public interface BI_ITERATOR KEY_GENERIC_TYPE extends ITERATOR KEY_GENERIC_TYPE
public interface BI_ITERATOR KEY_GENERIC_TYPE extends ITERATOR KEY_GENERIC_TYPE, BidirectionalIterator<CLASS_TYPE>
#endif #endif
{ {
public boolean hasPrevious();
public KEY_TYPE PREVIOUS(); public KEY_TYPE PREVIOUS();
#if !TYPE_OBJECT #if !TYPE_OBJECT
@ -24,5 +24,12 @@ public interface BI_ITERATOR KEY_GENERIC_TYPE extends ITERATOR KEY_GENERIC_TYPE,
{ {
return ITERATOR.super.skip(amount); return ITERATOR.super.skip(amount);
} }
#endif #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 #if !TYPE_OBJECT
public boolean add(KEY_TYPE o); 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 contains(KEY_TYPE o);
public boolean containsAll(COLLECTION c); public boolean containsAll(COLLECTION c);

View File

@ -4,9 +4,7 @@ import java.util.Collection;
import java.util.Objects; import java.util.Objects;
import speiger.src.collections.PACKAGE.collections.ABSTRACT_COLLECTION; import speiger.src.collections.PACKAGE.collections.ABSTRACT_COLLECTION;
#if !TYPE_OBJECT
import speiger.src.collections.PACKAGE.collections.COLLECTION; import speiger.src.collections.PACKAGE.collections.COLLECTION;
#endif
import speiger.src.collections.PACKAGE.collections.ITERATOR; 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 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; return true;
} }
#if !TYPE_OBJECT
@Override @Override
public boolean addAll(int index, COLLECTION KEY_GENERIC_TYPE c) { public boolean addAll(int index, COLLECTION KEY_GENERIC_TYPE c) {
checkAddRange(index); checkAddRange(index);
@ -168,7 +165,6 @@ public abstract class ABSTRACT_LIST KEY_GENERIC_TYPE extends ABSTRACT_COLLECTION
return true; return true;
} }
#endif
@Override @Override
public boolean addAll(int index, LIST KEY_GENERIC_TYPE c) { public boolean addAll(int index, LIST KEY_GENERIC_TYPE c) {
checkAddRange(index); checkAddRange(index);
@ -179,6 +175,48 @@ public abstract class ABSTRACT_LIST KEY_GENERIC_TYPE extends ABSTRACT_COLLECTION
return true; 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 @Override
public KEY_TYPE GET_KEY(int index) { public KEY_TYPE GET_KEY(int index) {
checkRange(index); checkRange(index);

View File

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

View File

@ -3,6 +3,8 @@ package speiger.src.collections.PACKAGE.utils;
public class ARRAYS public class ARRAYS
{ {
#if !TYPE_OBJECT #if !TYPE_OBJECT
public static final KEY_TYPE[] EMPTY_ARRAY = new KEY_TYPE[0];
public static CLASS_TYPE[] wrap(KEY_TYPE[] a) { public static CLASS_TYPE[] wrap(KEY_TYPE[] a) {
CLASS_TYPE[] result = new CLASS_TYPE[a.length]; CLASS_TYPE[] result = new CLASS_TYPE[a.length];
for(int i = 0,m=a.length;i<m;i++) for(int i = 0,m=a.length;i<m;i++)
@ -16,5 +18,13 @@ public class ARRAYS
result[i] = OBJ_TO_KEY(a[i]); result[i] = OBJ_TO_KEY(a[i]);
return result; 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 #endif
} }