From a28149ac8dc8e8bda26b736be6957e0ef6bfb10a Mon Sep 17 00:00:00 2001 From: Speiger Date: Wed, 23 Jun 2021 21:45:12 +0200 Subject: [PATCH] Added Shuffle & Reverse Methods and Concat Iterators. --- Changelog.md | 4 +- .../templates/utils/Arrays.template | 94 +++++++++++++++++++ .../templates/utils/Iterators.template | 62 ++++++++++++ .../templates/utils/Lists.template | 92 ++++++++++++++++++ 4 files changed, 251 insertions(+), 1 deletion(-) diff --git a/Changelog.md b/Changelog.md index 0f75ab7..a35f86d 100644 --- a/Changelog.md +++ b/Changelog.md @@ -9,4 +9,6 @@ - Changed: PriorityQueues no longer extends Object Variant. - Changed: Maps.get function is no longer using Suffixes unless its absolutely necessary. - Changed: Maps.remove function is no longer using Suffixes unless its absolutely necessary. -- Changed: ObjectList methods are no longer marked Deprecated even so it was for primitive ones. \ No newline at end of file +- Changed: ObjectList methods are no longer marked Deprecated even so it was for primitive ones. +- Added: Shuffle & Reverse Methods. +- Added: Concat Iterators. \ No newline at end of file diff --git a/src/builder/resources/speiger/assets/collections/templates/utils/Arrays.template b/src/builder/resources/speiger/assets/collections/templates/utils/Arrays.template index 4a0ae93..54afbde 100644 --- a/src/builder/resources/speiger/assets/collections/templates/utils/Arrays.template +++ b/src/builder/resources/speiger/assets/collections/templates/utils/Arrays.template @@ -205,6 +205,31 @@ public class ARRAYS return shuffle(array, SanityChecks.getRandom()); } + /** + * Simple Shuffle method for Arrays. + * @param array the elements that should be shuffled + * @param length the length of the array + * @ArrayType(T) + * @note This uses the SanityChecks#getRandom + * @return the provided sorted array + */ + public static GENERIC_KEY_BRACES KEY_TYPE[] shuffle(KEY_TYPE[] array, int length) { + return shuffle(array, 0, length, SanityChecks.getRandom()); + } + + /** + * Simple Shuffle method for Arrays. + * @param array the elements that should be shuffled + * @param offset the start array + * @param length the length of the array + * @ArrayType(T) + * @note This uses the SanityChecks#getRandom + * @return the provided sorted array + */ + public static GENERIC_KEY_BRACES KEY_TYPE[] shuffle(KEY_TYPE[] array, int offset, int length) { + return shuffle(array, offset, length, SanityChecks.getRandom()); + } + /** * Simple Shuffle method for Arrays. * @param array the elements that should be shuffled @@ -222,6 +247,75 @@ public class ARRAYS return array; } + /** + * Simple Shuffle method for Arrays. + * @param array the elements that should be shuffled + * @param length the length of the array + * @param random the Random Number Generator that should be used for the shuffling + * @ArrayType(T) + * @return the provided sorted array + */ + public static GENERIC_KEY_BRACES KEY_TYPE[] shuffle(KEY_TYPE[] array, int length, Random random) { + return shuffle(array, 0, length, random); + } + + /** + * Simple Shuffle method for Arrays. + * @param array the elements that should be shuffled + * @param offset the start array + * @param length the length of the array + * @param random the Random Number Generator that should be used for the shuffling + * @ArrayType(T) + * @return the provided sorted array + */ + public static GENERIC_KEY_BRACES KEY_TYPE[] shuffle(KEY_TYPE[] array, int offset, int length, Random random) { + for(int i = length-1; i>=0;i--) { + int p = offset + random.nextInt(i + 1); + KEY_TYPE t = array[offset+i]; + array[offset+i] = array[p]; + array[p] = t; + } + return array; + } + + /** + * Simple Array Reversal method + * @param array the Array that should flip + * @ArrayType(T) + * @return the provided array + */ + public static GENERIC_KEY_BRACES KEY_TYPE[] reverse(KEY_TYPE[] array) { + return reverse(array, 0, array.length); + } + + /** + * Simple Array Reversal method + * @param array the Array that should flip + * @param length the length of the array + * @ArrayType(T) + * @return the provided array + */ + public static GENERIC_KEY_BRACES KEY_TYPE[] reverse(KEY_TYPE[] array, int length) { + return reverse(array, 0, length); + } + + /** + * Simple Array Reversal method + * @param array the Array that should flip + * @param length the length of the array + * @param offset the start of the array + * @ArrayType(T) + * @return the provided array + */ + public static GENERIC_KEY_BRACES KEY_TYPE[] reverse(KEY_TYPE[] array, int offset, int length) { + for (int i = offset, mid = offset + length >> 1, j = offset + length - 1; i < mid; i++, j--) { + KEY_TYPE temp = array[i]; + array[i] = array[j]; + array[j] = temp; + } + return array; + } + /** * Sorts the specified range of elements according to the order induced by the specified comparator, * potentially dynamically choosing an appropriate algorithm given the type and size of the array. 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 9f585b9..efb8f86 100644 --- a/src/builder/resources/speiger/assets/collections/templates/utils/Iterators.template +++ b/src/builder/resources/speiger/assets/collections/templates/utils/Iterators.template @@ -1,6 +1,7 @@ package speiger.src.collections.PACKAGE.utils; import java.util.Iterator; +import java.util.NoSuchElementException; import speiger.src.collections.PACKAGE.collections.ITERATOR; import speiger.src.collections.PACKAGE.lists.LIST_ITERATOR; import speiger.src.collections.PACKAGE.collections.BI_ITERATOR; @@ -196,6 +197,28 @@ public class ITERATORS return index; } + /** + * Helper Iterator that concats other iterators together + * @param array the Iterators that should be concatenated + * @ArrayType(T) + * @return iterator of the inputted iterators + */ + public static GENERIC_KEY_BRACES ITERATOR KEY_GENERIC_TYPE concat(ITERATOR KEY_GENERIC_TYPE... array) { + return concat(array, 0, array.length); + } + + /** + * Helper Iterator that concats other iterators together + * @param array the Iterators that should be concatenated + * @param offset where to start within the array + * @param length the length of the array + * @ArrayType(T) + * @return iterator of the inputted iterators + */ + public static GENERIC_KEY_BRACES ITERATOR KEY_GENERIC_TYPE concat(ITERATOR KEY_GENERIC_TYPE[] array, int offset, int length) { + return new ConcatIteratorBRACES(array, offset, length); + } + #if !TYPE_OBJECT /** * A Function to convert a Primitive Iterator to a Object array. @@ -267,6 +290,45 @@ public class ITERATORS } #endif + private static class ConcatIterator KEY_GENERIC_TYPE implements ITERATOR KEY_GENERIC_TYPE + { + ITERATOR KEY_GENERIC_TYPE[] iters; + int offset; + int lastOffset = -1; + int length; + + public ConcatIterator(ITERATOR KEY_GENERIC_TYPE[] iters, int offset, int length) { + this.iters = iters; + this.offset = offset; + this.length = length; + find(); + } + + private void find() { + for(;length != 0 && !iters[offset].hasNext();length--, offset++); + } + + @Override + public boolean hasNext() { + return length > 0; + } + + @Override + public KEY_TYPE NEXT() { + if(!hasNext()) throw new NoSuchElementException(); + KEY_TYPE result = iters[lastOffset = offset].NEXT(); + find(); + return result; + } + + @Override + public void remove() { + if(lastOffset == -1) throw new IllegalStateException(); + iters[lastOffset].remove(); + lastOffset = -1; + } + } + private static class ReverseBiIterator KEY_GENERIC_TYPE implements BI_ITERATOR KEY_GENERIC_TYPE { BI_ITERATOR KEY_GENERIC_TYPE it; 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 3e5f452..6c15351 100644 --- a/src/builder/resources/speiger/assets/collections/templates/utils/Lists.template +++ b/src/builder/resources/speiger/assets/collections/templates/utils/Lists.template @@ -2,6 +2,7 @@ package speiger.src.collections.PACKAGE.utils; import java.util.Collection; import java.util.Objects; +import java.util.Random; import java.util.RandomAccess; import java.util.function.Consumer; @@ -12,6 +13,8 @@ import speiger.src.collections.PACKAGE.functions.CONSUMER; import speiger.src.collections.PACKAGE.lists.ABSTRACT_LIST; import speiger.src.collections.PACKAGE.lists.LIST; import speiger.src.collections.PACKAGE.lists.LIST_ITERATOR; +import speiger.src.collections.PACKAGE.utils.ARRAYS; +import speiger.src.collections.utils.SanityChecks; /** * A Helper class for Lists @@ -77,6 +80,95 @@ public class LISTS return new SingletonListBRACES(element); } + /** + * Reverses the list + * @param list that should be reversed. + * @Type(T) + * @return the input list + */ + public static GENERIC_KEY_BRACES LIST KEY_GENERIC_TYPE reverse(LIST KEY_GENERIC_TYPE list) { + int size = list.size(); + if(list instanceof IARRAY) { + IARRAY KEY_GENERIC_TYPE array = (IARRAY KEY_GENERIC_TYPE)list; +#if TYPE_OBJECT + if(array.isCastable()) { + if(list instanceof SynchronizedArrayList) array.elements(T -> ARRAYS.reverse(T, size)); + else ARRAYS.reverse(array.elements(), size); + return list; + } +#else + if(list instanceof SynchronizedArrayList) array.elements(T -> ARRAYS.reverse(T, size)); + else ARRAYS.reverse(array.elements(), size); + return list; +#endif + } + if(list instanceof RandomAccess) { + for (int i = 0, mid = size >> 1, j = size - 1; i < mid; i++, j--) { + KEY_TYPE t = list.GET_KEY(i); + list.set(i, list.GET_KEY(j)); + list.set(j, t); + } + return list; + } + LIST_ITERATOR KEY_GENERIC_TYPE fwd = list.listIterator(); + LIST_ITERATOR KEY_GENERIC_TYPE rev = list.listIterator(size); + for(int i = 0, mid = size >> 1; i < mid; i++) { + KEY_TYPE tmp = fwd.NEXT(); + fwd.set(rev.PREVIOUS()); + rev.set(tmp); + } + return list; + } + + /** + * Shuffles the list + * @param list that should be Shuffled. + * @Type(T) + * @return the input list + */ + public static GENERIC_KEY_BRACES LIST KEY_GENERIC_TYPE shuffle(LIST KEY_GENERIC_TYPE list) { + return shuffle(list, SanityChecks.getRandom()); + } + + /** + * Shuffles the list + * @param list that should be Shuffled. + * @param random the random that should be used + * @Type(T) + * @return the input list + */ + public static GENERIC_KEY_BRACES LIST KEY_GENERIC_TYPE shuffle(LIST KEY_GENERIC_TYPE list, Random random) { + int size = list.size(); + if(list instanceof IARRAY) { + IARRAY KEY_GENERIC_TYPE array = (IARRAY KEY_GENERIC_TYPE)list; +#if TYPE_OBJECT + if(array.isCastable()) { + if(list instanceof SynchronizedArrayList) array.elements(T -> ARRAYS.shuffle(T, size, random)); + else ARRAYS.shuffle(array.elements(), size, random); + } + else { + for(int i = list.size(); i-- != 0;) { + int p = random.nextInt(i + 1); + KEY_TYPE t = list.GET_KEY(i); + list.set(i, list.GET_KEY(p)); + list.set(p, t); + } + } +#else + if(list instanceof SynchronizedArrayList) array.elements(T -> ARRAYS.shuffle(T, size, random)); + else ARRAYS.shuffle(array.elements(), size, random); +#endif + return list; + } + for(int i = list.size(); i-- != 0;) { + int p = random.nextInt(i + 1); + KEY_TYPE t = list.GET_KEY(i); + list.set(i, list.GET_KEY(p)); + list.set(p, t); + } + return list; + } + private static class SingletonList KEY_GENERIC_TYPE extends ABSTRACT_LIST KEY_GENERIC_TYPE { KEY_TYPE element;