diff --git a/Changelog.md b/Changelog.md index 058d4db..1334c9a 100644 --- a/Changelog.md +++ b/Changelog.md @@ -1,5 +1,10 @@ # Changelog of versions +### Version 0.6.1 +- Fixed: FIFO queue crashing when the last index is before the first index when peek is called. +- Fixed: FIFO queue only clears the array if it was in use. +- Added: Sorted Method for the stream replacing functions. + ### Version 0.6.0 - Added: addOrGet for sets. - Added: Async API which allows to easily execute Iterables/Collections offthread without the complexity. diff --git a/README.md b/README.md index acf9350..3197ac9 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,7 @@ ![build](https://github.com/Speiger/Primitive-Collections/actions/workflows/build_validator.yml/badge.svg) -![Latest Release](https://jitpack.io/v/Speiger/Primitive-Collections.svg) - +[![Latest Release](https://jitpack.io/v/Speiger/Primitive-Collections.svg)](https://jitpack.io/#Speiger/Primitive-Collections) +[![License](https://img.shields.io/badge/License-Apache_2.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) +![GitHub commit activity](https://img.shields.io/github/commit-activity/m/Speiger/Primitive-Collections) # Primitive-Collections This is a Simple Primitive Collections Library aimed to outperform Java's Collection Library and FastUtil. Both in Performance and Quality of Life Features. diff --git a/build.gradle b/build.gradle index 2c35148..26e8839 100644 --- a/build.gradle +++ b/build.gradle @@ -18,7 +18,7 @@ repositories { } archivesBaseName = 'Primitive Collections' -version = '0.6.0'; +version = '0.6.1'; sourceCompatibility = targetCompatibility = compileJava.sourceCompatibility = compileJava.targetCompatibility = JavaVersion.current(); diff --git a/features.md b/features.md index 65fceb3..66b7594 100644 --- a/features.md +++ b/features.md @@ -15,7 +15,7 @@ Functions that increase performance or are quality of life in their nature. Java adds themselves a lot of functional functions like, - Stream: - Map/FlatMap - - Filter/Distinct/Limit + - Filter/Distinct/Limit/Sorted - Count/FindFirst/Collect - Peek/ForEach/Reduce - anyMatch/allMatch/NoneMatch 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 cdae093..0952733 100644 --- a/src/builder/resources/speiger/assets/collections/templates/collections/Iterable.template +++ b/src/builder/resources/speiger/assets/collections/templates/collections/Iterable.template @@ -5,9 +5,11 @@ import java.util.function.Consumer; #if !TYPE_OBJECT import speiger.src.collections.PACKAGE.functions.CONSUMER; +import speiger.src.collections.PACKAGE.functions.COMPARATOR; import speiger.src.collections.objects.collections.ObjectIterable; #else import java.util.function.BiFunction; +import java.util.Comparator; #endif import speiger.src.collections.PACKAGE.functions.function.TO_OBJECT_FUNCTION; @@ -156,6 +158,15 @@ public interface ITERABLE KEY_GENERIC_TYPE extends Iterable return ITERABLES.limit(this, limit); } + /** + * A Helper function to reduce the usage of Streams and allows to sort the elements + * @param sorter that sorts the elements. + * @return a Iterable that is sorted + */ + default ITERABLE KEY_GENERIC_TYPE sorted(COMPARATOR KEY_GENERIC_TYPE sorter) { + return ITERABLES.sorted(this, sorter); + } + /** * A Helper function to reduce the usage of Streams and allows to preview elements before they are iterated through * @param action the action that should be applied diff --git a/src/builder/resources/speiger/assets/collections/templates/queues/ArrayFIFOQueue.template b/src/builder/resources/speiger/assets/collections/templates/queues/ArrayFIFOQueue.template index 05cb271..58091ef 100644 --- a/src/builder/resources/speiger/assets/collections/templates/queues/ArrayFIFOQueue.template +++ b/src/builder/resources/speiger/assets/collections/templates/queues/ArrayFIFOQueue.template @@ -106,10 +106,15 @@ public class ARRAY_FIFO_QUEUE KEY_GENERIC_TYPE extends ABSTRACT_PRIORITY_QUEUE K @Override public void clear() { + if(first != last) { #if TYPE_OBJECT - Arrays.fill(array, null); + Arrays.fill(array, null); #endif - first = last = 0; + first = last = 0; + } + else if(first != 0) { + first = last = 0; + } } @Override @@ -152,9 +157,9 @@ public class ARRAY_FIFO_QUEUE KEY_GENERIC_TYPE extends ABSTRACT_PRIORITY_QUEUE K @Override public KEY_TYPE peek(int index) { - if(first == last || index < 0 || index > size()) throw new NoSuchElementException(); + if(first == last || index < 0 || index >= size()) throw new NoSuchElementException(); index += first; - return index > array.length ? array[index-array.length] : array[index]; + return index >= array.length ? array[index-array.length] : array[index]; } @Override 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 2614807..14c8912 100644 --- a/src/builder/resources/speiger/assets/collections/templates/utils/AsyncBuilder.template +++ b/src/builder/resources/speiger/assets/collections/templates/utils/AsyncBuilder.template @@ -7,12 +7,13 @@ import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; import java.util.concurrent.locks.LockSupport; import java.util.function.Consumer; - #if !TYPE_OBJECT import speiger.src.collections.PACKAGE.functions.CONSUMER; +import speiger.src.collections.PACKAGE.functions.COMPARATOR; #else import java.util.function.BiFunction; +import java.util.Comparator; #endif import speiger.src.collections.PACKAGE.collections.ITERABLE; @@ -172,6 +173,17 @@ public class ASYNC_BUILDER KEY_GENERIC_TYPE return this; } + /** + * Sorts the elements inside of the Iterable. + * This operation is heavily hurting performance because it rebuilds the entire iterator and then sorts it, and this will affect the pausing feature. + * @param sorter that sorts the elements. + * @return self with a sorter applied + */ + public ASYNC_BUILDER KEY_GENERIC_TYPE sorted(COMPARATOR KEY_GENERIC_TYPE sorter) { + iterable = ITERABLES.sorted(iterable, sorter); + return this; + } + /** * Allows to preview elements before they are processed * @param action the action that should be applied 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 9d66df8..5269bf5 100644 --- a/src/builder/resources/speiger/assets/collections/templates/utils/Iterables.template +++ b/src/builder/resources/speiger/assets/collections/templates/utils/Iterables.template @@ -3,6 +3,8 @@ package speiger.src.collections.PACKAGE.utils; import java.util.Objects; #if TYPE_BOOLEAN import java.util.concurrent.atomic.AtomicInteger; +#else if TYPE_OBJECT +import java.util.Comparator; #endif import java.util.concurrent.atomic.AtomicLong; import java.util.function.Consumer; @@ -12,8 +14,11 @@ import speiger.src.collections.PACKAGE.collections.ITERABLE; 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; #endif import speiger.src.collections.PACKAGE.collections.ITERATOR; +import speiger.src.collections.PACKAGE.lists.LIST; +import speiger.src.collections.PACKAGE.lists.ARRAY_LIST; import speiger.src.collections.PACKAGE.functions.function.TO_OBJECT_FUNCTION; import speiger.src.collections.PACKAGE.functions.function.PREDICATE; #if !TYPE_BOOLEAN @@ -164,6 +169,30 @@ public class ITERABLES return new LimitedIterableBRACES(wrap(iterable), limit); } + /** + * A Helper function that sorts the Iterable. + * This operation is heavily hurting performance because it rebuilds the entire iterator and then sorts it. + * @param iterable that should be sorted + * @param sorter that sorts the iterable. Can be null. + * @Type(T) + * @return a sorted iterable. + */ + public static GENERIC_KEY_BRACES ITERABLE KEY_GENERIC_TYPE sorted(ITERABLE KEY_GENERIC_TYPE iterable, COMPARATOR KEY_GENERIC_TYPE sorter) { + return new SortedIterableBRACES(iterable, sorter); + } + + /** + * A Helper function that sorts the Iterable from a Java Iterable + * This operation is heavily hurting performance because it rebuilds the entire iterator and then sorts it. + * @param iterable that should be sorted + * @param sorter that sorts the iterable. Can be null. + * @Type(T) + * @return a sorted iterable. + */ + public static GENERIC_KEY_BRACES ITERABLE KEY_GENERIC_TYPE sorted(Iterable iterable, COMPARATOR KEY_GENERIC_TYPE sorter) { + return new SortedIterableBRACES(wrap(iterable), sorter); + } + /** * A Helper function that allows to preview the result of a Iterable. * @param iterable that should be peeked at @@ -359,6 +388,42 @@ public class ITERABLES #endif } + private static class SortedIterable KEY_GENERIC_TYPE implements ITERABLE KEY_GENERIC_TYPE + { + ITERABLE KEY_GENERIC_TYPE iterable; + COMPARATOR KEY_GENERIC_TYPE sorter; + + public SortedIterable(ITERABLE KEY_GENERIC_TYPE iterable, COMPARATOR KEY_GENERIC_TYPE sorter) { + this.iterable = iterable; + this.sorter = sorter; + } + + @Override + public ITERATOR KEY_GENERIC_TYPE iterator() { + return ITERATORS.sorted(iterable.iterator(), sorter); + } + +#if !TYPE_OBJECT + @Override + public void forEach(CONSUMER action) { + Objects.requireNonNull(action); + LIST KEY_GENERIC_TYPE list = new ARRAY_LISTBRACES(); + iterable.forEach(list::add); + list.unstableSort(sorter); + list.forEach(action); + } +#else + @Override + public void forEach(Consumer action) { + Objects.requireNonNull(action); + LIST KEY_GENERIC_TYPE list = new ARRAY_LISTBRACES(); + iterable.forEach(list::add); + list.unstableSort(sorter); + list.forEach(action); + } +#endif + } + private static class DistinctIterable KEY_GENERIC_TYPE implements ITERABLE KEY_GENERIC_TYPE { ITERABLE KEY_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 88940ff..807298b 100644 --- a/src/builder/resources/speiger/assets/collections/templates/utils/Iterators.template +++ b/src/builder/resources/speiger/assets/collections/templates/utils/Iterators.template @@ -3,6 +3,7 @@ package speiger.src.collections.PACKAGE.utils; import java.util.Iterator; import java.util.NoSuchElementException; #if TYPE_OBJECT +import java.util.Comparator; import java.util.function.CONSUMER; #endif @@ -11,6 +12,7 @@ import speiger.src.collections.PACKAGE.collections.ITERATOR; 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; #endif import speiger.src.collections.PACKAGE.functions.function.TO_OBJECT_FUNCTION; import speiger.src.collections.PACKAGE.functions.function.PREDICATE; @@ -235,6 +237,30 @@ public class ITERATORS return new LimitedIteratorBRACES(wrap(iterator), limit); } + /** + * A Helper function that sorts the Iterator beforehand. + * This operation is heavily hurting performance because it rebuilds the entire iterator and then sorts it. + * @param iterator that should be sorted. + * @param sorter the sorter of the iterator. Can be null. + * @Type(T) + * @return a new sorted iterator + */ + public static GENERIC_KEY_BRACES ITERATOR KEY_GENERIC_TYPE sorted(ITERATOR KEY_GENERIC_TYPE iterator, COMPARATOR KEY_GENERIC_TYPE sorter) { + return new SortedIteratorBRACES(iterator, sorter); + } + + /** + * A Helper function that sorts the Iterator beforehand from a Java Iterator. + * This operation is heavily hurting performance because it rebuilds the entire iterator and then sorts it. + * @param iterator that should be sorted. + * @param sorter the sorter of the iterator. Can be null. + * @Type(T) + * @return a new sorted iterator + */ + public static GENERIC_KEY_BRACES ITERATOR KEY_GENERIC_TYPE sorted(Iterator iterator, COMPARATOR KEY_GENERIC_TYPE sorter) { + return new SortedIteratorBRACES(wrap(iterator), sorter); + } + /** * A Helper function that allows to preview the result of a Iterator. * @param iterator that should be peeked at @@ -871,6 +897,35 @@ public class ITERATORS } } + private static class SortedIterator KEY_GENERIC_TYPE implements ITERATOR KEY_GENERIC_TYPE + { + ITERATOR KEY_GENERIC_TYPE iterator; + COMPARATOR KEY_GENERIC_TYPE sorter; + LIST KEY_GENERIC_TYPE sortedElements = null; + int index = 0; + + public SortedIterator(ITERATOR KEY_GENERIC_TYPE iterator, COMPARATOR KEY_GENERIC_TYPE sorter) { + this.iterator = iterator; + this.sorter = sorter; + } + + @Override + public boolean hasNext() { + if(sortedElements == null) { + boolean hasNext = iterator.hasNext(); + sortedElements = hasNext ? pour(iterator) : LISTS.empty(); + if(hasNext) sortedElements.unstableSort(sorter); + } + return index < sortedElements.size(); + } + + @Override + public KEY_TYPE NEXT() { + if(!hasNext()) throw new IllegalStateException("End of Iterator"); + return sortedElements.GET_KEY(index++); + } + } + private static class DistinctIterator KEY_GENERIC_TYPE implements ITERATOR KEY_GENERIC_TYPE { ITERATOR KEY_GENERIC_TYPE iterator;