From 737c87daca666cd36437813ae010b738ae4570bd Mon Sep 17 00:00:00 2001 From: Speiger Date: Thu, 26 Nov 2020 22:56:15 +0100 Subject: [PATCH] More work on ArrayLists. Adding new functions. --- .../utils/BidirectionalIterator.java | 17 -- .../src/collections/utils/SanityChecks.java | 9 + .../collections/AbstractCollection.template | 8 +- .../BidirectionalIterator.template | 15 +- .../templates/collections/Collection.template | 4 +- .../templates/lists/AbstractList.template | 46 +++++- .../templates/lists/ArrayList.template | 156 ++++++++++++------ .../collections/templates/lists/List.template | 26 ++- .../templates/utils/Arrays.template | 12 +- 9 files changed, 212 insertions(+), 81 deletions(-) delete mode 100644 src/main/java/speiger/src/collections/utils/BidirectionalIterator.java diff --git a/src/main/java/speiger/src/collections/utils/BidirectionalIterator.java b/src/main/java/speiger/src/collections/utils/BidirectionalIterator.java deleted file mode 100644 index 72d4c2d..0000000 --- a/src/main/java/speiger/src/collections/utils/BidirectionalIterator.java +++ /dev/null @@ -1,17 +0,0 @@ -package speiger.src.collections.utils; - -import java.util.Iterator; - -public interface BidirectionalIterator extends Iterator -{ - 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 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 + ")"); + } } diff --git a/src/main/resources/speiger/assets/collections/templates/collections/AbstractCollection.template b/src/main/resources/speiger/assets/collections/templates/collections/AbstractCollection.template index 708ca7c..5577893 100644 --- a/src/main/resources/speiger/assets/collections/templates/collections/AbstractCollection.template +++ b/src/main/resources/speiger/assets/collections/templates/collections/AbstractCollection.template @@ -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 @@ -17,9 +19,10 @@ public abstract class ABSTRACT_COLLECTION KEY_GENERIC_TYPE extends AbstractColle @Override @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); } diff --git a/src/main/resources/speiger/assets/collections/templates/collections/BidirectionalIterator.template b/src/main/resources/speiger/assets/collections/templates/collections/BidirectionalIterator.template index ffeafef..6e7e107 100644 --- a/src/main/resources/speiger/assets/collections/templates/collections/BidirectionalIterator.template +++ b/src/main/resources/speiger/assets/collections/templates/collections/BidirectionalIterator.template @@ -5,13 +5,13 @@ import speiger.src.collections.objects.collections.ObjectBidirectionalIterator; public interface BI_ITERATOR KEY_GENERIC_TYPE extends ITERATOR KEY_GENERIC_TYPE, ObjectBidirectionalIterator #else -import speiger.src.collections.utils.BidirectionalIterator; - -public interface BI_ITERATOR KEY_GENERIC_TYPE extends ITERATOR KEY_GENERIC_TYPE, BidirectionalIterator +public interface BI_ITERATOR KEY_GENERIC_TYPE extends ITERATOR KEY_GENERIC_TYPE #endif { + public boolean hasPrevious(); + public KEY_TYPE PREVIOUS(); - + #if !TYPE_OBJECT @Override @Deprecated @@ -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, 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); diff --git a/src/main/resources/speiger/assets/collections/templates/lists/AbstractList.template b/src/main/resources/speiger/assets/collections/templates/lists/AbstractList.template index 7ca0930..81f0dfc 100644 --- a/src/main/resources/speiger/assets/collections/templates/lists/AbstractList.template +++ b/src/main/resources/speiger/assets/collections/templates/lists/AbstractList.template @@ -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 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); diff --git a/src/main/resources/speiger/assets/collections/templates/lists/ArrayList.template b/src/main/resources/speiger/assets/collections/templates/lists/ArrayList.template index 50b64f3..0f4be7c 100644 --- a/src/main/resources/speiger/assets/collections/templates/lists/ArrayList.template +++ b/src/main/resources/speiger/assets/collections/templates/lists/ArrayList.template @@ -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 c) - { -#if !TYPE_OBJECT - if(c instanceof COLLECTION) return addAll((COLLECTION)c); -#endif + 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; - ensureCapacity(size + add); + grow(size + add); if(index != size) System.arraycopy(data, index, data, index+add, size - index); size+=add; Iterator 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) { + 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 boolean addAll(int index, LIST KEY_GENERIC_TYPE c) - { - return false; + 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 GET_KEY(int index) - { - if (index >= size) throw new IndexOutOfBoundsException("Index (" + index + ") is not in lists size (" + size + ")"); + 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 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= 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 @@ -119,29 +175,33 @@ public class ARRAY_LIST KEY_GENERIC_TYPE extends ABSTRACT_LIST KEY_GENERIC_TYPE size--; return old; } - + @Override - public int size() - { + public int size() { return size; } @Override - public void clear() - { + public void clear() { #if TYPE_OBJECT for(int i = 0;i> 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); } } \ No newline at end of file diff --git a/src/main/resources/speiger/assets/collections/templates/lists/List.template b/src/main/resources/speiger/assets/collections/templates/lists/List.template index 582c382..bbfafc1 100644 --- a/src/main/resources/speiger/assets/collections/templates/lists/List.template +++ b/src/main/resources/speiger/assets/collections/templates/lists/List.template @@ -9,10 +9,10 @@ public interface LIST KEY_GENERIC_TYPE extends COLLECTION KEY_GENERIC_TYPE, List public boolean add(KEY_TYPE e); 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); @@ -27,7 +27,25 @@ public interface LIST KEY_GENERIC_TYPE extends COLLECTION KEY_GENERIC_TYPE, List public int indexOf(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 type); + +#else + public KEY_TYPE[] extractElements(int from, int to); + #endif @Override public LIST_ITERATOR KEY_GENERIC_TYPE listIterator(); diff --git a/src/main/resources/speiger/assets/collections/templates/utils/Arrays.template b/src/main/resources/speiger/assets/collections/templates/utils/Arrays.template index a3b4917..82bc146 100644 --- a/src/main/resources/speiger/assets/collections/templates/utils/Arrays.template +++ b/src/main/resources/speiger/assets/collections/templates/utils/Arrays.template @@ -1,8 +1,10 @@ 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 clz, int length) { + if(clz == Object.class) return (KEY_TYPE[])new Object[length]; + return (KEY_TYPE[]) java.lang.reflect.Array.newInstance(clz, length); + } #endif } \ No newline at end of file