From 274d37c4d62aa27b4c5e5c33c2ea039282be2573 Mon Sep 17 00:00:00 2001 From: Speiger Date: Thu, 29 Jun 2023 18:30:22 +0200 Subject: [PATCH] New Features. -Added: List.indexedIterator which allows you to create a iterator with a customized iteration indecies. Useful if you want to transform lists output. -Added: PriorityQueue.contains is now a function -Added: Iterators/Async Builders now support MapToPrimitiveType function on the object variant. So more processing can be done. (Will be expanded upon later versions) -Updated: SimpleCodeGenerator 1.3.0 is now being used which allows for iterative code support. --- Changelog.md | 6 +- build.gradle | 2 +- .../builder/PrimitiveCollectionsBuilder.java | 101 +- .../src/builder/modules/BaseModule.java | 3 + .../src/builder/modules/FunctionModule.java | 4 +- .../templates/collections/Iterable.template | 32 + .../templates/lists/AbstractList.template | 167 +++- .../collections/templates/lists/List.template | 23 + .../maps/abstracts/AbstractMap.template | 90 +- .../concurrent/ConcurrentOpenHashMap.template | 186 ++-- .../customHash/OpenCustomHashMap.template | 118 +-- .../maps/impl/hash/OpenHashMap.template | 118 +-- .../immutable/ImmutableOpenHashMap.template | 15 +- .../maps/impl/misc/ArrayMap.template | 124 +-- .../templates/maps/impl/misc/EnumMap.template | 120 +-- .../maps/impl/tree/AVLTreeMap.template | 136 +-- .../maps/impl/tree/RBTreeMap.template | 136 +-- .../templates/maps/interfaces/Map.template | 58 +- .../templates/queues/ArrayFIFOQueue.template | 925 +++++++++--------- .../queues/ArrayPriorityQueue.template | 885 ++++++++--------- .../queues/HeapPriorityQueue.template | 821 ++++++++-------- .../templates/queues/PriorityQueue.template | 7 + .../templates/utils/AsyncBuilder.template | 35 + .../templates/utils/Iterables.template | 91 ++ .../templates/utils/Iterators.template | 85 ++ .../templates/utils/Lists.template | 39 + .../templates/utils/PriorityQueues.template | 2 + .../templates/utils/maps/Maps.template | 56 +- .../ints/base/BaseIntIterableTest.java | 346 +++---- .../ints/base/BaseIntPriorityQueueTest.java | 312 +++--- .../collections/tests/PriorityQueueTest.java | 21 +- 31 files changed, 2792 insertions(+), 2272 deletions(-) diff --git a/Changelog.md b/Changelog.md index 1e32e89..9c8f69f 100644 --- a/Changelog.md +++ b/Changelog.md @@ -6,9 +6,13 @@ - Added: ToArray/pushTop functions to Stack.class. - Added: ComputeNonDefault functions which will contain the current behavior of the Compute function, while the Compute will be changed to be more java compliant! - Added: List.reversed, which returns a SubList that has all elements in reversed order and also inserts reversed. -- Added: Iterators.infinite as an option that will create a Infinite Iterator based on the inputted one. +- Added: Iterators.infinite as an option that will create a Infinite Iterator based on the inputed one. +- Added: List.indexedIterator which allows you to create a iterator with a customized iteration indecies. Useful if you want to transform lists output. +- Added: PriorityQueue.contains is now a function +- Added: Iterators/Async Builders now support MapToPrimitiveType function on the object variant. So more processing can be done. (Will be expanded upon later versions) - Fixed: SetValue wasn't working on forEach implementations. - Fixed: Compute functions now perform with primitives more java compliant. Meaning that getDefaultReturnValue function no longer is seen as null. +- Updated: SimpleCodeGenerator 1.3.0 is now being used which allows for iterative code support. ### Version 0.8.0 - Added: getFirst/getLast/removeFirst/removeLast to Lists diff --git a/build.gradle b/build.gradle index 6de12ed..5b9780e 100644 --- a/build.gradle +++ b/build.gradle @@ -46,7 +46,7 @@ configurations { dependencies { builderImplementation 'com.google.code.gson:gson:2.10' - builderImplementation 'de.speiger:Simple-Code-Generator:1.2.2' + builderImplementation 'de.speiger:Simple-Code-Generator:1.3.0' testImplementation 'junit:junit:4.12' testImplementation 'com.google.guava:guava-testlib:31.0.1-jre' diff --git a/src/builder/java/speiger/src/builder/PrimitiveCollectionsBuilder.java b/src/builder/java/speiger/src/builder/PrimitiveCollectionsBuilder.java index a750e89..41bbc82 100644 --- a/src/builder/java/speiger/src/builder/PrimitiveCollectionsBuilder.java +++ b/src/builder/java/speiger/src/builder/PrimitiveCollectionsBuilder.java @@ -45,23 +45,19 @@ public class PrimitiveCollectionsBuilder extends TemplateProcessor SettingsManager manager = new SettingsManager(); int flags; - public PrimitiveCollectionsBuilder() - { + public PrimitiveCollectionsBuilder() { this(false); } - public PrimitiveCollectionsBuilder(boolean silencedSuccess) - { + public PrimitiveCollectionsBuilder(boolean silencedSuccess) { super(silencedSuccess, Paths.get("src/builder/resources/speiger/assets/collections/templates/"), Paths.get("src/main/java/speiger/src/collections/"), Paths.get("src/builder/resources/speiger/assets/collections/")); } - public PrimitiveCollectionsBuilder(Path sourceFolder, Path outputFolder, Path dataFolder) - { + public PrimitiveCollectionsBuilder(Path sourceFolder, Path outputFolder, Path dataFolder) { this(false, sourceFolder, outputFolder, dataFolder); } - public PrimitiveCollectionsBuilder(boolean silencedSuccess, Path sourceFolder, Path outputFolder, Path dataFolder) - { + public PrimitiveCollectionsBuilder(boolean silencedSuccess, Path sourceFolder, Path outputFolder, Path dataFolder) { super(silencedSuccess, sourceFolder, outputFolder, dataFolder); } @@ -88,42 +84,24 @@ public class PrimitiveCollectionsBuilder extends TemplateProcessor } @Override - protected boolean isFileValid(Path fileName) - { - return true; - } + protected boolean isFileValid(Path fileName) { return true; } + @Override + protected boolean relativePackages() { return true; } + @Override + protected boolean debugUnusedMappers() { return false; } @Override - protected boolean relativePackages() - { - return true; - } - - @Override - protected boolean debugUnusedMappers() - { - return false; - } - - @Override - protected void afterFinish() - { - if((flags & SPECIAL) == 0 && getVersion() > 8) - { + protected void afterFinish() { + if((flags & SPECIAL) == 0 && getVersion() > 8) { Path basePath = Paths.get("src/main/java"); - try(BufferedWriter writer = Files.newBufferedWriter(basePath.resolve("module-info.java"))) - { + try(BufferedWriter writer = Files.newBufferedWriter(basePath.resolve("module-info.java"))) { writer.write(getModuleInfo(basePath)); } - catch(Exception e) - { - e.printStackTrace(); - } + catch(Exception e) { e.printStackTrace(); } } } - public List createModules() - { + public List createModules() { List modules = new ArrayList<>(); modules.add(JavaModule.INSTANCE); modules.add(FunctionModule.INSTANCE); @@ -139,38 +117,31 @@ public class PrimitiveCollectionsBuilder extends TemplateProcessor @Override - protected void init() - { + protected void init() { prepPackages(); //Init Modules here addModules(createModules()); finishPackages(); } - public void addModules(List modules) - { + public void addModules(List modules) { for(int i = 0,m=modules.size();i process) - { + public void createProcesses(String fileName, Consumer process) { List packages = getPackagesByRequirement(requirements.get(fileName)); - for(int i = 0,m=packages.size();i stream = Files.walk(getOutputFolder())) - { + try(Stream stream = Files.walk(getOutputFolder())) { stream.filter(Files::isDirectory) .filter(this::containsFiles) .map(basePath::relativize) @@ -206,8 +174,7 @@ public class PrimitiveCollectionsBuilder extends TemplateProcessor .map(this::sanitize) .forEach(T -> joiner.add("\texports "+T+";")); } - catch(Exception e) - { + catch(Exception e) { e.printStackTrace(); throw new RuntimeException(e); } @@ -218,34 +185,26 @@ public class PrimitiveCollectionsBuilder extends TemplateProcessor return builder.toString(); } - private String sanitize(String input) - { + private String sanitize(String input) { return input.replace("\\", ".").replace("/", "."); } - private boolean containsFiles(Path path) - { - try(Stream stream = Files.walk(path, 1)) - { + private boolean containsFiles(Path path) { + try(Stream stream = Files.walk(path, 1)) { return stream.filter(Files::isRegularFile).findFirst().isPresent(); } - catch(Exception e) - { - e.printStackTrace(); - } + catch(Exception e) { e.printStackTrace(); } return false; } - private int getVersion() - { + private int getVersion() { String version = System.getProperty("java.version"); if(version.startsWith("1.")) return Integer.parseInt(version.substring(2, 3)); int dot = version.indexOf("."); return Integer.parseInt(dot != -1 ? version.substring(0, dot) : version); } - public static void main(String...args) - { + public static void main(String...args) { try { Set flags = new HashSet<>(Arrays.asList(args)); diff --git a/src/builder/java/speiger/src/builder/modules/BaseModule.java b/src/builder/java/speiger/src/builder/modules/BaseModule.java index d13f72f..866b729 100644 --- a/src/builder/java/speiger/src/builder/modules/BaseModule.java +++ b/src/builder/java/speiger/src/builder/modules/BaseModule.java @@ -59,6 +59,9 @@ public abstract class BaseModule public Set getModuleKeys(ClassType keyType, ClassType valueType) { return Collections.emptySet(); } public boolean isModuleValid(ClassType keyType, ClassType valueType) { return true; } + public ClassType keyType() { return keyType; } + public ClassType valueType() { return valueType; } + protected boolean isModuleEnabled() { return manager == null || manager.isModuleEnabled(this, keyType, valueType); } diff --git a/src/builder/java/speiger/src/builder/modules/FunctionModule.java b/src/builder/java/speiger/src/builder/modules/FunctionModule.java index 1ab81fc..999f457 100644 --- a/src/builder/java/speiger/src/builder/modules/FunctionModule.java +++ b/src/builder/java/speiger/src/builder/modules/FunctionModule.java @@ -54,8 +54,8 @@ public class FunctionModule extends BaseModule protected void loadFunctions() { addSimpleMapper("APPLY", keyType.getApply(valueType)); - addSimpleMapper("SUPPLY_GET", keyType.isObject() ? "get" : "getAs"+keyType.getCustomJDKType().getNonFileType()); - addSimpleMapper("VALUE_SUPPLY_GET", valueType.isObject() ? "get" : "getAs"+valueType.getCustomJDKType().getNonFileType()); + addSimpleMapper("SUPPLY_GET", keyType.isObject() ? "get" : "getAs"+keyType.getNonFileType()); + addSimpleMapper("VALUE_SUPPLY_GET", valueType.isObject() ? "get" : "getAs"+valueType.getNonFileType()); } @Override diff --git a/src/builder/resources/speiger/assets/collections/templates/collections/Iterable.template b/src/builder/resources/speiger/assets/collections/templates/collections/Iterable.template index e5ccd70..1b48b6d 100644 --- a/src/builder/resources/speiger/assets/collections/templates/collections/Iterable.template +++ b/src/builder/resources/speiger/assets/collections/templates/collections/Iterable.template @@ -16,6 +16,19 @@ import java.util.function.BiFunction; import java.util.function.IntFunction; import java.util.Comparator; +#if BOOLEAN_COLLECTION_MODULE +import speiger.src.collections.booleans.collections.BooleanIterable; +#endif +#iterate +#argument OUTPUT_ITERABLE ByteIterable ShortIterable IntIterable LongIterable FloatIterable DoubleIterable +#argument MAPPER ToByteFunction ToShortFunction ToIntFunction ToLongFunction ToFloatFunction ToDoubleFunction +#argument PACKAGE bytes shorts ints longs floats doubles +#argument FILTER_TYPE BYTE_COLLECTION_MODULE SHORT_COLLECTION_MODULE INT_COLLECTION_MODULE LONG_COLLECTION_MODULE FLOAT_COLLECTION_MODULE DOUBLE_COLLECTION_MODULE +#if FILTER_TYPE +import speiger.src.collections.objects.functions.function.MAPPER; +import speiger.src.collections.PACKAGE.collections.OUTPUT_ITERABLE; +#endif +#enditerate #endif import speiger.src.collections.PACKAGE.functions.function.TO_OBJECT_FUNCTION; import speiger.src.collections.ints.functions.consumer.BI_FROM_INT_CONSUMER; @@ -165,6 +178,25 @@ public interface ITERABLE KEY_GENERIC_TYPE extends Iterable return ITERABLES.map(this, mapper); } +#if TYPE_OBJECT +#iterate +#argument OUTPUT_ITERABLE BooleanIterable ByteIterable ShortIterable IntIterable LongIterable FloatIterable DoubleIterable +#argument MAPPER Predicate ToByteFunction ToShortFunction ToIntFunction ToLongFunction ToFloatFunction ToDoubleFunction +#argument DATA_TYPE Boolean Byte Short Int Long Float Double +#argument FILTER_TYPE BOOLEAN_COLLECTION_MODULE BYTE_COLLECTION_MODULE SHORT_COLLECTION_MODULE INT_COLLECTION_MODULE LONG_COLLECTION_MODULE FLOAT_COLLECTION_MODULE DOUBLE_COLLECTION_MODULE +#if FILTER_TYPE + /** + * A Helper function to reduce the usage of Streams and allows to convert a Iterable to something else. + * @param mapper the mapping function + * @return a new Iterable that returns the desired result + */ + default OUTPUT_ITERABLE mapToDATA_TYPE(MAPPER mapper) { + return ITERABLES.mapToDATA_TYPE(this, mapper); + } + +#endif +#enditerate +#endif /** * A Helper function to reduce the usage of Streams and allows to convert a Iterable to something else. * @param mapper the flatMapping function diff --git a/src/builder/resources/speiger/assets/collections/templates/lists/AbstractList.template b/src/builder/resources/speiger/assets/collections/templates/lists/AbstractList.template index 6276055..54a1143 100644 --- a/src/builder/resources/speiger/assets/collections/templates/lists/AbstractList.template +++ b/src/builder/resources/speiger/assets/collections/templates/lists/AbstractList.template @@ -12,6 +12,9 @@ import speiger.src.collections.PACKAGE.collections.ABSTRACT_COLLECTION; import speiger.src.collections.PACKAGE.collections.COLLECTION; import speiger.src.collections.PACKAGE.collections.ITERATOR; import speiger.src.collections.PACKAGE.collections.SPLIT_ITERATOR; +#if INT_LIST_MODULE && !TYPE_INT +import speiger.src.collections.ints.lists.IntList; +#endif import speiger.src.collections.PACKAGE.utils.SPLIT_ITERATORS; import speiger.src.collections.utils.SanityChecks; @@ -236,13 +239,25 @@ public abstract class ABSTRACT_LIST KEY_GENERIC_TYPE extends ABSTRACT_COLLECTION public LIST_ITERATOR KEY_GENERIC_TYPE listIterator() { return listIterator(0); } - + @Override public LIST_ITERATOR KEY_GENERIC_TYPE listIterator(int index) { if(index < 0 || index > size()) throw new IndexOutOfBoundsException(); return new LIST_ITER(index); } + @Override + public LIST_ITERATOR KEY_GENERIC_TYPE indexedIterator(int...indecies) { + return new IndexedIterator(indecies); + } + +#if INT_LIST_MODULE + @Override + public LIST_ITERATOR KEY_GENERIC_TYPE indexedIterator(IntList indecies) { + return new ListIndexedIterator(indecies); + } + +#endif @Override public void size(int size) { while(size > size()) add(EMPTY_KEY_VALUE); @@ -628,7 +643,155 @@ public abstract class ABSTRACT_LIST KEY_GENERIC_TYPE extends ABSTRACT_COLLECTION } } } + +#if INT_LIST_MODULE + private class ListIndexedIterator implements LIST_ITERATOR KEY_GENERIC_TYPE { + IntList indecies; + int index; + int lastReturned = -1; + ListIndexedIterator(IntList indecies) { + this.indecies = indecies; + } + + @Override + public boolean hasNext() { + return index < indecies.size(); + } + + @Override + public KEY_TYPE NEXT() { + if(!hasNext()) throw new NoSuchElementException(); + int i = index++; + return GET_KEY((lastReturned = indecies.getInt(i))); + } + + @Override + public boolean hasPrevious() { + return index > 0; + } + + @Override + public KEY_TYPE PREVIOUS() { + if(!hasPrevious()) throw new NoSuchElementException(); + index--; + return GET_KEY((lastReturned = indecies.getInt(index))); + } + + @Override + public int nextIndex() { + return index; + } + + @Override + public int previousIndex() { + return index-1; + } + + @Override + public void remove() { throw new UnsupportedOperationException(); } + @Override + public void add(KEY_TYPE e) { throw new UnsupportedOperationException(); } + + @Override + public void set(KEY_TYPE e) { + if(lastReturned == -1) throw new IllegalStateException(); + ABSTRACT_LIST.this.set(lastReturned, e); + } + + @Override + public int skip(int amount) { + if(amount < 0) throw new IllegalStateException("Negative Numbers are not allowed"); + int steps = Math.min(amount, indecies.size() - index); + index += steps; + if(steps > 0) lastReturned = Math.min(index-1, indecies.size()-1); + return steps; + } + + @Override + public int back(int amount) { + if(amount < 0) throw new IllegalStateException("Negative Numbers are not allowed"); + int steps = Math.min(amount, index); + index -= steps; + if(steps > 0) lastReturned = Math.max(index, 0); + return steps; + } + } + +#endif + private class IndexedIterator implements LIST_ITERATOR KEY_GENERIC_TYPE { + int[] indecies; + int index; + int lastReturned = -1; + + IndexedIterator(int[] indecies) { + this.indecies = indecies; + } + + @Override + public boolean hasNext() { + return index < indecies.length; + } + + @Override + public KEY_TYPE NEXT() { + if(!hasNext()) throw new NoSuchElementException(); + int i = index++; + return GET_KEY((lastReturned = indecies[i])); + } + + @Override + public boolean hasPrevious() { + return index > 0; + } + + @Override + public KEY_TYPE PREVIOUS() { + if(!hasPrevious()) throw new NoSuchElementException(); + index--; + return GET_KEY((lastReturned = indecies[index])); + } + + @Override + public int nextIndex() { + return index; + } + + @Override + public int previousIndex() { + return index-1; + } + + @Override + public void remove() { throw new UnsupportedOperationException(); } + @Override + public void add(KEY_TYPE e) { throw new UnsupportedOperationException(); } + + @Override + public void set(KEY_TYPE e) { + if(lastReturned == -1) throw new IllegalStateException(); + ABSTRACT_LIST.this.set(lastReturned, e); + } + + @Override + public int skip(int amount) { + if(amount < 0) throw new IllegalStateException("Negative Numbers are not allowed"); + int steps = Math.min(amount, indecies.length - index); + index += steps; + if(steps > 0) lastReturned = Math.min(index-1, indecies.length-1); + return steps; + } + + @Override + public int back(int amount) { + if(amount < 0) throw new IllegalStateException("Negative Numbers are not allowed"); + int steps = Math.min(amount, index); + index -= steps; + if(steps > 0) lastReturned = Math.max(index, 0); + return steps; + } + } + private class LIST_ITER implements LIST_ITERATOR KEY_GENERIC_TYPE { int index; int lastReturned = -1; @@ -706,7 +869,7 @@ public abstract class ABSTRACT_LIST KEY_GENERIC_TYPE extends ABSTRACT_COLLECTION if(amount < 0) throw new IllegalStateException("Negative Numbers are not allowed"); int steps = Math.min(amount, index); index -= steps; - if(steps > 0) lastReturned = Math.min(index, size()-1); + if(steps > 0) lastReturned = Math.max(index, 0); return steps; } } diff --git a/src/builder/resources/speiger/assets/collections/templates/lists/List.template b/src/builder/resources/speiger/assets/collections/templates/lists/List.template index 8835013..3443086 100644 --- a/src/builder/resources/speiger/assets/collections/templates/lists/List.template +++ b/src/builder/resources/speiger/assets/collections/templates/lists/List.template @@ -24,6 +24,9 @@ import speiger.src.collections.PACKAGE.utils.ARRAYS; #if LISTS_FEATURE import speiger.src.collections.PACKAGE.utils.LISTS; #endif +#if INT_LIST_MODULE && !TYPE_INT +import speiger.src.collections.ints.lists.IntList; +#endif import speiger.src.collections.PACKAGE.utils.SPLIT_ITERATORS; #if TYPE_BYTE || TYPE_SHORT || TYPE_CHAR || TYPE_FLOAT import speiger.src.collections.utils.SanityChecks; @@ -425,6 +428,26 @@ public interface LIST KEY_GENERIC_TYPE extends COLLECTION KEY_GENERIC_TYPE, List @Override public LIST_ITERATOR KEY_GENERIC_TYPE listIterator(int index); + /** + * Creates a Iterator that follows the indecies provided.
+ * For example if the Lists Contents is:
-1, 0 1
and the indecies are:
0, 1, 2, 2, 1, 0
+ * then the iterator will return the following values:
-1, 0, 1, 1, 0, -1 + * @param indecies that should be used for the iteration. + * @return a custom indexed iterator + */ + public LIST_ITERATOR KEY_GENERIC_TYPE indexedIterator(int...indecies); + +#if INT_LIST_MODULE + /** + * Creates a Iterator that follows the indecies provided.
+ * For example if the Lists Contents is:
-1, 0 1
and the indecies are:
0, 1, 2, 2, 1, 0
+ * then the iterator will return the following values:
-1, 0, 1, 1, 0, -1 + * @param indecies that should be used for the iteration. + * @return a custom indexed iterator + */ + public LIST_ITERATOR KEY_GENERIC_TYPE indexedIterator(IntList indecies); + +#endif /** * A Type-Specific List of subList * @see java.util.List#subList(int, int) diff --git a/src/builder/resources/speiger/assets/collections/templates/maps/abstracts/AbstractMap.template b/src/builder/resources/speiger/assets/collections/templates/maps/abstracts/AbstractMap.template index fe65662..29e0b4d 100644 --- a/src/builder/resources/speiger/assets/collections/templates/maps/abstracts/AbstractMap.template +++ b/src/builder/resources/speiger/assets/collections/templates/maps/abstracts/AbstractMap.template @@ -218,22 +218,6 @@ public abstract class ABSTRACT_MAP KEY_VALUE_GENERIC_TYPE extends AbstractMap= 0 ? apparentLength : array.length + apparentLength; - } - - @Override - public void clear() { - if(first != last) { -#if TYPE_OBJECT - Arrays.fill(array, null); -#endif - first = last = 0; - } - else if(first != 0) { - first = last = 0; - } - } - - @Override - public void enqueue(KEY_TYPE e) { - array[last++] = e; - if(last == array.length) last = 0; - if(last == first) expand(); - } - - @Override - public void enqueueFirst(KEY_TYPE e) { - if(first == 0) first = array.length; - array[--first] = e; - if(first == last) expand(); - } - - @Override - public KEY_TYPE dequeue() { - if(first == last) throw new NoSuchElementException(); - KEY_TYPE data = array[first]; -#if TYPE_OBJECT - array[first] = null; -#endif - if(++first == array.length) first = 0; - reduce(); - return data; - } - - @Override - public KEY_TYPE dequeueLast() { - if(first == last) throw new NoSuchElementException(); - if(last == 0) last = array.length; - KEY_TYPE data = array[--last]; -#if TYPE_OBJECT - array[last] = null; -#endif - reduce(); - return data; - } - - @Override - public KEY_TYPE peek(int index) { - if(first == last || index < 0 || index >= size()) throw new NoSuchElementException(); - index += first; - return index >= array.length ? array[index-array.length] : array[index]; - } - - @Override - public boolean removeFirst(KEY_TYPE e) { - if(first == last) return false; - for(int i = 0,m=size();i=0;i--) { - int index = (first + i) % array.length; - if(e == array[index]) - return removeIndex(index); - } - return false; - } - - protected boolean removeIndex(int index) { - if(first >= last ? index < first && index > last : index < first || index > last) return false; - if(index == first) { -#if TYPE_OBJECT - array[first] = null; -#endif - first++; - } - else if(index == last) { - last--; -#if TYPE_OBJECT - array[last] = null; -#endif - } - else if(index > last) { - System.arraycopy(array, first, array, first+1, (index - first)); -#if TYPE_OBJECT - array[first] = null; -#endif - first = ++first % array.length; - } - else if(index < first) { - System.arraycopy(array, index+1, array, index, (last - index) - 1); -#if TYPE_OBJECT - array[last] = null; -#endif - if(--last < 0) last += array.length; - } - else { - if(index - first < last - index) { - System.arraycopy(array, first, array, first+1, (index - first)); -#if TYPE_OBJECT - array[first] = null; -#endif - first = ++first % array.length; - } - else { - System.arraycopy(array, index+1, array, index, (last - index) - 1); -#if TYPE_OBJECT - array[last] = null; -#endif - if(--last < 0) last += array.length; - } - } - reduce(); - return true; - } - - @Override - public void onChanged() {} - - @Override - public ARRAY_FIFO_QUEUE KEY_GENERIC_TYPE copy() { - ARRAY_FIFO_QUEUE KEY_GENERIC_TYPE queue = new ARRAY_FIFO_QUEUEBRACES(); - queue.first = first; - queue.last = last; - queue.minCapacity = minCapacity; - queue.array = Arrays.copyOf(array, array.length); - return queue; - } - - @Override - public COMPARATOR KEY_SUPER_GENERIC_TYPE comparator() { return null; } - - @Override - public void forEach(CONSUMER KEY_SUPER_GENERIC_TYPE action) { - Objects.requireNonNull(action); - if(first == last) return; - for(int i = 0,m=size();i void forEach(E input, BI_FROM_OBJECT_CONSUMER KSK_GENERIC_TYPE action) { - Objects.requireNonNull(action); - if(first == last) return; - for(int i = 0,m=size();i KEY_SPECIAL_TYPE reduce(KEY_SPECIAL_TYPE identity, BiFunction operator) { - Objects.requireNonNull(operator); - KEY_SPECIAL_TYPE state = identity; - for(int i = 0,m=size();i= array.length) return false; - KEY_TYPE[] newArray = NEW_KEY_ARRAY(newSize); - if(first <= last) System.arraycopy(array, first, newArray, 0, last - first); - else { - System.arraycopy(array, first, newArray, 0, array.length - first); - System.arraycopy(array, 0, newArray, array.length - first, last); - } - first = 0; - last = size(); - array = newArray; - return true; - } - - /** - * Trims the collection down to the requested size and clears all elements while doing so - * @param size the amount of elements that should be allowed - * @note this will enforce minimum size of the collection itself - */ - @Override - public void clearAndTrim(int size) { - int newSize = Math.max(minCapacity, size); - if(array.length <= newSize) { - clear(); - return; - } - first = last = 0; - array = NEW_KEY_ARRAY(newSize); - } - - @Override - public GENERIC_SPECIAL_KEY_BRACES KEY_SPECIAL_TYPE[] TO_ARRAY(KEY_SPECIAL_TYPE[] input) { - if(input == null || input.length < size()) input = NEW_SPECIAL_KEY_ARRAY(size()); - if (first <= last) System.arraycopy(array, first, input, 0, last - first); - else { - System.arraycopy(array, first, input, 0, array.length - first); - System.arraycopy(array, 0, input, array.length - first, last); - } - return input; - } - - protected void reduce() { - final int size = size(); - if (array.length > minCapacity && size <= array.length / 4) resize(size, Math.max(array.length / 2, minCapacity)); - } - - protected void expand() { - resize(array.length, (int)Math.min(MAX_ARRAY_SIZE, 2L * array.length)); - } - - protected final void resize(int oldSize, int newSize) { - KEY_TYPE[] newArray = NEW_KEY_ARRAY(newSize); - if(first >= last) { - if(oldSize != 0) - { - System.arraycopy(array, first, newArray, 0, array.length - first); - System.arraycopy(array, 0, newArray, array.length - first, last); - } - } - else System.arraycopy(array, first, newArray, 0, last-first); - first = 0; - last = oldSize; - array = newArray; - } - - private class Iter implements ITERATOR KEY_GENERIC_TYPE - { - int index = first; - @Override - public boolean hasNext() - { - return index != last; - } - - @Override - public KEY_TYPE NEXT() { - if(!hasNext()) throw new NoSuchElementException(); - KEY_TYPE value = array[index]; - removeIndex(index); - index = ++index % array.length; - return value; - } - } +package speiger.src.collections.PACKAGE.queues; + +import java.util.Arrays; +#if TYPE_OBJECT +import java.util.Comparator; +import java.util.function.Consumer; +import java.util.function.BiFunction; +#endif +import java.util.Objects; +import java.util.NoSuchElementException; +#if JDK_FUNCTION +import java.util.function.PREDICATE; +#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.ints.functions.consumer.BI_FROM_INT_CONSUMER; +import speiger.src.collections.objects.functions.consumer.BI_FROM_OBJECT_CONSUMER; +#if !JDK_FUNCTION +import speiger.src.collections.PACKAGE.functions.function.PREDICATE; +#endif +import speiger.src.collections.PACKAGE.functions.function.UNARY_OPERATOR; +import speiger.src.collections.utils.ITrimmable; + +/** + * A Simple First In First Out Priority Queue that is a Good Replacement for a linked list (or ArrayDequeue) + * Its specific implementation uses a backing array that grows and shrinks as it is needed. + * @Type(T) + */ +public class ARRAY_FIFO_QUEUE KEY_GENERIC_TYPE extends ABSTRACT_PRIORITY_QUEUE KEY_GENERIC_TYPE implements PRIORITY_DEQUEUE KEY_GENERIC_TYPE, ITrimmable +{ + /** Max Possible ArraySize without the JVM Crashing */ + private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8; + /** The Minimum Capacity that is allowed */ + public static final int MIN_CAPACITY = 4; + /** The Backing array */ + protected transient KEY_TYPE[] array; + /** The First Index pointer */ + protected int first; + /** The Last Index pointer */ + protected int last; + /** The Minimum Capacity of the Queue **/ + protected int minCapacity; + + /** + * Constructor using a initial array + * @param values the Array that should be used + */ + public ARRAY_FIFO_QUEUE(KEY_TYPE[] values) { + this(values, 0, values.length); + } + + /** + * Constructor using a initial array + * @param values the Array that should be used + * @param size the amount of elements that are in the initial array + * @throws IllegalStateException if values is smaller then size + */ + public ARRAY_FIFO_QUEUE(KEY_TYPE[] values, int size) { + this(values, 0, size); + } + + /** + * Constructor using a initial array + * @param values the Array that should be used + * @param offset where to begin in the initial array + * @param size the amount of elements that are in the initial array + * @throws IllegalStateException if values is smaller then size + */ + public ARRAY_FIFO_QUEUE(KEY_TYPE[] values, int offset, int size) { + if (values.length < size) throw new IllegalArgumentException("Initial array (" + values.length + ") is smaller then the expected size (" + size + ")"); + if(values.length <= 0) values = NEW_KEY_ARRAY(MIN_CAPACITY); + else if(values.length < MIN_CAPACITY) values = Arrays.copyOf(values, MIN_CAPACITY); + minCapacity = MIN_CAPACITY; + array = values; + first = offset; + last = (offset + size) % array.length; + if(array.length == size) expand(); + } + + /** + * Constructor with a Min Capacity + * @param capacity the initial capacity of the backing array + * @throws IllegalStateException if the initial size is smaller 0 + */ + public ARRAY_FIFO_QUEUE(int capacity) { + if (capacity < 0) throw new IllegalArgumentException("Initial capacity (" + capacity + ") is negative"); + array = NEW_KEY_ARRAY(Math.max(MIN_CAPACITY, capacity+1)); + minCapacity = array.length; + } + + /** + * Default Construtor + */ + public ARRAY_FIFO_QUEUE() { + this(MIN_CAPACITY); + } + + @Override + public ITERATOR KEY_GENERIC_TYPE iterator() { + return new Iter(); + } + + @Override + public int size() { + final int apparentLength = last - first; + return apparentLength >= 0 ? apparentLength : array.length + apparentLength; + } + + @Override + public void clear() { + if(first != last) { +#if TYPE_OBJECT + Arrays.fill(array, null); +#endif + first = last = 0; + } + else if(first != 0) { + first = last = 0; + } + } + + @Override + public void enqueue(KEY_TYPE e) { + array[last++] = e; + if(last == array.length) last = 0; + if(last == first) expand(); + } + + @Override + public void enqueueFirst(KEY_TYPE e) { + if(first == 0) first = array.length; + array[--first] = e; + if(first == last) expand(); + } + + @Override + public KEY_TYPE dequeue() { + if(first == last) throw new NoSuchElementException(); + KEY_TYPE data = array[first]; +#if TYPE_OBJECT + array[first] = null; +#endif + if(++first == array.length) first = 0; + reduce(); + return data; + } + + @Override + public KEY_TYPE dequeueLast() { + if(first == last) throw new NoSuchElementException(); + if(last == 0) last = array.length; + KEY_TYPE data = array[--last]; +#if TYPE_OBJECT + array[last] = null; +#endif + reduce(); + return data; + } + + @Override + public KEY_TYPE peek(int index) { + if(first == last || index < 0 || index >= size()) throw new NoSuchElementException(); + index += first; + return index >= array.length ? array[index-array.length] : array[index]; + } + + @Override + public boolean contains(KEY_TYPE e) { + if(first == last) return false; + for(int i = 0,m=size();i=0;i--) { + int index = (first + i) % array.length; + if(e == array[index]) + return removeIndex(index); + } + return false; + } + + protected boolean removeIndex(int index) { + if(first >= last ? index < first && index > last : index < first || index > last) return false; + if(index == first) { +#if TYPE_OBJECT + array[first] = null; +#endif + first++; + } + else if(index == last) { + last--; +#if TYPE_OBJECT + array[last] = null; +#endif + } + else if(index > last) { + System.arraycopy(array, first, array, first+1, (index - first)); +#if TYPE_OBJECT + array[first] = null; +#endif + first = ++first % array.length; + } + else if(index < first) { + System.arraycopy(array, index+1, array, index, (last - index) - 1); +#if TYPE_OBJECT + array[last] = null; +#endif + if(--last < 0) last += array.length; + } + else { + if(index - first < last - index) { + System.arraycopy(array, first, array, first+1, (index - first)); +#if TYPE_OBJECT + array[first] = null; +#endif + first = ++first % array.length; + } + else { + System.arraycopy(array, index+1, array, index, (last - index) - 1); +#if TYPE_OBJECT + array[last] = null; +#endif + if(--last < 0) last += array.length; + } + } + reduce(); + return true; + } + + @Override + public void onChanged() {} + + @Override + public ARRAY_FIFO_QUEUE KEY_GENERIC_TYPE copy() { + ARRAY_FIFO_QUEUE KEY_GENERIC_TYPE queue = new ARRAY_FIFO_QUEUEBRACES(); + queue.first = first; + queue.last = last; + queue.minCapacity = minCapacity; + queue.array = Arrays.copyOf(array, array.length); + return queue; + } + + @Override + public COMPARATOR KEY_SUPER_GENERIC_TYPE comparator() { return null; } + + @Override + public void forEach(CONSUMER KEY_SUPER_GENERIC_TYPE action) { + Objects.requireNonNull(action); + if(first == last) return; + for(int i = 0,m=size();i void forEach(E input, BI_FROM_OBJECT_CONSUMER KSK_GENERIC_TYPE action) { + Objects.requireNonNull(action); + if(first == last) return; + for(int i = 0,m=size();i KEY_SPECIAL_TYPE reduce(KEY_SPECIAL_TYPE identity, BiFunction operator) { + Objects.requireNonNull(operator); + KEY_SPECIAL_TYPE state = identity; + for(int i = 0,m=size();i= array.length) return false; + KEY_TYPE[] newArray = NEW_KEY_ARRAY(newSize); + if(first <= last) System.arraycopy(array, first, newArray, 0, last - first); + else { + System.arraycopy(array, first, newArray, 0, array.length - first); + System.arraycopy(array, 0, newArray, array.length - first, last); + } + first = 0; + last = size(); + array = newArray; + return true; + } + + /** + * Trims the collection down to the requested size and clears all elements while doing so + * @param size the amount of elements that should be allowed + * @note this will enforce minimum size of the collection itself + */ + @Override + public void clearAndTrim(int size) { + int newSize = Math.max(minCapacity, size); + if(array.length <= newSize) { + clear(); + return; + } + first = last = 0; + array = NEW_KEY_ARRAY(newSize); + } + + @Override + public GENERIC_SPECIAL_KEY_BRACES KEY_SPECIAL_TYPE[] TO_ARRAY(KEY_SPECIAL_TYPE[] input) { + if(input == null || input.length < size()) input = NEW_SPECIAL_KEY_ARRAY(size()); + if (first <= last) System.arraycopy(array, first, input, 0, last - first); + else { + System.arraycopy(array, first, input, 0, array.length - first); + System.arraycopy(array, 0, input, array.length - first, last); + } + return input; + } + + protected void reduce() { + final int size = size(); + if (array.length > minCapacity && size <= array.length / 4) resize(size, Math.max(array.length / 2, minCapacity)); + } + + protected void expand() { + resize(array.length, (int)Math.min(MAX_ARRAY_SIZE, 2L * array.length)); + } + + protected final void resize(int oldSize, int newSize) { + KEY_TYPE[] newArray = NEW_KEY_ARRAY(newSize); + if(first >= last) { + if(oldSize != 0) + { + System.arraycopy(array, first, newArray, 0, array.length - first); + System.arraycopy(array, 0, newArray, array.length - first, last); + } + } + else System.arraycopy(array, first, newArray, 0, last-first); + first = 0; + last = oldSize; + array = newArray; + } + + private class Iter implements ITERATOR KEY_GENERIC_TYPE + { + int index = first; + @Override + public boolean hasNext() + { + return index != last; + } + + @Override + public KEY_TYPE NEXT() { + if(!hasNext()) throw new NoSuchElementException(); + KEY_TYPE value = array[index]; + removeIndex(index); + index = ++index % array.length; + return value; + } + } } \ No newline at end of file diff --git a/src/builder/resources/speiger/assets/collections/templates/queues/ArrayPriorityQueue.template b/src/builder/resources/speiger/assets/collections/templates/queues/ArrayPriorityQueue.template index c4e9047..9a7a0c6 100644 --- a/src/builder/resources/speiger/assets/collections/templates/queues/ArrayPriorityQueue.template +++ b/src/builder/resources/speiger/assets/collections/templates/queues/ArrayPriorityQueue.template @@ -1,440 +1,447 @@ -package speiger.src.collections.PACKAGE.queues; - -import java.util.Arrays; -import java.util.NoSuchElementException; -#if TYPE_OBJECT -import java.util.Comparator; -import java.util.function.Consumer; -import java.util.function.BiFunction; -#endif -import java.util.Objects; -#if JDK_FUNCTION -import java.util.function.PREDICATE; -#endif - -import speiger.src.collections.PACKAGE.collections.COLLECTION; -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.ints.functions.consumer.BI_FROM_INT_CONSUMER; -import speiger.src.collections.objects.functions.consumer.BI_FROM_OBJECT_CONSUMER; -#if !JDK_FUNCTION -import speiger.src.collections.PACKAGE.functions.function.PREDICATE; -#endif -import speiger.src.collections.PACKAGE.functions.function.UNARY_OPERATOR; -import speiger.src.collections.PACKAGE.utils.ARRAYS; -import speiger.src.collections.utils.SanityChecks; - -/** - * A Array Priority Queue, this is a very unoptimized implementation of the PriorityQueue for very specific usecases. - * It allows for duplicated entries and works like {@link java.util.List#indexOf(Object)} search. - * It is highly suggested to use HeapPriorityQueue otherwise, unless you know why you need this specific implementation - * @Type(T) - */ -public class ARRAY_PRIORITY_QUEUE KEY_GENERIC_TYPE extends ABSTRACT_PRIORITY_QUEUE KEY_GENERIC_TYPE -{ - /** The Backing Array */ - protected transient KEY_TYPE[] array = EMPTY_KEY_ARRAY; - /** The Amount of elements stored within the array */ - protected int size; - /** The Last known first index pointer */ - protected int firstIndex = -1; - /** The Sorter of the Array */ - protected COMPARATOR KEY_SUPER_GENERIC_TYPE comparator; - - /** - * Default Constructor - */ - public ARRAY_PRIORITY_QUEUE() { - this(0, null); - } - - /** - * Constructor using custom sorter - * @param comp Comparator to sort the Array. Can be null - */ - public ARRAY_PRIORITY_QUEUE(COMPARATOR KEY_SUPER_GENERIC_TYPE comp) { - this(0, comp); - } - - /** - * Constructor with a Min Capacity - * @param size the initial capacity of the backing array - * @throws IllegalStateException if the initial size is smaller 0 - */ - public ARRAY_PRIORITY_QUEUE(int size) { - this(size, null); - } - - /** - * Constructor with a Min Capacity and custom Sorter - * @param size the initial capacity of the backing array - * @param comp Comparator to sort the Array. Can be null - * @throws IllegalStateException if the initial size is smaller 0 - */ - public ARRAY_PRIORITY_QUEUE(int size, COMPARATOR KEY_SUPER_GENERIC_TYPE comp) { - if(size < 0) throw new IllegalAccessError("Size has to be 0 or positive"); - if(size > 0) array = NEW_KEY_ARRAY(size); - comparator = comp; - } - - /** - * Constructor using a initial array - * @param array the Array that should be used - */ - public ARRAY_PRIORITY_QUEUE(KEY_TYPE[] array) { - this(array, array.length); - } - - /** - * Constructor using a initial array - * @param array the Array that should be used - * @param size the amount of elements found within the array - * @throws NegativeArraySizeException if size is smaller then 0 - */ - public ARRAY_PRIORITY_QUEUE(KEY_TYPE[] array, int size) { - this.array = Arrays.copyOf(array, size); - this.size = size; - } - - /** - * Constructor using a initial array and a custom sorter - * @param array the Array that should be used - * @param comp Comparator to sort the Array. Can be null - */ - public ARRAY_PRIORITY_QUEUE(KEY_TYPE[] array, COMPARATOR KEY_SUPER_GENERIC_TYPE comp) { - this(array, array.length, comp); - } - - /** - * Constructor using a initial array and a custom sorter - * @param array the Array that should be used - * @param size the amount of elements found within the array - * @param comp Comparator to sort the Array. Can be null - * @throws NegativeArraySizeException if size is smaller then 0 - */ - public ARRAY_PRIORITY_QUEUE(KEY_TYPE[] array, int size, COMPARATOR KEY_SUPER_GENERIC_TYPE comp) { - this.array = Arrays.copyOf(array, size); - this.size = size; - this.comparator = comp; - } - - /** - * Constructor using a Collection - * @param c the Collection that should be used - */ - public ARRAY_PRIORITY_QUEUE(COLLECTION KEY_GENERIC_TYPE c) { - array = CAST_KEY_ARRAY c.TO_ARRAY(); - size = c.size(); - } - - /** - * Constructor using a Collection and a custom sorter - * @param c the Collection that should be used - * @param comp Comparator to sort the Array. Can be null - */ - public ARRAY_PRIORITY_QUEUE(COLLECTION KEY_GENERIC_TYPE c, COMPARATOR KEY_SUPER_GENERIC_TYPE comp) { - array = CAST_KEY_ARRAY c.TO_ARRAY(); - size = c.size(); - comparator = comp; - } - - /** - * Wrapping method to help serialization - * @param array the array that should be used - * @Type(T) - * @return a ArrayPriorityQueue containing the original input array - */ - public static GENERIC_KEY_BRACES ARRAY_PRIORITY_QUEUE KEY_GENERIC_TYPE wrap(KEY_TYPE[] array) { - return wrap(array, array.length); - } - - /** - * Wrapping method to help serialization - * @param array the array that should be used - * @param size the amount of elements within the array - * @Type(T) - * @return a ArrayPriorityQueue containing the original input array - */ - public static GENERIC_KEY_BRACES ARRAY_PRIORITY_QUEUE KEY_GENERIC_TYPE wrap(KEY_TYPE[] array, int size) { - ARRAY_PRIORITY_QUEUE KEY_GENERIC_TYPE queue = new ARRAY_PRIORITY_QUEUEBRACES(); - queue.array = array; - queue.size = size; - return queue; - } - - /** - * Wrapping method to help serialization, using a custom sorter - * @param array the array that should be used - * @param comp Comparator to sort the Array. Can be null - * @Type(T) - * @return a ArrayPriorityQueue containing the original input array - */ - public static GENERIC_KEY_BRACES ARRAY_PRIORITY_QUEUE KEY_GENERIC_TYPE wrap(KEY_TYPE[] array, COMPARATOR KEY_SUPER_GENERIC_TYPE comp) { - return wrap(array, array.length, comp); - } - - /** - * Wrapping method to help serialization, using a custom sorter - * @param array the array that should be used - * @param size the amount of elements within the array - * @param comp Comparator to sort the Array. Can be null - * @Type(T) - * @return a ArrayPriorityQueue containing the original input array - */ - public static GENERIC_KEY_BRACES ARRAY_PRIORITY_QUEUE KEY_GENERIC_TYPE wrap(KEY_TYPE[] array, int size, COMPARATOR KEY_SUPER_GENERIC_TYPE comp) { - ARRAY_PRIORITY_QUEUE KEY_GENERIC_TYPE queue = new ARRAY_PRIORITY_QUEUEBRACES(comp); - queue.array = array; - queue.size = size; - return queue; - } - - @Override - public void enqueue(KEY_TYPE e) { - if(size == array.length) array = Arrays.copyOf(array, (int)Math.max(Math.min((long)array.length + (long)(array.length >> 1), (long)SanityChecks.MAX_ARRAY_SIZE), size+1)); - if(firstIndex != -1){ - int compare = comparator == null ? COMPAREABLE_TO_KEY(e, array[firstIndex]) : comparator.compare(e, array[firstIndex]); - if(compare < 0) firstIndex = size; - else if(compare > 0) firstIndex = -1; - } - array[size++] = e; - } - - @Override - public KEY_TYPE dequeue() { - if(size <= 0) throw new NoSuchElementException(); - int index = findFirstIndex(); - KEY_TYPE value = array[index]; - if(index != --size) System.arraycopy(array, index+1, array, index, size - index); -#if TYPE_OBJECT - array[size] = null; -#endif - firstIndex = -1; - return value; - } - - @Override - public KEY_TYPE first() { - if(isEmpty()) throw new NoSuchElementException(); - if(firstIndex == -1) findFirstIndex(); - return array[firstIndex]; - } - - @Override - public KEY_TYPE peek(int index) { - if(index < 0 || index >= size) throw new NoSuchElementException(); - return array[index]; - } - - @Override - public boolean removeFirst(KEY_TYPE e) { - for(int i = 0;i=0;i--) - if(KEY_EQUALS(e, array[i])) return removeIndex(i); - return false; - } - - protected boolean removeIndex(int index) { - if(index != --size) System.arraycopy(array, index+1, array, index, size - index); -#if TYPE_OBJECT - array[size] = null; -#endif - if(index == firstIndex) firstIndex = -1; - else if(firstIndex != -1 && index >= firstIndex) firstIndex--; - return true; - } - - @Override - public void onChanged() { - firstIndex = -1; - } - - @Override - public int size() { - return size; - } - - @Override - public void clear() { -#if TYPE_OBJECT - Arrays.fill(array, null); -#endif - size = 0; - } - - @Override - public void forEach(CONSUMER KEY_SUPER_GENERIC_TYPE action) { - Objects.requireNonNull(action); - for(int i = 0,m=size;i void forEach(E input, BI_FROM_OBJECT_CONSUMER KSK_GENERIC_TYPE action) { - Objects.requireNonNull(action); - for(int i = 0,m=size;i KEY_SPECIAL_TYPE reduce(KEY_SPECIAL_TYPE identity, BiFunction operator) { - Objects.requireNonNull(operator); - KEY_SPECIAL_TYPE state = identity; - for(int i = 0;i KEY_SPECIAL_TYPE[] TO_ARRAY(KEY_SPECIAL_TYPE[] input) { - if(input == null || input.length < size()) input = NEW_SPECIAL_KEY_ARRAY(size()); - System.arraycopy(array, 0, input, 0, size()); - return input; - } - - protected int findFirstIndex() { - if(firstIndex == -1) { - int index = size-1; - KEY_TYPE value = array[index]; - if(comparator == null) { - for(int i = index;i>=0;i--) { - if(COMPAREABLE_TO_KEY(array[i], value) < 0) - value = array[index = i]; - } - } - else { - for(int i = index;i>=0;i--) { - if(comparator.compare(array[i], value) < 0) - value = array[index = i]; - } - } - firstIndex = index; - } - return firstIndex; - } - - private class Iter implements ITERATOR KEY_GENERIC_TYPE { - @Override - public boolean hasNext() { - return !isEmpty(); - } - - @Override - public KEY_TYPE NEXT() { - if(!hasNext()) throw new NoSuchElementException(); - return dequeue(); - } - } +package speiger.src.collections.PACKAGE.queues; + +import java.util.Arrays; +import java.util.NoSuchElementException; +#if TYPE_OBJECT +import java.util.Comparator; +import java.util.function.Consumer; +import java.util.function.BiFunction; +#endif +import java.util.Objects; +#if JDK_FUNCTION +import java.util.function.PREDICATE; +#endif + +import speiger.src.collections.PACKAGE.collections.COLLECTION; +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.ints.functions.consumer.BI_FROM_INT_CONSUMER; +import speiger.src.collections.objects.functions.consumer.BI_FROM_OBJECT_CONSUMER; +#if !JDK_FUNCTION +import speiger.src.collections.PACKAGE.functions.function.PREDICATE; +#endif +import speiger.src.collections.PACKAGE.functions.function.UNARY_OPERATOR; +import speiger.src.collections.PACKAGE.utils.ARRAYS; +import speiger.src.collections.utils.SanityChecks; + +/** + * A Array Priority Queue, this is a very unoptimized implementation of the PriorityQueue for very specific usecases. + * It allows for duplicated entries and works like {@link java.util.List#indexOf(Object)} search. + * It is highly suggested to use HeapPriorityQueue otherwise, unless you know why you need this specific implementation + * @Type(T) + */ +public class ARRAY_PRIORITY_QUEUE KEY_GENERIC_TYPE extends ABSTRACT_PRIORITY_QUEUE KEY_GENERIC_TYPE +{ + /** The Backing Array */ + protected transient KEY_TYPE[] array = EMPTY_KEY_ARRAY; + /** The Amount of elements stored within the array */ + protected int size; + /** The Last known first index pointer */ + protected int firstIndex = -1; + /** The Sorter of the Array */ + protected COMPARATOR KEY_SUPER_GENERIC_TYPE comparator; + + /** + * Default Constructor + */ + public ARRAY_PRIORITY_QUEUE() { + this(0, null); + } + + /** + * Constructor using custom sorter + * @param comp Comparator to sort the Array. Can be null + */ + public ARRAY_PRIORITY_QUEUE(COMPARATOR KEY_SUPER_GENERIC_TYPE comp) { + this(0, comp); + } + + /** + * Constructor with a Min Capacity + * @param size the initial capacity of the backing array + * @throws IllegalStateException if the initial size is smaller 0 + */ + public ARRAY_PRIORITY_QUEUE(int size) { + this(size, null); + } + + /** + * Constructor with a Min Capacity and custom Sorter + * @param size the initial capacity of the backing array + * @param comp Comparator to sort the Array. Can be null + * @throws IllegalStateException if the initial size is smaller 0 + */ + public ARRAY_PRIORITY_QUEUE(int size, COMPARATOR KEY_SUPER_GENERIC_TYPE comp) { + if(size < 0) throw new IllegalAccessError("Size has to be 0 or positive"); + if(size > 0) array = NEW_KEY_ARRAY(size); + comparator = comp; + } + + /** + * Constructor using a initial array + * @param array the Array that should be used + */ + public ARRAY_PRIORITY_QUEUE(KEY_TYPE[] array) { + this(array, array.length); + } + + /** + * Constructor using a initial array + * @param array the Array that should be used + * @param size the amount of elements found within the array + * @throws NegativeArraySizeException if size is smaller then 0 + */ + public ARRAY_PRIORITY_QUEUE(KEY_TYPE[] array, int size) { + this.array = Arrays.copyOf(array, size); + this.size = size; + } + + /** + * Constructor using a initial array and a custom sorter + * @param array the Array that should be used + * @param comp Comparator to sort the Array. Can be null + */ + public ARRAY_PRIORITY_QUEUE(KEY_TYPE[] array, COMPARATOR KEY_SUPER_GENERIC_TYPE comp) { + this(array, array.length, comp); + } + + /** + * Constructor using a initial array and a custom sorter + * @param array the Array that should be used + * @param size the amount of elements found within the array + * @param comp Comparator to sort the Array. Can be null + * @throws NegativeArraySizeException if size is smaller then 0 + */ + public ARRAY_PRIORITY_QUEUE(KEY_TYPE[] array, int size, COMPARATOR KEY_SUPER_GENERIC_TYPE comp) { + this.array = Arrays.copyOf(array, size); + this.size = size; + this.comparator = comp; + } + + /** + * Constructor using a Collection + * @param c the Collection that should be used + */ + public ARRAY_PRIORITY_QUEUE(COLLECTION KEY_GENERIC_TYPE c) { + array = CAST_KEY_ARRAY c.TO_ARRAY(); + size = c.size(); + } + + /** + * Constructor using a Collection and a custom sorter + * @param c the Collection that should be used + * @param comp Comparator to sort the Array. Can be null + */ + public ARRAY_PRIORITY_QUEUE(COLLECTION KEY_GENERIC_TYPE c, COMPARATOR KEY_SUPER_GENERIC_TYPE comp) { + array = CAST_KEY_ARRAY c.TO_ARRAY(); + size = c.size(); + comparator = comp; + } + + /** + * Wrapping method to help serialization + * @param array the array that should be used + * @Type(T) + * @return a ArrayPriorityQueue containing the original input array + */ + public static GENERIC_KEY_BRACES ARRAY_PRIORITY_QUEUE KEY_GENERIC_TYPE wrap(KEY_TYPE[] array) { + return wrap(array, array.length); + } + + /** + * Wrapping method to help serialization + * @param array the array that should be used + * @param size the amount of elements within the array + * @Type(T) + * @return a ArrayPriorityQueue containing the original input array + */ + public static GENERIC_KEY_BRACES ARRAY_PRIORITY_QUEUE KEY_GENERIC_TYPE wrap(KEY_TYPE[] array, int size) { + ARRAY_PRIORITY_QUEUE KEY_GENERIC_TYPE queue = new ARRAY_PRIORITY_QUEUEBRACES(); + queue.array = array; + queue.size = size; + return queue; + } + + /** + * Wrapping method to help serialization, using a custom sorter + * @param array the array that should be used + * @param comp Comparator to sort the Array. Can be null + * @Type(T) + * @return a ArrayPriorityQueue containing the original input array + */ + public static GENERIC_KEY_BRACES ARRAY_PRIORITY_QUEUE KEY_GENERIC_TYPE wrap(KEY_TYPE[] array, COMPARATOR KEY_SUPER_GENERIC_TYPE comp) { + return wrap(array, array.length, comp); + } + + /** + * Wrapping method to help serialization, using a custom sorter + * @param array the array that should be used + * @param size the amount of elements within the array + * @param comp Comparator to sort the Array. Can be null + * @Type(T) + * @return a ArrayPriorityQueue containing the original input array + */ + public static GENERIC_KEY_BRACES ARRAY_PRIORITY_QUEUE KEY_GENERIC_TYPE wrap(KEY_TYPE[] array, int size, COMPARATOR KEY_SUPER_GENERIC_TYPE comp) { + ARRAY_PRIORITY_QUEUE KEY_GENERIC_TYPE queue = new ARRAY_PRIORITY_QUEUEBRACES(comp); + queue.array = array; + queue.size = size; + return queue; + } + + @Override + public void enqueue(KEY_TYPE e) { + if(size == array.length) array = Arrays.copyOf(array, (int)Math.max(Math.min((long)array.length + (long)(array.length >> 1), (long)SanityChecks.MAX_ARRAY_SIZE), size+1)); + if(firstIndex != -1){ + int compare = comparator == null ? COMPAREABLE_TO_KEY(e, array[firstIndex]) : comparator.compare(e, array[firstIndex]); + if(compare < 0) firstIndex = size; + else if(compare > 0) firstIndex = -1; + } + array[size++] = e; + } + + @Override + public KEY_TYPE dequeue() { + if(size <= 0) throw new NoSuchElementException(); + int index = findFirstIndex(); + KEY_TYPE value = array[index]; + if(index != --size) System.arraycopy(array, index+1, array, index, size - index); +#if TYPE_OBJECT + array[size] = null; +#endif + firstIndex = -1; + return value; + } + + @Override + public KEY_TYPE first() { + if(isEmpty()) throw new NoSuchElementException(); + if(firstIndex == -1) findFirstIndex(); + return array[firstIndex]; + } + + @Override + public KEY_TYPE peek(int index) { + if(index < 0 || index >= size) throw new NoSuchElementException(); + return array[index]; + } + + @Override + public boolean contains(KEY_TYPE e) { + for(int i = 0;i=0;i--) + if(KEY_EQUALS(e, array[i])) return removeIndex(i); + return false; + } + + protected boolean removeIndex(int index) { + if(index != --size) System.arraycopy(array, index+1, array, index, size - index); +#if TYPE_OBJECT + array[size] = null; +#endif + if(index == firstIndex) firstIndex = -1; + else if(firstIndex != -1 && index >= firstIndex) firstIndex--; + return true; + } + + @Override + public void onChanged() { + firstIndex = -1; + } + + @Override + public int size() { + return size; + } + + @Override + public void clear() { +#if TYPE_OBJECT + Arrays.fill(array, null); +#endif + size = 0; + } + + @Override + public void forEach(CONSUMER KEY_SUPER_GENERIC_TYPE action) { + Objects.requireNonNull(action); + for(int i = 0,m=size;i void forEach(E input, BI_FROM_OBJECT_CONSUMER KSK_GENERIC_TYPE action) { + Objects.requireNonNull(action); + for(int i = 0,m=size;i KEY_SPECIAL_TYPE reduce(KEY_SPECIAL_TYPE identity, BiFunction operator) { + Objects.requireNonNull(operator); + KEY_SPECIAL_TYPE state = identity; + for(int i = 0;i KEY_SPECIAL_TYPE[] TO_ARRAY(KEY_SPECIAL_TYPE[] input) { + if(input == null || input.length < size()) input = NEW_SPECIAL_KEY_ARRAY(size()); + System.arraycopy(array, 0, input, 0, size()); + return input; + } + + protected int findFirstIndex() { + if(firstIndex == -1) { + int index = size-1; + KEY_TYPE value = array[index]; + if(comparator == null) { + for(int i = index;i>=0;i--) { + if(COMPAREABLE_TO_KEY(array[i], value) < 0) + value = array[index = i]; + } + } + else { + for(int i = index;i>=0;i--) { + if(comparator.compare(array[i], value) < 0) + value = array[index = i]; + } + } + firstIndex = index; + } + return firstIndex; + } + + private class Iter implements ITERATOR KEY_GENERIC_TYPE { + @Override + public boolean hasNext() { + return !isEmpty(); + } + + @Override + public KEY_TYPE NEXT() { + if(!hasNext()) throw new NoSuchElementException(); + return dequeue(); + } + } } \ No newline at end of file diff --git a/src/builder/resources/speiger/assets/collections/templates/queues/HeapPriorityQueue.template b/src/builder/resources/speiger/assets/collections/templates/queues/HeapPriorityQueue.template index 3906caa..f0a275c 100644 --- a/src/builder/resources/speiger/assets/collections/templates/queues/HeapPriorityQueue.template +++ b/src/builder/resources/speiger/assets/collections/templates/queues/HeapPriorityQueue.template @@ -1,408 +1,415 @@ -package speiger.src.collections.PACKAGE.queues; - -import java.util.Arrays; -import java.util.NoSuchElementException; -#if TYPE_OBJECT -import java.util.Comparator; -import java.util.function.Consumer; -import java.util.function.BiFunction; -#endif -import java.util.Objects; -#if JDK_FUNCTION -import java.util.function.PREDICATE; -#endif - -import speiger.src.collections.PACKAGE.collections.COLLECTION; -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.ints.functions.consumer.BI_FROM_INT_CONSUMER; -import speiger.src.collections.objects.functions.consumer.BI_FROM_OBJECT_CONSUMER; -#if !JDK_FUNCTION -import speiger.src.collections.PACKAGE.functions.function.PREDICATE; -#endif -import speiger.src.collections.PACKAGE.functions.function.UNARY_OPERATOR; -import speiger.src.collections.PACKAGE.utils.ARRAYS; -import speiger.src.collections.utils.SanityChecks; - -/** - * A Simple Heap base Priority Queue implementation - * It is a ArrayBased Alternative to TreeSets that has less object allocations - * @Type(T) - */ -public class HEAP_PRIORITY_QUEUE KEY_GENERIC_TYPE extends ABSTRACT_PRIORITY_QUEUE KEY_GENERIC_TYPE -{ - /** The Backing Array */ - protected transient KEY_TYPE[] array = EMPTY_KEY_ARRAY; - /** The Amount of elements stored within the array */ - protected int size; - /** The Sorter of the Array */ - protected COMPARATOR KEY_SUPER_GENERIC_TYPE comparator; - - /** - * Default Constructor - */ - public HEAP_PRIORITY_QUEUE() { - this(0, null); - } - - /** - * Constructor using custom sorter - * @param comp Comparator to sort the Array. Can be null - */ - public HEAP_PRIORITY_QUEUE(COMPARATOR KEY_SUPER_GENERIC_TYPE comp) { - this(0, comp); - } - - /** - * Constructor with a Min Capacity - * @param size the initial capacity of the backing array - * @throws IllegalStateException if the initial size is smaller 0 - */ - public HEAP_PRIORITY_QUEUE(int size) { - this(size, null); - } - - /** - * Constructor with a Min Capacity and custom Sorter - * @param size the initial capacity of the backing array - * @param comp Comparator to sort the Array. Can be null - * @throws IllegalStateException if the initial size is smaller 0 - */ - public HEAP_PRIORITY_QUEUE(int size, COMPARATOR KEY_SUPER_GENERIC_TYPE comp) { - if(size > 0) array = NEW_KEY_ARRAY(size); - comparator = comp; - } - - /** - * Constructor using a initial array - * @param array the Array that should be used - */ - public HEAP_PRIORITY_QUEUE(KEY_TYPE[] array) { - this(array, array.length); - } - - /** - * Constructor using a initial array - * @param array the Array that should be used - * @param size the amount of elements found within the array - * @throws NegativeArraySizeException if size is smaller then 0 - */ - public HEAP_PRIORITY_QUEUE(KEY_TYPE[] array, int size) { - this.array = Arrays.copyOf(array, size); - this.size = size; - ARRAYS.heapify(array, size, null); - } - - /** - * Constructor using a initial array and a custom sorter - * @param array the Array that should be used - * @param comp Comparator to sort the Array. Can be null - */ - public HEAP_PRIORITY_QUEUE(KEY_TYPE[] array, COMPARATOR KEY_SUPER_GENERIC_TYPE comp) { - this(array, array.length, comp); - } - - /** - * Constructor using a initial array and a custom sorter - * @param array the Array that should be used - * @param size the amount of elements found within the array - * @param comp Comparator to sort the Array. Can be null - * @throws NegativeArraySizeException if size is smaller then 0 - */ - public HEAP_PRIORITY_QUEUE(KEY_TYPE[] array, int size, COMPARATOR KEY_SUPER_GENERIC_TYPE comp) { - this.array = Arrays.copyOf(array, size); - this.size = size; - comparator = comp; - ARRAYS.heapify(array, size, comp); - } - - /** - * Constructor using a Collection - * @param c the Collection that should be used - */ - public HEAP_PRIORITY_QUEUE(COLLECTION KEY_GENERIC_TYPE c) { - array = CAST_KEY_ARRAY c.TO_ARRAY(); - size = c.size(); - ARRAYS.heapify(array, size, null); - } - - /** - * Constructor using a Collection and a custom sorter - * @param c the Collection that should be used - * @param comp Comparator to sort the Array. Can be null - */ - public HEAP_PRIORITY_QUEUE(COLLECTION KEY_GENERIC_TYPE c, COMPARATOR KEY_SUPER_GENERIC_TYPE comp) { - array = CAST_KEY_ARRAY c.TO_ARRAY(); - size = c.size(); - comparator = comp; - ARRAYS.heapify(array, size, comp); - } - - /** - * Wrapping method to help serialization - * @param array the array that should be used - * @Type(T) - * @return a HeapPriorityQueue containing the original input array - */ - public static GENERIC_KEY_BRACES HEAP_PRIORITY_QUEUE KEY_GENERIC_TYPE wrap(KEY_TYPE[] array) { - return wrap(array, array.length); - } - - /** - * Wrapping method to help serialization - * @param array the array that should be used - * @param size the amount of elements within the array - * @Type(T) - * @return a HeapPriorityQueue containing the original input array - */ - public static GENERIC_KEY_BRACES HEAP_PRIORITY_QUEUE KEY_GENERIC_TYPE wrap(KEY_TYPE[] array, int size) { - HEAP_PRIORITY_QUEUE KEY_GENERIC_TYPE queue = new HEAP_PRIORITY_QUEUEBRACES(); - queue.array = array; - queue.size = size; - ARRAYS.heapify(array, size, null); - return queue; - } - - /** - * Wrapping method to help serialization, using a custom sorter - * @param array the array that should be used - * @param comp Comparator to sort the Array. Can be null - * @Type(T) - * @return a HeapPriorityQueue containing the original input array - */ - public static GENERIC_KEY_BRACES HEAP_PRIORITY_QUEUE KEY_GENERIC_TYPE wrap(KEY_TYPE[] array, COMPARATOR KEY_SUPER_GENERIC_TYPE comp) { - return wrap(array, array.length, comp); - } - - /** - * Wrapping method to help serialization, using a custom sorter - * @param array the array that should be used - * @param size the amount of elements within the array - * @param comp Comparator to sort the Array. Can be null - * @Type(T) - * @return a HeapPriorityQueue containing the original input array - */ - public static GENERIC_KEY_BRACES HEAP_PRIORITY_QUEUE KEY_GENERIC_TYPE wrap(KEY_TYPE[] array, int size, COMPARATOR KEY_SUPER_GENERIC_TYPE comp) { - HEAP_PRIORITY_QUEUE KEY_GENERIC_TYPE queue = new HEAP_PRIORITY_QUEUEBRACES(comp); - queue.array = array; - queue.size = size; - ARRAYS.heapify(array, size, comp); - return queue; - } - - @Override - public int size() { - return size; - } - - @Override - public void clear() { -#if TYPE_OBJECT - Arrays.fill(array, null); -#endif - size = 0; - } - - @Override - public ITERATOR KEY_GENERIC_TYPE iterator() { - return new Iter(); - } - - @Override - public void enqueue(KEY_TYPE e) { - if(size == array.length) array = Arrays.copyOf(array, (int)Math.max(Math.min((long)array.length + (long)(array.length >> 1), (long)SanityChecks.MAX_ARRAY_SIZE), size+1)); - array[size++] = e; - ARRAYS.shiftUp(array, size-1, comparator); - } - - @Override - public KEY_TYPE dequeue() { - if(size <= 0) throw new NoSuchElementException(); - KEY_TYPE value = array[0]; - array[0] = array[--size]; -#if TYPE_OBJECT - array[size] = null; -#endif - if(size != 0) ARRAYS.shiftDown(array, size, 0, comparator); - return value; - } - - @Override - public KEY_TYPE peek(int index) { - if(index < 0 || index >= size) throw new NoSuchElementException(); - return array[index]; - } - - @Override - public boolean removeFirst(KEY_TYPE e) { - for(int i = 0;i=0;i--) - if(KEY_EQUALS(e, array[i])) return removeIndex(i); - return false; - } - - @Override - public void forEach(CONSUMER KEY_SUPER_GENERIC_TYPE action) { - Objects.requireNonNull(action); - for(int i = 0,m=size;i void forEach(E input, BI_FROM_OBJECT_CONSUMER KSK_GENERIC_TYPE action) { - Objects.requireNonNull(action); - for(int i = 0,m=size;i KEY_SPECIAL_TYPE reduce(KEY_SPECIAL_TYPE identity, BiFunction operator) { - Objects.requireNonNull(operator); - KEY_SPECIAL_TYPE state = identity; - for(int i = 0;i KEY_SPECIAL_TYPE[] TO_ARRAY(KEY_SPECIAL_TYPE[] input) { - if(input == null || input.length < size()) input = NEW_SPECIAL_KEY_ARRAY(size()); - System.arraycopy(array, 0, input, 0, size()); - return input; - } - - private class Iter implements ITERATOR KEY_GENERIC_TYPE { - @Override - public boolean hasNext() { - return !isEmpty(); - } - - @Override - public KEY_TYPE NEXT() { - if(!hasNext()) throw new NoSuchElementException(); - return dequeue(); - } - } +package speiger.src.collections.PACKAGE.queues; + +import java.util.Arrays; +import java.util.NoSuchElementException; +#if TYPE_OBJECT +import java.util.Comparator; +import java.util.function.Consumer; +import java.util.function.BiFunction; +#endif +import java.util.Objects; +#if JDK_FUNCTION +import java.util.function.PREDICATE; +#endif + +import speiger.src.collections.PACKAGE.collections.COLLECTION; +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.ints.functions.consumer.BI_FROM_INT_CONSUMER; +import speiger.src.collections.objects.functions.consumer.BI_FROM_OBJECT_CONSUMER; +#if !JDK_FUNCTION +import speiger.src.collections.PACKAGE.functions.function.PREDICATE; +#endif +import speiger.src.collections.PACKAGE.functions.function.UNARY_OPERATOR; +import speiger.src.collections.PACKAGE.utils.ARRAYS; +import speiger.src.collections.utils.SanityChecks; + +/** + * A Simple Heap base Priority Queue implementation + * It is a ArrayBased Alternative to TreeSets that has less object allocations + * @Type(T) + */ +public class HEAP_PRIORITY_QUEUE KEY_GENERIC_TYPE extends ABSTRACT_PRIORITY_QUEUE KEY_GENERIC_TYPE +{ + /** The Backing Array */ + protected transient KEY_TYPE[] array = EMPTY_KEY_ARRAY; + /** The Amount of elements stored within the array */ + protected int size; + /** The Sorter of the Array */ + protected COMPARATOR KEY_SUPER_GENERIC_TYPE comparator; + + /** + * Default Constructor + */ + public HEAP_PRIORITY_QUEUE() { + this(0, null); + } + + /** + * Constructor using custom sorter + * @param comp Comparator to sort the Array. Can be null + */ + public HEAP_PRIORITY_QUEUE(COMPARATOR KEY_SUPER_GENERIC_TYPE comp) { + this(0, comp); + } + + /** + * Constructor with a Min Capacity + * @param size the initial capacity of the backing array + * @throws IllegalStateException if the initial size is smaller 0 + */ + public HEAP_PRIORITY_QUEUE(int size) { + this(size, null); + } + + /** + * Constructor with a Min Capacity and custom Sorter + * @param size the initial capacity of the backing array + * @param comp Comparator to sort the Array. Can be null + * @throws IllegalStateException if the initial size is smaller 0 + */ + public HEAP_PRIORITY_QUEUE(int size, COMPARATOR KEY_SUPER_GENERIC_TYPE comp) { + if(size > 0) array = NEW_KEY_ARRAY(size); + comparator = comp; + } + + /** + * Constructor using a initial array + * @param array the Array that should be used + */ + public HEAP_PRIORITY_QUEUE(KEY_TYPE[] array) { + this(array, array.length); + } + + /** + * Constructor using a initial array + * @param array the Array that should be used + * @param size the amount of elements found within the array + * @throws NegativeArraySizeException if size is smaller then 0 + */ + public HEAP_PRIORITY_QUEUE(KEY_TYPE[] array, int size) { + this.array = Arrays.copyOf(array, size); + this.size = size; + ARRAYS.heapify(array, size, null); + } + + /** + * Constructor using a initial array and a custom sorter + * @param array the Array that should be used + * @param comp Comparator to sort the Array. Can be null + */ + public HEAP_PRIORITY_QUEUE(KEY_TYPE[] array, COMPARATOR KEY_SUPER_GENERIC_TYPE comp) { + this(array, array.length, comp); + } + + /** + * Constructor using a initial array and a custom sorter + * @param array the Array that should be used + * @param size the amount of elements found within the array + * @param comp Comparator to sort the Array. Can be null + * @throws NegativeArraySizeException if size is smaller then 0 + */ + public HEAP_PRIORITY_QUEUE(KEY_TYPE[] array, int size, COMPARATOR KEY_SUPER_GENERIC_TYPE comp) { + this.array = Arrays.copyOf(array, size); + this.size = size; + comparator = comp; + ARRAYS.heapify(array, size, comp); + } + + /** + * Constructor using a Collection + * @param c the Collection that should be used + */ + public HEAP_PRIORITY_QUEUE(COLLECTION KEY_GENERIC_TYPE c) { + array = CAST_KEY_ARRAY c.TO_ARRAY(); + size = c.size(); + ARRAYS.heapify(array, size, null); + } + + /** + * Constructor using a Collection and a custom sorter + * @param c the Collection that should be used + * @param comp Comparator to sort the Array. Can be null + */ + public HEAP_PRIORITY_QUEUE(COLLECTION KEY_GENERIC_TYPE c, COMPARATOR KEY_SUPER_GENERIC_TYPE comp) { + array = CAST_KEY_ARRAY c.TO_ARRAY(); + size = c.size(); + comparator = comp; + ARRAYS.heapify(array, size, comp); + } + + /** + * Wrapping method to help serialization + * @param array the array that should be used + * @Type(T) + * @return a HeapPriorityQueue containing the original input array + */ + public static GENERIC_KEY_BRACES HEAP_PRIORITY_QUEUE KEY_GENERIC_TYPE wrap(KEY_TYPE[] array) { + return wrap(array, array.length); + } + + /** + * Wrapping method to help serialization + * @param array the array that should be used + * @param size the amount of elements within the array + * @Type(T) + * @return a HeapPriorityQueue containing the original input array + */ + public static GENERIC_KEY_BRACES HEAP_PRIORITY_QUEUE KEY_GENERIC_TYPE wrap(KEY_TYPE[] array, int size) { + HEAP_PRIORITY_QUEUE KEY_GENERIC_TYPE queue = new HEAP_PRIORITY_QUEUEBRACES(); + queue.array = array; + queue.size = size; + ARRAYS.heapify(array, size, null); + return queue; + } + + /** + * Wrapping method to help serialization, using a custom sorter + * @param array the array that should be used + * @param comp Comparator to sort the Array. Can be null + * @Type(T) + * @return a HeapPriorityQueue containing the original input array + */ + public static GENERIC_KEY_BRACES HEAP_PRIORITY_QUEUE KEY_GENERIC_TYPE wrap(KEY_TYPE[] array, COMPARATOR KEY_SUPER_GENERIC_TYPE comp) { + return wrap(array, array.length, comp); + } + + /** + * Wrapping method to help serialization, using a custom sorter + * @param array the array that should be used + * @param size the amount of elements within the array + * @param comp Comparator to sort the Array. Can be null + * @Type(T) + * @return a HeapPriorityQueue containing the original input array + */ + public static GENERIC_KEY_BRACES HEAP_PRIORITY_QUEUE KEY_GENERIC_TYPE wrap(KEY_TYPE[] array, int size, COMPARATOR KEY_SUPER_GENERIC_TYPE comp) { + HEAP_PRIORITY_QUEUE KEY_GENERIC_TYPE queue = new HEAP_PRIORITY_QUEUEBRACES(comp); + queue.array = array; + queue.size = size; + ARRAYS.heapify(array, size, comp); + return queue; + } + + @Override + public int size() { + return size; + } + + @Override + public void clear() { +#if TYPE_OBJECT + Arrays.fill(array, null); +#endif + size = 0; + } + + @Override + public ITERATOR KEY_GENERIC_TYPE iterator() { + return new Iter(); + } + + @Override + public void enqueue(KEY_TYPE e) { + if(size == array.length) array = Arrays.copyOf(array, (int)Math.max(Math.min((long)array.length + (long)(array.length >> 1), (long)SanityChecks.MAX_ARRAY_SIZE), size+1)); + array[size++] = e; + ARRAYS.shiftUp(array, size-1, comparator); + } + + @Override + public KEY_TYPE dequeue() { + if(size <= 0) throw new NoSuchElementException(); + KEY_TYPE value = array[0]; + array[0] = array[--size]; +#if TYPE_OBJECT + array[size] = null; +#endif + if(size != 0) ARRAYS.shiftDown(array, size, 0, comparator); + return value; + } + + @Override + public KEY_TYPE peek(int index) { + if(index < 0 || index >= size) throw new NoSuchElementException(); + return array[index]; + } + + @Override + public boolean contains(KEY_TYPE e) { + for(int i = 0;i=0;i--) + if(KEY_EQUALS(e, array[i])) return removeIndex(i); + return false; + } + + @Override + public void forEach(CONSUMER KEY_SUPER_GENERIC_TYPE action) { + Objects.requireNonNull(action); + for(int i = 0,m=size;i void forEach(E input, BI_FROM_OBJECT_CONSUMER KSK_GENERIC_TYPE action) { + Objects.requireNonNull(action); + for(int i = 0,m=size;i KEY_SPECIAL_TYPE reduce(KEY_SPECIAL_TYPE identity, BiFunction operator) { + Objects.requireNonNull(operator); + KEY_SPECIAL_TYPE state = identity; + for(int i = 0;i KEY_SPECIAL_TYPE[] TO_ARRAY(KEY_SPECIAL_TYPE[] input) { + if(input == null || input.length < size()) input = NEW_SPECIAL_KEY_ARRAY(size()); + System.arraycopy(array, 0, input, 0, size()); + return input; + } + + private class Iter implements ITERATOR KEY_GENERIC_TYPE { + @Override + public boolean hasNext() { + return !isEmpty(); + } + + @Override + public KEY_TYPE NEXT() { + if(!hasNext()) throw new NoSuchElementException(); + return dequeue(); + } + } } \ No newline at end of file diff --git a/src/builder/resources/speiger/assets/collections/templates/queues/PriorityQueue.template b/src/builder/resources/speiger/assets/collections/templates/queues/PriorityQueue.template index 41a40ac..07693d9 100644 --- a/src/builder/resources/speiger/assets/collections/templates/queues/PriorityQueue.template +++ b/src/builder/resources/speiger/assets/collections/templates/queues/PriorityQueue.template @@ -111,6 +111,13 @@ public interface PRIORITY_QUEUE KEY_GENERIC_TYPE extends ITERABLE KEY_GENERIC_TY */ public default KEY_TYPE first() { return peek(0); } + /** + * Method to find out if a element is part of the queue + * @param e the element that is searched for + * @return true if the element is in the queue + */ + public boolean contains(KEY_TYPE e); + /** * Removes the first found element in the queue * @param e the element that should be removed diff --git a/src/builder/resources/speiger/assets/collections/templates/utils/AsyncBuilder.template b/src/builder/resources/speiger/assets/collections/templates/utils/AsyncBuilder.template index 50e70ff..d6ab499 100644 --- a/src/builder/resources/speiger/assets/collections/templates/utils/AsyncBuilder.template +++ b/src/builder/resources/speiger/assets/collections/templates/utils/AsyncBuilder.template @@ -16,6 +16,16 @@ import java.util.function.IntFunction; import java.util.function.BiFunction; import java.util.Comparator; +#iterate +#argument MAPPER Predicate ToByteFunction ToShortFunction ToIntFunction ToLongFunction ToFloatFunction ToDoubleFunction +#argument BUILDER BooleanAsyncBuilder ByteAsyncBuilder ShortAsyncBuilder IntAsyncBuilder LongAsyncBuilder FloatAsyncBuilder DoubleAsyncBuilder +#argument PACKAGE booleans bytes shorts ints longs floats doubles +#argument CHECK BOOLEAN_ASYNC_MODULE BYTE_ASYNC_MODULE SHORT_ASYNC_MODULE INT_ASYNC_MODULE LONG_ASYNC_MODULE FLOAT_ASYNC_MODULE DOUBLE_ASYNC_MODULE +#if CHECK +import speiger.src.collections.objects.functions.function.MAPPER; +import speiger.src.collections.PACKAGE.utils.BUILDER; +#endif +#enditerate #endif import speiger.src.collections.PACKAGE.collections.ITERABLE; #if OBJECT_ASYNC_MODULE @@ -23,7 +33,9 @@ import speiger.src.collections.PACKAGE.collections.COLLECTION; #endif import speiger.src.collections.PACKAGE.collections.ITERATOR; import speiger.src.collections.PACKAGE.functions.TASK; +#if !TYPE_OBJECT import speiger.src.collections.PACKAGE.functions.function.PREDICATE; +#endif #if OBJECT_ASYNC_MODULE import speiger.src.collections.PACKAGE.functions.function.TO_OBJECT_FUNCTION; #endif @@ -59,7 +71,9 @@ import speiger.src.collections.PACKAGE.sets.ARRAY_SET; #endif #endif #if !TYPE_BOOLEAN && BOOLEAN_ASYNC_MODULE +#if !TYPE_OBJECT import speiger.src.collections.booleans.utils.BooleanAsyncBuilder; +#endif import speiger.src.collections.booleans.utils.BooleanAsyncBuilder.BaseBooleanTask; #endif #if !TYPE_OBJECT && OBJECT_ASYNC_MODULE @@ -67,7 +81,9 @@ import speiger.src.collections.objects.utils.ObjectAsyncBuilder; import speiger.src.collections.objects.utils.ObjectAsyncBuilder.BaseObjectTask; #endif #if !TYPE_INT && INT_ASYNC_MODULE +#if !TYPE_OBJECT import speiger.src.collections.ints.utils.IntAsyncBuilder; +#endif import speiger.src.collections.ints.utils.IntAsyncBuilder.BaseIntTask; #endif import speiger.src.collections.utils.ISizeProvider; @@ -187,6 +203,25 @@ public class ASYNC_BUILDER KEY_GENERIC_TYPE return new ObjectAsyncBuilder<>(ITERABLES.arrayFlatMap(iterable, mapper)); } +#endif +#if TYPE_OBJECT +#iterate +#argument BUILDER BooleanAsyncBuilder ByteAsyncBuilder ShortAsyncBuilder IntAsyncBuilder LongAsyncBuilder FloatAsyncBuilder DoubleAsyncBuilder +#argument MAPPER Predicate ToByteFunction ToShortFunction ToIntFunction ToLongFunction ToFloatFunction ToDoubleFunction +#argument TYPE Boolean Byte Short Int Long Float Double +#argument CHECK BOOLEAN_ASYNC_MODULE BYTE_ASYNC_MODULE SHORT_ASYNC_MODULE INT_ASYNC_MODULE LONG_ASYNC_MODULE FLOAT_ASYNC_MODULE DOUBLE_ASYNC_MODULE +#if CHECK + /** + * Maps the elements to something else + * @param mapper the mapping function + * @return a new Builder Object with the mapped Iterable + */ + public BUILDER mapToTYPE(MAPPER mapper) { + return new BUILDER(ITERABLES.mapToTYPE(iterable, mapper)); + } + +#endif +#enditerate #endif /** * Filters out the unwanted elements out of the Iterable diff --git a/src/builder/resources/speiger/assets/collections/templates/utils/Iterables.template b/src/builder/resources/speiger/assets/collections/templates/utils/Iterables.template index 54f4592..d7b6c64 100644 --- a/src/builder/resources/speiger/assets/collections/templates/utils/Iterables.template +++ b/src/builder/resources/speiger/assets/collections/templates/utils/Iterables.template @@ -19,6 +19,26 @@ import speiger.src.collections.objects.collections.ObjectIterable; import speiger.src.collections.objects.collections.ObjectIterator; import speiger.src.collections.PACKAGE.functions.CONSUMER; import speiger.src.collections.PACKAGE.functions.COMPARATOR; +#else +#if BOOLEAN_COLLECTION_MODULE +import speiger.src.collections.booleans.functions.BooleanConsumer; +import speiger.src.collections.booleans.collections.BooleanIterable; +import speiger.src.collections.booleans.collections.BooleanIterator; +#endif +#iterate +#argument FILTER_TYPE BYTE_COLLECTION_MODULE SHORT_COLLECTION_MODULE INT_COLLECTION_MODULE LONG_COLLECTION_MODULE FLOAT_COLLECTION_MODULE DOUBLE_COLLECTION_MODULE +#argument CONSUMER ByteConsumer ShortConsumer IntConsumer LongConsumer FloatConsumer DoubleConsumer +#argument OUTPUT_ITERABLE ByteIterable ShortIterable IntIterable LongIterable FloatIterable DoubleIterable +#argument OUTPUT_ITERATOR ByteIterator ShortIterator IntIterator LongIterator FloatIterator DoubleIterator +#argument MAPPER ToByteFunction ToShortFunction ToIntFunction ToLongFunction ToFloatFunction ToDoubleFunction +#argument PACKAGE bytes shorts ints longs floats doubles +#if FILTER_TYPE +import speiger.src.collections.PACKAGE.functions.CONSUMER; +import speiger.src.collections.objects.functions.function.MAPPER; +import speiger.src.collections.PACKAGE.collections.OUTPUT_ITERABLE; +import speiger.src.collections.PACKAGE.collections.OUTPUT_ITERATOR; +#endif +#enditerate #endif import speiger.src.collections.PACKAGE.collections.ITERATOR; import speiger.src.collections.PACKAGE.functions.function.TO_OBJECT_FUNCTION; @@ -56,6 +76,39 @@ public class ITERABLES return new MappedIterable<>(iterable, mapper); } +#if TYPE_OBJECT +#iterate +#argument MAPPED_TYPE MappedBoolean MappedByte MappedShort MappedInt MappedLong MappedFloat MappedDouble +#argument OUTPUT_ITERABLE BooleanIterable ByteIterable ShortIterable IntIterable LongIterable FloatIterable DoubleIterable +#argument MAPPER Predicate ToByteFunction ToShortFunction ToIntFunction ToLongFunction ToFloatFunction ToDoubleFunction +#argument DATA_TYPE Boolean Byte Short Int Long Float Double +#argument FILTER_TYPE BOOLEAN_COLLECTION_MODULE BYTE_COLLECTION_MODULE SHORT_COLLECTION_MODULE INT_COLLECTION_MODULE LONG_COLLECTION_MODULE FLOAT_COLLECTION_MODULE DOUBLE_COLLECTION_MODULE +#if FILTER_TYPE + /** + * A Helper function that maps a Java-Iterable into a new Type. + * @param iterable the iterable that should be mapped + * @param mapper the function that decides what the result turns into. + * @Type(T) + * @return a iterable that is mapped to a new result + */ + public static OUTPUT_ITERABLE mapToDATA_TYPE(Iterable iterable, MAPPER mapper) { + return new MAPPED_TYPEIterable<>(wrap(iterable), mapper); + } + + /** + * A Helper function that maps a Iterable into a new Type. + * @param iterable the iterable that should be mapped + * @param mapper the function that decides what the result turns into. + * @Type(T) + * @return a iterable that is mapped to a new result + */ + public static OUTPUT_ITERABLE mapToDATA_TYPE(ITERABLE KEY_GENERIC_TYPE iterable, MAPPER mapper) { + return new MAPPED_TYPEIterable<>(iterable, mapper); + } + +#endif +#enditerate +#endif /** * A Helper function that flatMaps a Java-Iterable into a new Type. * @param iterable the iterable that should be flatMapped @@ -280,6 +333,44 @@ public class ITERABLES #endif } +#if TYPE_OBJECT +#iterate +#argument CONSUMER BooleanConsumer ByteConsumer ShortConsumer IntConsumer LongConsumer FloatConsumer DoubleConsumer +#argument MAPPED_TYPE MappedBoolean MappedByte MappedShort MappedInt MappedLong MappedFloat MappedDouble +#argument OUTPUT_ITERABLE BooleanIterable ByteIterable ShortIterable IntIterable LongIterable FloatIterable DoubleIterable +#argument OUTPUT_ITERATOR BooleanIterator ByteIterator ShortIterator IntIterator LongIterator FloatIterator DoubleIterator +#argument MAPPER Predicate ToByteFunction ToShortFunction ToIntFunction ToLongFunction ToFloatFunction ToDoubleFunction +#argument APPLY test applyAsByte applyAsShort applyAsInt applyAsLong applyAsFloat applyAsDouble +#argument DATA_TYPE Boolean Byte Short Int Long Float Double + private static class MAPPED_TYPEIterable implements OUTPUT_ITERABLE, ISizeProvider + { + ITERABLE KEY_SPECIAL_GENERIC_TYPE iterable; + MAPPER mapper; + + MAPPED_TYPEIterable(ITERABLE iterable, MAPPER mapper) { + this.iterable = iterable; + this.mapper = mapper; + } + + public OUTPUT_ITERATOR iterator() { + return ITERATORS.mapToDATA_TYPE(iterable.iterator(), mapper); + } + + @Override + public int size() { + ISizeProvider prov = ISizeProvider.of(this); + return prov == null ? -1 : prov.size(); + } + + @Override + public void forEach(CONSUMER action) { + Objects.requireNonNull(action); + iterable.forEach(E -> action.accept(mapper.APPLY(E))); + } + } + +#enditerate +#endif private static class MappedIterable KSS_GENERIC_TYPE implements ObjectIterable, ISizeProvider { ITERABLE KEY_SPECIAL_GENERIC_TYPE iterable; diff --git a/src/builder/resources/speiger/assets/collections/templates/utils/Iterators.template b/src/builder/resources/speiger/assets/collections/templates/utils/Iterators.template index 4734daf..dc71c85 100644 --- a/src/builder/resources/speiger/assets/collections/templates/utils/Iterators.template +++ b/src/builder/resources/speiger/assets/collections/templates/utils/Iterators.template @@ -16,6 +16,20 @@ import speiger.src.collections.objects.collections.ObjectIterator; import speiger.src.collections.objects.utils.ObjectIterators; import speiger.src.collections.PACKAGE.functions.CONSUMER; import speiger.src.collections.PACKAGE.functions.COMPARATOR; +#else +#if BOOLEAN_COLLECTION_MODULE +import speiger.src.collections.booleans.collections.BooleanIterator; +#endif +#iterate +#argument ITERATOR ByteIterator ShortIterator IntIterator LongIterator FloatIterator DoubleIterator +#argument PACKAGE bytes shorts ints longs floats doubles +#argument MAPPER ToByteFunction ToShortFunction ToIntFunction ToLongFunction ToFloatFunction ToDoubleFunction +#argument FILTER_TYPE BYTE_COLLECTION_MODULE SHORT_COLLECTION_MODULE INT_COLLECTION_MODULE LONG_COLLECTION_MODULE FLOAT_COLLECTION_MODULE DOUBLE_COLLECTION_MODULE +#if BOOLEAN_COLLECTION_MODULE +import speiger.src.collections.objects.functions.function.MAPPER; +import speiger.src.collections.PACKAGE.collections.ITERATOR; +#endif +#enditerate #endif import speiger.src.collections.PACKAGE.functions.function.TO_OBJECT_FUNCTION; import speiger.src.collections.objects.functions.consumer.BI_FROM_OBJECT_CONSUMER; @@ -109,6 +123,7 @@ public class ITERATORS return iterator instanceof UnmodifiableListIterator ? iterator : new UnmodifiableListIteratorBRACES(iterator); } +#if OBJECT_COLLECTION_MODULE /** * A Helper function that maps a Java-Iterator into a new Type. * @param iterator that should be mapped @@ -133,6 +148,40 @@ public class ITERATORS return new MappedIterator<>(iterator, mapper); } +#endif +#if TYPE_OBJECT +#iterate +#argument MAPPED_TYPE MappedBoolean MappedByte MappedShort MappedInt MappedLong MappedFloat MappedDouble +#argument OUTPUT_ITERATOR BooleanIterator ByteIterator ShortIterator IntIterator LongIterator FloatIterator DoubleIterator +#argument MAPPER Predicate ToByteFunction ToShortFunction ToIntFunction ToLongFunction ToFloatFunction ToDoubleFunction +#argument DATA_TYPE Boolean Byte Short Int Long Float Double +#argument FILTER_TYPE BOOLEAN_COLLECTION_MODULE BYTE_COLLECTION_MODULE SHORT_COLLECTION_MODULE INT_COLLECTION_MODULE LONG_COLLECTION_MODULE FLOAT_COLLECTION_MODULE DOUBLE_COLLECTION_MODULE +#if FILTER_TYPE + /** + * A Helper function that maps a Java-Iterator into a new Type. + * @param iterator that should be mapped + * @param mapper the function that decides what the result turns into. + * @Type(T) + * @return a iterator that is mapped to a new result + */ + public static OUTPUT_ITERATOR mapToDATA_TYPE(Iterator iterator, MAPPER mapper) { + return new MAPPED_TYPEIterator<>(wrap(iterator), mapper); + } + + /** + * A Helper function that maps a Iterator into a new Type. + * @param iterator that should be mapped + * @param mapper the function that decides what the result turns into. + * @Type(T) + * @return a iterator that is mapped to a new result + */ + public static OUTPUT_ITERATOR mapToDATA_TYPE(ITERATOR KEY_GENERIC_TYPE iterator, MAPPER mapper) { + return new MAPPED_TYPEIterator<>(iterator, mapper); + } + +#endif +#enditerate +#endif /** * A Helper function that flatMaps a Java-Iterator into a new Type. * @param iterator that should be flatMapped @@ -868,6 +917,42 @@ public class ITERATORS } } +#if TYPE_OBJECT +#iterate +#argument MAPPED_TYPE MappedBoolean MappedByte MappedShort MappedInt MappedLong MappedFloat MappedDouble +#argument NEXT_TYPE nextBoolean nextByte nextShort nextInt nextLong nextFloat nextDouble +#argument OUTPUT_ITERATOR BooleanIterator ByteIterator ShortIterator IntIterator LongIterator FloatIterator DoubleIterator +#argument MAPPER Predicate ToByteFunction ToShortFunction ToIntFunction ToLongFunction ToFloatFunction ToDoubleFunction +#argument APPLY test applyAsByte applyAsShort applyAsInt applyAsLong applyAsFloat applyAsDouble +#argument DATA_TYPE boolean byte short int long float double + private static class MAPPED_TYPEIterator implements OUTPUT_ITERATOR + { + ITERATOR iterator; + MAPPER mapper; + + MAPPED_TYPEIterator(ITERATOR KEY_SPECIAL_GENERIC_TYPE iterator, MAPPER mapper) { + this.iterator = iterator; + this.mapper = mapper; + } + + @Override + public boolean hasNext() { + return iterator.hasNext(); + } + + @Override + public DATA_TYPE NEXT_TYPE() { + return mapper.APPLY(iterator.NEXT()); + } + + @Override + public int skip(int amount) { + return iterator.skip(amount); + } + } + +#enditerate +#endif private static class FlatMappedIterator KSS_GENERIC_TYPE> implements ObjectIterator { ITERATOR KEY_SPECIAL_GENERIC_TYPE iterator; diff --git a/src/builder/resources/speiger/assets/collections/templates/utils/Lists.template b/src/builder/resources/speiger/assets/collections/templates/utils/Lists.template index b160d45..f48adc3 100644 --- a/src/builder/resources/speiger/assets/collections/templates/utils/Lists.template +++ b/src/builder/resources/speiger/assets/collections/templates/utils/Lists.template @@ -24,6 +24,9 @@ import speiger.src.collections.PACKAGE.functions.CONSUMER; #endif import speiger.src.collections.PACKAGE.lists.ABSTRACT_LIST; import speiger.src.collections.PACKAGE.lists.LIST; +#if INT_LIST_MODULE && !TYPE_INT +import speiger.src.collections.ints.lists.IntList; +#endif import speiger.src.collections.PACKAGE.lists.LIST_ITERATOR; import speiger.src.collections.utils.SanityChecks; @@ -408,6 +411,18 @@ public class LISTS return l.listIterator(index); } + @Override + public LIST_ITERATOR KEY_GENERIC_TYPE indexedIterator(int...indecies) { + return l.indexedIterator(indecies); + } + +#if INT_LIST_MODULE + @Override + public LIST_ITERATOR KEY_GENERIC_TYPE indexedIterator(IntList indecies) { + return l.indexedIterator(indecies); + } + +#endif @Override public LIST KEY_GENERIC_TYPE subList(int from, int to) { return LISTS.synchronize(l.subList(from, to)); @@ -535,6 +550,18 @@ public class LISTS return ITERATORS.unmodifiable(l.listIterator(index)); } + @Override + public LIST_ITERATOR KEY_GENERIC_TYPE indexedIterator(int...indecies) { + return ITERATORS.unmodifiable(l.indexedIterator(indecies)); + } + +#if INT_LIST_MODULE + @Override + public LIST_ITERATOR KEY_GENERIC_TYPE indexedIterator(IntList indecies) { + return ITERATORS.unmodifiable(l.indexedIterator(indecies)); + } + +#endif @Override public LIST KEY_GENERIC_TYPE subList(int from, int to) { return LISTS.unmodifiable(l.subList(from, to)); @@ -633,6 +660,18 @@ public class LISTS return ITERATORS.empty(); } + @Override + public LIST_ITERATOR KEY_GENERIC_TYPE indexedIterator(int...indecies) { + return ITERATORS.empty(); + } + +#if INT_LIST_MODULE + @Override + public LIST_ITERATOR KEY_GENERIC_TYPE indexedIterator(IntList indecies) { + return ITERATORS.empty(); + } + +#endif @Override public int hashCode() { return 1; } diff --git a/src/builder/resources/speiger/assets/collections/templates/utils/PriorityQueues.template b/src/builder/resources/speiger/assets/collections/templates/utils/PriorityQueues.template index 7289a6d..d83a50d 100644 --- a/src/builder/resources/speiger/assets/collections/templates/utils/PriorityQueues.template +++ b/src/builder/resources/speiger/assets/collections/templates/utils/PriorityQueues.template @@ -116,6 +116,8 @@ public class PRIORITY_QUEUES @Override public KEY_TYPE peek(int index) { synchronized(mutex) { return queue.peek(index); } } @Override + public boolean contains(KEY_TYPE e) { synchronized(mutex) { return queue.contains(e); } } + @Override public boolean removeFirst(KEY_TYPE e) { synchronized(mutex) { return queue.removeFirst(e); } } @Override public boolean removeLast(KEY_TYPE e) { synchronized(mutex) { return queue.removeLast(e); } } diff --git a/src/builder/resources/speiger/assets/collections/templates/utils/maps/Maps.template b/src/builder/resources/speiger/assets/collections/templates/utils/maps/Maps.template index 1328436..2fa0854 100644 --- a/src/builder/resources/speiger/assets/collections/templates/utils/maps/Maps.template +++ b/src/builder/resources/speiger/assets/collections/templates/utils/maps/Maps.template @@ -341,19 +341,21 @@ public class MAPS @Override public VALUE_TYPE COMPUTE(KEY_TYPE key, UNARY_OPERATOR KEY_VALUE_GENERIC_TYPE mappingFunction) { throw new UnsupportedOperationException(); } @Override - public VALUE_TYPE COMPUTENonDefault(KEY_TYPE key, UNARY_OPERATOR KEY_VALUE_GENERIC_TYPE mappingFunction) { throw new UnsupportedOperationException(); } - @Override public VALUE_TYPE COMPUTE_IF_ABSENT(KEY_TYPE key, FUNCTION KEY_VALUE_GENERIC_TYPE mappingFunction) { throw new UnsupportedOperationException(); } @Override - public VALUE_TYPE COMPUTE_IF_ABSENTNonDefault(KEY_TYPE key, FUNCTION KEY_VALUE_GENERIC_TYPE mappingFunction) { throw new UnsupportedOperationException(); } - @Override public VALUE_TYPE COMPUTE_IF_PRESENT(KEY_TYPE key, UNARY_OPERATOR KEY_VALUE_GENERIC_TYPE mappingFunction) { throw new UnsupportedOperationException(); } @Override + public VALUE_TYPE SUPPLY_IF_ABSENT(KEY_TYPE key, VALUE_SUPPLIER VALUE_GENERIC_TYPE valueProvider) { throw new UnsupportedOperationException(); } +#if !VALUE_OBJECT + @Override + public VALUE_TYPE COMPUTENonDefault(KEY_TYPE key, UNARY_OPERATOR KEY_VALUE_GENERIC_TYPE mappingFunction) { throw new UnsupportedOperationException(); } + @Override + public VALUE_TYPE COMPUTE_IF_ABSENTNonDefault(KEY_TYPE key, FUNCTION KEY_VALUE_GENERIC_TYPE mappingFunction) { throw new UnsupportedOperationException(); } + @Override public VALUE_TYPE COMPUTE_IF_PRESENTNonDefault(KEY_TYPE key, UNARY_OPERATOR KEY_VALUE_GENERIC_TYPE mappingFunction) { throw new UnsupportedOperationException(); } @Override - public VALUE_TYPE SUPPLY_IF_ABSENT(KEY_TYPE key, VALUE_SUPPLIER VALUE_GENERIC_TYPE valueProvider) { throw new UnsupportedOperationException(); } - @Override public VALUE_TYPE SUPPLY_IF_ABSENTNonDefault(KEY_TYPE key, VALUE_SUPPLIER VALUE_GENERIC_TYPE valueProvider) { throw new UnsupportedOperationException(); } +#endif @Override public VALUE_TYPE MERGE(KEY_TYPE key, VALUE_TYPE value, VALUE_UNARY_OPERATOR VALUE_VALUE_GENERIC_TYPE mappingFunction) { throw new UnsupportedOperationException(); } @Override @@ -411,19 +413,21 @@ public class MAPS @Override public VALUE_TYPE COMPUTE(KEY_TYPE key, UNARY_OPERATOR KEY_VALUE_GENERIC_TYPE mappingFunction) { throw new UnsupportedOperationException(); } @Override - public VALUE_TYPE COMPUTENonDefault(KEY_TYPE key, UNARY_OPERATOR KEY_VALUE_GENERIC_TYPE mappingFunction) { throw new UnsupportedOperationException(); } - @Override public VALUE_TYPE COMPUTE_IF_ABSENT(KEY_TYPE key, FUNCTION KEY_VALUE_GENERIC_TYPE mappingFunction) { throw new UnsupportedOperationException(); } @Override - public VALUE_TYPE COMPUTE_IF_ABSENTNonDefault(KEY_TYPE key, FUNCTION KEY_VALUE_GENERIC_TYPE mappingFunction) { throw new UnsupportedOperationException(); } - @Override public VALUE_TYPE COMPUTE_IF_PRESENT(KEY_TYPE key, UNARY_OPERATOR KEY_VALUE_GENERIC_TYPE mappingFunction) { throw new UnsupportedOperationException(); } @Override + public VALUE_TYPE SUPPLY_IF_ABSENT(KEY_TYPE key, VALUE_SUPPLIER VALUE_GENERIC_TYPE valueProvider) { throw new UnsupportedOperationException(); } +#if !VALUE_OBJECT + @Override + public VALUE_TYPE COMPUTENonDefault(KEY_TYPE key, UNARY_OPERATOR KEY_VALUE_GENERIC_TYPE mappingFunction) { throw new UnsupportedOperationException(); } + @Override + public VALUE_TYPE COMPUTE_IF_ABSENTNonDefault(KEY_TYPE key, FUNCTION KEY_VALUE_GENERIC_TYPE mappingFunction) { throw new UnsupportedOperationException(); } + @Override public VALUE_TYPE COMPUTE_IF_PRESENTNonDefault(KEY_TYPE key, UNARY_OPERATOR KEY_VALUE_GENERIC_TYPE mappingFunction) { throw new UnsupportedOperationException(); } @Override - public VALUE_TYPE SUPPLY_IF_ABSENT(KEY_TYPE key, VALUE_SUPPLIER VALUE_GENERIC_TYPE valueProvider) { throw new UnsupportedOperationException(); } - @Override public VALUE_TYPE SUPPLY_IF_ABSENTNonDefault(KEY_TYPE key, VALUE_SUPPLIER VALUE_GENERIC_TYPE valueProvider) { throw new UnsupportedOperationException(); } +#endif @Override public VALUE_TYPE MERGE(KEY_TYPE key, VALUE_TYPE value, VALUE_UNARY_OPERATOR VALUE_VALUE_GENERIC_TYPE mappingFunction) { throw new UnsupportedOperationException(); } @Override @@ -670,19 +674,21 @@ public class MAPS @Override public VALUE_TYPE COMPUTE(KEY_TYPE key, UNARY_OPERATOR KEY_VALUE_GENERIC_TYPE mappingFunction) { throw new UnsupportedOperationException(); } @Override - public VALUE_TYPE COMPUTENonDefault(KEY_TYPE key, UNARY_OPERATOR KEY_VALUE_GENERIC_TYPE mappingFunction) { throw new UnsupportedOperationException(); } - @Override public VALUE_TYPE COMPUTE_IF_ABSENT(KEY_TYPE key, FUNCTION KEY_VALUE_GENERIC_TYPE mappingFunction) { throw new UnsupportedOperationException(); } @Override - public VALUE_TYPE COMPUTE_IF_ABSENTNonDefault(KEY_TYPE key, FUNCTION KEY_VALUE_GENERIC_TYPE mappingFunction) { throw new UnsupportedOperationException(); } - @Override public VALUE_TYPE COMPUTE_IF_PRESENT(KEY_TYPE key, UNARY_OPERATOR KEY_VALUE_GENERIC_TYPE mappingFunction) { throw new UnsupportedOperationException(); } @Override + public VALUE_TYPE SUPPLY_IF_ABSENT(KEY_TYPE key, VALUE_SUPPLIER VALUE_GENERIC_TYPE valueProvider) { throw new UnsupportedOperationException(); } +#if !VALUE_OBJECT + @Override + public VALUE_TYPE COMPUTENonDefault(KEY_TYPE key, UNARY_OPERATOR KEY_VALUE_GENERIC_TYPE mappingFunction) { throw new UnsupportedOperationException(); } + @Override + public VALUE_TYPE COMPUTE_IF_ABSENTNonDefault(KEY_TYPE key, FUNCTION KEY_VALUE_GENERIC_TYPE mappingFunction) { throw new UnsupportedOperationException(); } + @Override public VALUE_TYPE COMPUTE_IF_PRESENTNonDefault(KEY_TYPE key, UNARY_OPERATOR KEY_VALUE_GENERIC_TYPE mappingFunction) { throw new UnsupportedOperationException(); } @Override - public VALUE_TYPE SUPPLY_IF_ABSENT(KEY_TYPE key, VALUE_SUPPLIER VALUE_GENERIC_TYPE valueProvider) { throw new UnsupportedOperationException(); } - @Override public VALUE_TYPE SUPPLY_IF_ABSENTNonDefault(KEY_TYPE key, VALUE_SUPPLIER VALUE_GENERIC_TYPE valueProvider) { throw new UnsupportedOperationException(); } +#endif @Override public VALUE_TYPE MERGE(KEY_TYPE key, VALUE_TYPE value, VALUE_UNARY_OPERATOR VALUE_VALUE_GENERIC_TYPE mappingFunction) { throw new UnsupportedOperationException(); } @Override @@ -1110,19 +1116,21 @@ public class MAPS @Override public VALUE_TYPE COMPUTE(KEY_TYPE key, UNARY_OPERATOR KEY_VALUE_GENERIC_TYPE mappingFunction) { synchronized(mutex) { return map.COMPUTE(key, mappingFunction); } } @Override - public VALUE_TYPE COMPUTENonDefault(KEY_TYPE key, UNARY_OPERATOR KEY_VALUE_GENERIC_TYPE mappingFunction) { synchronized(mutex) { return map.COMPUTENonDefault(key, mappingFunction); } } - @Override public VALUE_TYPE COMPUTE_IF_ABSENT(KEY_TYPE key, FUNCTION KEY_VALUE_GENERIC_TYPE mappingFunction) { synchronized(mutex) { return map.COMPUTE_IF_ABSENT(key, mappingFunction); } } @Override - public VALUE_TYPE COMPUTE_IF_ABSENTNonDefault(KEY_TYPE key, FUNCTION KEY_VALUE_GENERIC_TYPE mappingFunction) { synchronized(mutex) { return map.COMPUTE_IF_ABSENTNonDefault(key, mappingFunction); } } - @Override public VALUE_TYPE COMPUTE_IF_PRESENT(KEY_TYPE key, UNARY_OPERATOR KEY_VALUE_GENERIC_TYPE mappingFunction) { synchronized(mutex) { return map.COMPUTE_IF_PRESENT(key, mappingFunction); } } @Override + public VALUE_TYPE SUPPLY_IF_ABSENT(KEY_TYPE key, VALUE_SUPPLIER VALUE_GENERIC_TYPE valueProvider) { synchronized(mutex) { return map.SUPPLY_IF_ABSENT(key, valueProvider); } } +#if !VALUE_OBJECT + @Override + public VALUE_TYPE COMPUTENonDefault(KEY_TYPE key, UNARY_OPERATOR KEY_VALUE_GENERIC_TYPE mappingFunction) { synchronized(mutex) { return map.COMPUTENonDefault(key, mappingFunction); } } + @Override + public VALUE_TYPE COMPUTE_IF_ABSENTNonDefault(KEY_TYPE key, FUNCTION KEY_VALUE_GENERIC_TYPE mappingFunction) { synchronized(mutex) { return map.COMPUTE_IF_ABSENTNonDefault(key, mappingFunction); } } + @Override public VALUE_TYPE COMPUTE_IF_PRESENTNonDefault(KEY_TYPE key, UNARY_OPERATOR KEY_VALUE_GENERIC_TYPE mappingFunction) { synchronized(mutex) { return map.COMPUTE_IF_PRESENTNonDefault(key, mappingFunction); } } @Override - public VALUE_TYPE SUPPLY_IF_ABSENT(KEY_TYPE key, VALUE_SUPPLIER VALUE_GENERIC_TYPE valueProvider) { synchronized(mutex) { return map.SUPPLY_IF_ABSENT(key, valueProvider); } } - @Override public VALUE_TYPE SUPPLY_IF_ABSENTNonDefault(KEY_TYPE key, VALUE_SUPPLIER VALUE_GENERIC_TYPE valueProvider) { synchronized(mutex) { return map.SUPPLY_IF_ABSENTNonDefault(key, valueProvider); } } +#endif @Override public VALUE_TYPE MERGE(KEY_TYPE key, VALUE_TYPE value, VALUE_UNARY_OPERATOR VALUE_VALUE_GENERIC_TYPE mappingFunction) { synchronized(mutex) { return map.MERGE(key, value, mappingFunction); } } @Override diff --git a/src/test/java/speiger/src/collections/ints/base/BaseIntIterableTest.java b/src/test/java/speiger/src/collections/ints/base/BaseIntIterableTest.java index 946d1e5..26387d3 100644 --- a/src/test/java/speiger/src/collections/ints/base/BaseIntIterableTest.java +++ b/src/test/java/speiger/src/collections/ints/base/BaseIntIterableTest.java @@ -1,174 +1,174 @@ -package speiger.src.collections.ints.base; - -import java.util.Arrays; -import java.util.EnumSet; -import java.util.stream.IntStream; - -import org.junit.Assert; -import org.junit.Test; - -import speiger.src.collections.ints.collections.IntIterable; -import speiger.src.collections.ints.collections.IntIterator; -import speiger.src.collections.ints.lists.IntArrayList; -import speiger.src.collections.ints.utils.IntArrays; -import speiger.src.collections.ints.utils.IntIterators; -import speiger.src.collections.objects.utils.ObjectArrays; -import speiger.src.collections.objects.utils.ObjectIterators; -import speiger.src.collections.tests.IterableTest; - -@SuppressWarnings("javadoc") -public abstract class BaseIntIterableTest -{ - protected static final int[] EMPTY_ARRAY = new int[0]; - protected static final int[] TEST_ARRAY = IntStream.range(0, 100).toArray(); - protected static final int[] DISTINCT_ARRAY = IntStream.range(0, 100).flatMap(T -> Arrays.stream(new int[]{T, T})).toArray(); - - protected abstract IntIterable create(int[] data); - - protected EnumSet getValidIterableTests() { return EnumSet.allOf(IterableTest.class); } - - @Test - public void testForEach() { - if(getValidIterableTests().contains(IterableTest.FOR_EACH)) { - create(TEST_ARRAY).forEach(T -> Assert.assertTrue(T >= 0 && T < 100)); - } - } - - @Test - public void testIteratorForEach() { - if(getValidIterableTests().contains(IterableTest.ITERATOR_FOR_EACH)) { - create(TEST_ARRAY).iterator().forEachRemaining(T -> Assert.assertTrue(T >= 0 && T < 100)); - } - } - - @Test - public void testSkip() { - if(getValidIterableTests().contains(IterableTest.ITERATOR_SKIP)) { - IntIterator iter = create(TEST_ARRAY).iterator(); - Assert.assertEquals(50, iter.skip(50)); - Assert.assertNotEquals(100, iter.skip(100)); - } - } - - @Test - public void testIteratorLoop() { - if(getValidIterableTests().contains(IterableTest.ITERATOR_LOOP)) { - for(int entry : create(TEST_ARRAY)) Assert.assertTrue(entry >= 0 && entry < 100); - - for(IntIterator iter = create(TEST_ARRAY).iterator();iter.hasNext();) { - int entry = iter.nextInt(); - Assert.assertTrue(entry >= 0 && entry < 100); - } - } - } - - @Test - public void testIteratorRemovalLoop() { - if(getValidIterableTests().contains(IterableTest.ITERATOR_REMOVAL)) { - for(IntIterator iter = create(TEST_ARRAY).iterator();iter.hasNext();) { - int entry = iter.nextInt(); - Assert.assertTrue(entry >= 0 && entry < 100); - iter.remove(); - } - } - } - - @Test - public void testStreamCount() { - if(getValidIterableTests().contains(IterableTest.STREAM_COUNT)) { - long expected = IntStream.of(TEST_ARRAY).filter(T -> T % 2 == 0).count(); - int size = create(TEST_ARRAY).count(T -> T % 2 == 0); - Assert.assertEquals(expected, size); - } - } - - @Test - public void testStreamFilter() { - if(getValidIterableTests().contains(IterableTest.STREAM_FILTER)) { - int[] expected = IntStream.of(TEST_ARRAY).filter(T -> T % 2 == 0).toArray(); - int[] actual = IntIterators.pour(create(TEST_ARRAY).filter(T -> T % 2 == 0).iterator()).toIntArray(); - IntArrays.stableSort(actual); - Assert.assertArrayEquals(expected, actual); - } - } - - @Test - public void testStreamFindFirst() { - if(getValidIterableTests().contains(IterableTest.STREAM_FIND_FIRST)) { - int expected = IntStream.of(TEST_ARRAY).filter(T -> T / 50 > 0).findFirst().getAsInt(); - int actual = create(TEST_ARRAY).findFirst(T -> T / 50 > 0); - Assert.assertEquals(expected, actual); - } - } - - @Test - public void teastStreamDistinct() { - if(getValidIterableTests().contains(IterableTest.STREAM_DISTINCT)) { - int[] expected = IntStream.of(DISTINCT_ARRAY).distinct().toArray(); - int[] actual = IntIterators.pour(create(DISTINCT_ARRAY).distinct().iterator()).toIntArray(); - IntArrays.stableSort(actual); - Assert.assertArrayEquals(expected, actual); - } - } - - @Test - public void testStreamLimit() { - if(getValidIterableTests().contains(IterableTest.STREAM_LIMIT)) { - int[] expected = IntStream.of(TEST_ARRAY).limit(25).toArray(); - int[] actual = IntIterators.pour(create(TEST_ARRAY).limit(25).iterator()).toIntArray(); - Assert.assertEquals(expected.length, actual.length); - } - } - - @Test - public void testStreamMap() { - if(getValidIterableTests().contains(IterableTest.STREAM_MAP)) { - Integer[] expected = IntStream.of(TEST_ARRAY).mapToObj(Integer::valueOf).toArray(Integer[]::new); - Integer[] actual = ObjectIterators.pour(create(TEST_ARRAY).map(Integer::valueOf).iterator()).toArray(Integer[]::new); - ObjectArrays.stableSort(actual); - Assert.assertArrayEquals(expected, actual); - } - } - - @Test - public void testStreamMatches() { - if(getValidIterableTests().contains(IterableTest.STREAM_MATCHES)) { - IntIterable iterable = create(TEST_ARRAY); - Assert.assertTrue(iterable.matchesAll(T -> T >= 0)); - Assert.assertFalse(iterable.matchesAll(T -> T < 0)); - Assert.assertTrue(iterable.matchesAny(T -> T % 2 != 0)); - Assert.assertFalse(iterable.matchesAny(T -> T % 2 >= 2)); - Assert.assertTrue(iterable.matchesNone(T -> T % 2 >= 2)); - Assert.assertFalse(iterable.matchesNone(T -> T % 2 != 0)); - } - } - - @Test - public void testStreamPeek() { - if(getValidIterableTests().contains(IterableTest.STREAM_PEEK)) { - int[] peekCount = new int[2]; - create(TEST_ARRAY).peek(T -> peekCount[0]++).forEach(T -> peekCount[1]++); - Assert.assertEquals(TEST_ARRAY.length, peekCount[0]); - Assert.assertEquals(TEST_ARRAY.length, peekCount[1]); - } - } - - @Test - public void testStreamPour() { - if(getValidIterableTests().contains(IterableTest.STREAM_POUR)) { - int[] expected = TEST_ARRAY; - int[] actual = create(TEST_ARRAY).pour(new IntArrayList()).toIntArray(); - IntArrays.stableSort(actual); - Assert.assertArrayEquals(expected, actual); - } - } - - @Test - public void testStreamReduce() { - if(getValidIterableTests().contains(IterableTest.STREAM_REDUCE)) { - int expected = IntStream.of(TEST_ARRAY).reduce(0, Integer::sum); - int actual = create(TEST_ARRAY).reduce(0, Integer::sum); - Assert.assertEquals(expected, actual); - } - } +package speiger.src.collections.ints.base; + +import java.util.Arrays; +import java.util.EnumSet; +import java.util.stream.IntStream; + +import org.junit.Assert; +import org.junit.Test; + +import speiger.src.collections.ints.collections.IntIterable; +import speiger.src.collections.ints.collections.IntIterator; +import speiger.src.collections.ints.lists.IntArrayList; +import speiger.src.collections.ints.utils.IntArrays; +import speiger.src.collections.ints.utils.IntIterators; +import speiger.src.collections.objects.utils.ObjectArrays; +import speiger.src.collections.objects.utils.ObjectIterators; +import speiger.src.collections.tests.IterableTest; + +@SuppressWarnings("javadoc") +public abstract class BaseIntIterableTest +{ + protected static final int[] EMPTY_ARRAY = new int[0]; + protected static final int[] TEST_ARRAY = IntStream.range(0, 100).toArray(); + protected static final int[] DISTINCT_ARRAY = IntStream.range(0, 100).flatMap(T -> Arrays.stream(new int[]{T, T})).toArray(); + + protected abstract IntIterable create(int[] data); + + protected EnumSet getValidIterableTests() { return EnumSet.allOf(IterableTest.class); } + + @Test + public void testForEach() { + if(getValidIterableTests().contains(IterableTest.FOR_EACH)) { + create(TEST_ARRAY).forEach(T -> Assert.assertTrue(T >= 0 && T < 100)); + } + } + + @Test + public void testIteratorForEach() { + if(getValidIterableTests().contains(IterableTest.ITERATOR_FOR_EACH)) { + create(TEST_ARRAY).iterator().forEachRemaining(T -> Assert.assertTrue(T >= 0 && T < 100)); + } + } + + @Test + public void testSkip() { + if(getValidIterableTests().contains(IterableTest.ITERATOR_SKIP)) { + IntIterator iter = create(TEST_ARRAY).iterator(); + Assert.assertEquals(50, iter.skip(50)); + Assert.assertNotEquals(100, iter.skip(100)); + } + } + + @Test + public void testIteratorLoop() { + if(getValidIterableTests().contains(IterableTest.ITERATOR_LOOP)) { + for(int entry : create(TEST_ARRAY)) Assert.assertTrue(entry >= 0 && entry < 100); + + for(IntIterator iter = create(TEST_ARRAY).iterator();iter.hasNext();) { + int entry = iter.nextInt(); + Assert.assertTrue(entry >= 0 && entry < 100); + } + } + } + + @Test + public void testIteratorRemovalLoop() { + if(getValidIterableTests().contains(IterableTest.ITERATOR_REMOVAL)) { + for(IntIterator iter = create(TEST_ARRAY).iterator();iter.hasNext();) { + int entry = iter.nextInt(); + Assert.assertTrue(entry >= 0 && entry < 100); + iter.remove(); + } + } + } + + @Test + public void testStreamCount() { + if(getValidIterableTests().contains(IterableTest.STREAM_COUNT)) { + long expected = IntStream.of(TEST_ARRAY).filter(T -> T % 2 == 0).count(); + int size = create(TEST_ARRAY).count(T -> T % 2 == 0); + Assert.assertEquals(expected, size); + } + } + + @Test + public void testStreamFilter() { + if(getValidIterableTests().contains(IterableTest.STREAM_FILTER)) { + int[] expected = IntStream.of(TEST_ARRAY).filter(T -> T % 2 == 0).toArray(); + int[] actual = IntIterators.pour(create(TEST_ARRAY).filter(T -> T % 2 == 0).iterator()).toIntArray(); + IntArrays.stableSort(actual); + Assert.assertArrayEquals(expected, actual); + } + } + + @Test + public void testStreamFindFirst() { + if(getValidIterableTests().contains(IterableTest.STREAM_FIND_FIRST)) { + int expected = IntStream.of(TEST_ARRAY).filter(T -> T / 50 > 0).findFirst().getAsInt(); + int actual = create(TEST_ARRAY).findFirst(T -> T / 50 > 0); + Assert.assertEquals(expected, actual); + } + } + + @Test + public void teastStreamDistinct() { + if(getValidIterableTests().contains(IterableTest.STREAM_DISTINCT)) { + int[] expected = IntStream.of(DISTINCT_ARRAY).distinct().toArray(); + int[] actual = IntIterators.pour(create(DISTINCT_ARRAY).distinct().iterator()).toIntArray(); + IntArrays.stableSort(actual); + Assert.assertArrayEquals(expected, actual); + } + } + + @Test + public void testStreamLimit() { + if(getValidIterableTests().contains(IterableTest.STREAM_LIMIT)) { + int[] expected = IntStream.of(TEST_ARRAY).limit(25).toArray(); + int[] actual = IntIterators.pour(create(TEST_ARRAY).limit(25).iterator()).toIntArray(); + Assert.assertEquals(expected.length, actual.length); + } + } + + @Test + public void testStreamMap() { + if(getValidIterableTests().contains(IterableTest.STREAM_MAP)) { + Integer[] expected = IntStream.of(TEST_ARRAY).mapToObj(Integer::valueOf).toArray(Integer[]::new); + Integer[] actual = ObjectIterators.pour(create(TEST_ARRAY).map(Integer::valueOf).iterator()).toArray(Integer[]::new); + ObjectArrays.stableSort(actual); + Assert.assertArrayEquals(expected, actual); + } + } + + @Test + public void testStreamMatches() { + if(getValidIterableTests().contains(IterableTest.STREAM_MATCHES)) { + IntIterable iterable = create(TEST_ARRAY); + Assert.assertTrue(iterable.matchesAll(T -> T >= 0)); + Assert.assertFalse(iterable.matchesAll(T -> T < 0)); + Assert.assertTrue(iterable.matchesAny(T -> T % 2 != 0)); + Assert.assertFalse(iterable.matchesAny(T -> T % 2 >= 2)); + Assert.assertTrue(iterable.matchesNone(T -> T % 2 >= 2)); + Assert.assertFalse(iterable.matchesNone(T -> T % 2 != 0)); + } + } + + @Test + public void testStreamPeek() { + if(getValidIterableTests().contains(IterableTest.STREAM_PEEK)) { + int[] peekCount = new int[2]; + create(TEST_ARRAY).peek(T -> peekCount[0]++).forEach(T -> peekCount[1]++); + Assert.assertEquals(TEST_ARRAY.length, peekCount[0]); + Assert.assertEquals(TEST_ARRAY.length, peekCount[1]); + } + } + + @Test + public void testStreamPour() { + if(getValidIterableTests().contains(IterableTest.STREAM_POUR)) { + int[] expected = TEST_ARRAY; + int[] actual = create(TEST_ARRAY).pour(new IntArrayList()).toIntArray(); + IntArrays.stableSort(actual); + Assert.assertArrayEquals(expected, actual); + } + } + + @Test + public void testStreamReduce() { + if(getValidIterableTests().contains(IterableTest.STREAM_REDUCE)) { + int expected = IntStream.of(TEST_ARRAY).reduce(0, Integer::sum); + int actual = create(TEST_ARRAY).reduce(0, Integer::sum); + Assert.assertEquals(expected, actual); + } + } } \ No newline at end of file diff --git a/src/test/java/speiger/src/collections/ints/base/BaseIntPriorityQueueTest.java b/src/test/java/speiger/src/collections/ints/base/BaseIntPriorityQueueTest.java index 6e53787..5f3290f 100644 --- a/src/test/java/speiger/src/collections/ints/base/BaseIntPriorityQueueTest.java +++ b/src/test/java/speiger/src/collections/ints/base/BaseIntPriorityQueueTest.java @@ -1,150 +1,162 @@ -package speiger.src.collections.ints.base; - - -import java.util.EnumSet; - -import org.junit.Assert; -import org.junit.Test; - -import speiger.src.collections.ints.queues.IntPriorityQueue; -import speiger.src.collections.ints.utils.IntArrays; -import speiger.src.collections.tests.IterableTest; -import speiger.src.collections.tests.PriorityQueueTest; - -@SuppressWarnings("javadoc") -public abstract class BaseIntPriorityQueueTest extends BaseIntIterableTest -{ - @Override - protected abstract IntPriorityQueue create(int[] data); - @Override - protected EnumSet getValidIterableTests() { return EnumSet.of(IterableTest.FOR_EACH, IterableTest.ITERATOR_FOR_EACH, IterableTest.ITERATOR_LOOP, IterableTest.ITERATOR_SKIP); } - protected EnumSet getValidPriorityQueueTests() { return EnumSet.allOf(PriorityQueueTest.class); } - protected boolean isUnsortedRead() { return true; } - - @Test - public void testEnqueue() { - if(getValidPriorityQueueTests().contains(PriorityQueueTest.IN_OUT)) { - IntPriorityQueue queue = create(EMPTY_ARRAY); - for(int i = 0;i<100;i++) { - queue.enqueue(i); - } - for(int i = 0;i<100;i++) { - Assert.assertEquals(i, queue.dequeue()); - } - queue = create(TEST_ARRAY); - for(int i = 0;i<100;i++) { - Assert.assertEquals(i, queue.dequeue()); - } - } - } - - @Test - public void testPeek() { - if(getValidPriorityQueueTests().contains(PriorityQueueTest.PEEK)) { - IntPriorityQueue queue = create(EMPTY_ARRAY); - for(int i = 0;i<100;i++) { - queue.enqueue(i); - } - if(isUnsortedRead()) { - for(int i = 0;i<100;i++) { - int value = queue.peek(i); - Assert.assertTrue(value >= 0 && value < 100); - } - } - else { - for(int i = 0;i<100;i++) { - Assert.assertEquals(i, queue.peek(i)); - } - } - } - } - - @Test - public void testRemove() { - if(getValidPriorityQueueTests().contains(PriorityQueueTest.REMOVE)) { - IntPriorityQueue queue = create(EMPTY_ARRAY); - for(int i = 0;i<100;i++) { - queue.enqueue(i); - } - queue.removeFirst(40); - for(int i = 0;i<99;i++) { - if(i >= 40) Assert.assertEquals(i + 1, queue.dequeue()); - else Assert.assertEquals(i, queue.dequeue()); - } - for(int i = 0;i<100;i++) { - queue.enqueue(i); - } - queue.removeLast(40); - for(int i = 0;i<99;i++) { - if(i >= 40) Assert.assertEquals(i + 1, queue.dequeue()); - else Assert.assertEquals(i, queue.dequeue()); - } - } - } - - @Test - public void testUnorderedPeek() { - EnumSet valid = getValidPriorityQueueTests(); - if(valid.contains(PriorityQueueTest.IN_OUT) && valid.contains(PriorityQueueTest.PEEK) && !isUnsortedRead()) { - IntPriorityQueue queue = create(EMPTY_ARRAY); - for(int i = 0;i<100;i++) { - queue.enqueue(i); - } - for(int i = 0;i<25;i++) { - queue.dequeue(); - queue.enqueue(i); - } - for(int i = 0;i<100;i++) { - Assert.assertEquals((i+25) % 100, queue.peek(i)); - } - } - } - - @Test - @SuppressWarnings("deprecation") - public void testToArray() { - if(getValidPriorityQueueTests().contains(PriorityQueueTest.TO_ARRAY)) { - IntPriorityQueue queue = create(EMPTY_ARRAY); - if(isUnsortedRead()) { - for(int i = 0;i<100;i++) { - queue.enqueue(i); - } - int[] array = queue.toIntArray(); - IntArrays.stableSort(array); - Assert.assertArrayEquals(TEST_ARRAY, array); - int[] data = queue.toIntArray(new int[100]); - int[] nonData = queue.toIntArray(new int[0]); - IntArrays.stableSort(data); - IntArrays.stableSort(nonData); - Assert.assertArrayEquals(array, data); - Assert.assertArrayEquals(array, nonData); - } - else { - int[] shiftPrimArray = new int[100]; - for(int i = 0; i < 100; i++) { - queue.enqueue(i); - shiftPrimArray[(i+80) % 100] = i; - } - Assert.assertArrayEquals(TEST_ARRAY, queue.toIntArray()); - Assert.assertArrayEquals(TEST_ARRAY, queue.toIntArray(new int[100])); - Assert.assertArrayEquals(TEST_ARRAY, queue.toIntArray(null)); - IntPriorityQueue other = create(queue.toIntArray()); - for(int i = 0;i<20;i++) { - other.dequeue(); - other.enqueue(i); - } - Assert.assertArrayEquals(shiftPrimArray, other.toIntArray()); - Assert.assertArrayEquals(shiftPrimArray, other.toIntArray(new int[100])); - } - } - } - - @Test - public void testCopy() { - if(!getValidPriorityQueueTests().contains(PriorityQueueTest.COPY)) return; - IntPriorityQueue queue = create(TEST_ARRAY); - IntPriorityQueue copy = queue.copy(); - Assert.assertFalse(queue == copy); - Assert.assertEquals(queue, copy); - } -} +package speiger.src.collections.ints.base; + + +import java.util.EnumSet; + +import org.junit.Assert; +import org.junit.Test; + +import speiger.src.collections.ints.queues.IntPriorityQueue; +import speiger.src.collections.ints.utils.IntArrays; +import speiger.src.collections.tests.IterableTest; +import speiger.src.collections.tests.PriorityQueueTest; + +@SuppressWarnings("javadoc") +public abstract class BaseIntPriorityQueueTest extends BaseIntIterableTest +{ + @Override + protected abstract IntPriorityQueue create(int[] data); + @Override + protected EnumSet getValidIterableTests() { return EnumSet.of(IterableTest.FOR_EACH, IterableTest.ITERATOR_FOR_EACH, IterableTest.ITERATOR_LOOP, IterableTest.ITERATOR_SKIP); } + protected EnumSet getValidPriorityQueueTests() { return EnumSet.allOf(PriorityQueueTest.class); } + protected boolean isUnsortedRead() { return true; } + + @Test + public void testEnqueue() { + if(getValidPriorityQueueTests().contains(PriorityQueueTest.IN_OUT)) { + IntPriorityQueue queue = create(EMPTY_ARRAY); + for(int i = 0;i<100;i++) { + queue.enqueue(i); + } + for(int i = 0;i<100;i++) { + Assert.assertEquals(i, queue.dequeue()); + } + queue = create(TEST_ARRAY); + for(int i = 0;i<100;i++) { + Assert.assertEquals(i, queue.dequeue()); + } + } + } + + @Test + public void testPeek() { + if(getValidPriorityQueueTests().contains(PriorityQueueTest.PEEK)) { + IntPriorityQueue queue = create(EMPTY_ARRAY); + for(int i = 0;i<100;i++) { + queue.enqueue(i); + } + if(isUnsortedRead()) { + for(int i = 0;i<100;i++) { + int value = queue.peek(i); + Assert.assertTrue(value >= 0 && value < 100); + } + } + else { + for(int i = 0;i<100;i++) { + Assert.assertEquals(i, queue.peek(i)); + } + } + } + } + + @Test + public void testContains() { + if(getValidPriorityQueueTests().contains(PriorityQueueTest.CONTAINS)) { + IntPriorityQueue queue = create(EMPTY_ARRAY); + for(int i = 0;i<100;i++) { + queue.enqueue(i); + } + Assert.assertEquals(true, queue.contains(40)); + Assert.assertEquals(false, queue.contains(140)); + } + } + + @Test + public void testRemove() { + if(getValidPriorityQueueTests().contains(PriorityQueueTest.REMOVE)) { + IntPriorityQueue queue = create(EMPTY_ARRAY); + for(int i = 0;i<100;i++) { + queue.enqueue(i); + } + queue.removeFirst(40); + for(int i = 0;i<99;i++) { + if(i >= 40) Assert.assertEquals(i + 1, queue.dequeue()); + else Assert.assertEquals(i, queue.dequeue()); + } + for(int i = 0;i<100;i++) { + queue.enqueue(i); + } + queue.removeLast(40); + for(int i = 0;i<99;i++) { + if(i >= 40) Assert.assertEquals(i + 1, queue.dequeue()); + else Assert.assertEquals(i, queue.dequeue()); + } + } + } + + @Test + public void testUnorderedPeek() { + EnumSet valid = getValidPriorityQueueTests(); + if(valid.contains(PriorityQueueTest.IN_OUT) && valid.contains(PriorityQueueTest.PEEK) && !isUnsortedRead()) { + IntPriorityQueue queue = create(EMPTY_ARRAY); + for(int i = 0;i<100;i++) { + queue.enqueue(i); + } + for(int i = 0;i<25;i++) { + queue.dequeue(); + queue.enqueue(i); + } + for(int i = 0;i<100;i++) { + Assert.assertEquals((i+25) % 100, queue.peek(i)); + } + } + } + + @Test + @SuppressWarnings("deprecation") + public void testToArray() { + if(getValidPriorityQueueTests().contains(PriorityQueueTest.TO_ARRAY)) { + IntPriorityQueue queue = create(EMPTY_ARRAY); + if(isUnsortedRead()) { + for(int i = 0;i<100;i++) { + queue.enqueue(i); + } + int[] array = queue.toIntArray(); + IntArrays.stableSort(array); + Assert.assertArrayEquals(TEST_ARRAY, array); + int[] data = queue.toIntArray(new int[100]); + int[] nonData = queue.toIntArray(new int[0]); + IntArrays.stableSort(data); + IntArrays.stableSort(nonData); + Assert.assertArrayEquals(array, data); + Assert.assertArrayEquals(array, nonData); + } + else { + int[] shiftPrimArray = new int[100]; + for(int i = 0; i < 100; i++) { + queue.enqueue(i); + shiftPrimArray[(i+80) % 100] = i; + } + Assert.assertArrayEquals(TEST_ARRAY, queue.toIntArray()); + Assert.assertArrayEquals(TEST_ARRAY, queue.toIntArray(new int[100])); + Assert.assertArrayEquals(TEST_ARRAY, queue.toIntArray(null)); + IntPriorityQueue other = create(queue.toIntArray()); + for(int i = 0;i<20;i++) { + other.dequeue(); + other.enqueue(i); + } + Assert.assertArrayEquals(shiftPrimArray, other.toIntArray()); + Assert.assertArrayEquals(shiftPrimArray, other.toIntArray(new int[100])); + } + } + } + + @Test + public void testCopy() { + if(!getValidPriorityQueueTests().contains(PriorityQueueTest.COPY)) return; + IntPriorityQueue queue = create(TEST_ARRAY); + IntPriorityQueue copy = queue.copy(); + Assert.assertFalse(queue == copy); + Assert.assertEquals(queue, copy); + } +} diff --git a/src/test/java/speiger/src/collections/tests/PriorityQueueTest.java b/src/test/java/speiger/src/collections/tests/PriorityQueueTest.java index 963c2e0..5cb8bde 100644 --- a/src/test/java/speiger/src/collections/tests/PriorityQueueTest.java +++ b/src/test/java/speiger/src/collections/tests/PriorityQueueTest.java @@ -1,11 +1,12 @@ -package speiger.src.collections.tests; - -@SuppressWarnings("javadoc") -public enum PriorityQueueTest -{ - IN_OUT, - PEEK, - REMOVE, - TO_ARRAY, - COPY; +package speiger.src.collections.tests; + +@SuppressWarnings("javadoc") +public enum PriorityQueueTest +{ + IN_OUT, + PEEK, + CONTAINS, + REMOVE, + TO_ARRAY, + COPY; } \ No newline at end of file