diff --git a/README.md b/README.md index 93fa5eae..fba0b38b 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,32 @@ -# Primitive-Collections - -Simple library to create primitive collections. -Using template files to generate them. - -Project for self teaching. \ No newline at end of file +# Primitive-Collections (To be Renamed) + +This is a Simple Primitive Collections Library i started as a hobby Project. +It's basis is of FastUtil and Java's Collection Library +But both lib's have a lot of problems, and in FastUtils case foundation seem changes to be no longer possible. +So this project was started. +With a Rule-Sheet, and also hopefully more Test-Coverage. + +Currently Cons against FastUtil (will/might change over time). +- No Maps, this is next on the todolist. +- No Singletons, +- No BigLists/Sets/Maps +- No Custom Spliterator support. +- No Reference Collections. +- Some implementations are slower due to not including all Micro-optimizations (this might not change) +- Not as Specific Case Testing compared to FastUtil +- No Java Serialization implemented +- Code Generator is right now not finalized and no automatic setup exists as of this moment. + +Pros against FastUtil +- A Cleaner implementation of Collections that do exists: NavigableSet (Exists), PriorityQueues are Save-able outside of java Serialization and a lot of others. +- More Consistency with features, not leaving a lot of holes in implementations. (Anything outside of HashMaps/Lists have massive holes) +- Abstract Tests to allow more coverage on tests and allow quicker implementation on tests on new Implementations. +- A lot better packaging where each types have their own packages to also make it easier to use the library. (lists/sets/collections/queues/utils) +- Due to package name choice: This Library imports do not overshadow java imports. (Anything after s is overshadowed) +- No Linux Environment necessary to generate the sourcecode if you want to work on it. All done with Java and or Gradle. +- A lot of extra functions that become useful in some cases, like: ITrimmable, IArray, extractElements(from, to), moveToFirst/Last, PriorityQueue iterator. Better Synchronization wrappers that expose useful interfaces. +- More Control how internals work thanks to SanityChecks +- Support to some extend of a Java Specific Feature: Non-TypeSepcific Collection Non Delete functions. (any method that used Object as Parameter instead of Generic) + +This Library also includes my own MergeSort Algorithm that does not need to duplicate the input array. +It is a bit slower depending on the size, but is a stable sort that does not require to duplicate an array \ No newline at end of file diff --git a/build.gradle b/build.gradle index 2b035101..44cd562f 100644 --- a/build.gradle +++ b/build.gradle @@ -1,26 +1,30 @@ -plugins { - id 'java-library' -} - -tasks.withType(JavaCompile) { - options.encoding = 'UTF-8' -} - -eclipse { - classpath { - downloadJavadoc = true - downloadSources = true - } -} - -repositories { - jcenter() - flatDir { - dirs '/libs' - } -} - -dependencies { - compile 'SimpleCodeGenerator:Simple Code Generator:1.0' - testImplementation 'junit:junit:4.12' -} +plugins { + id 'java-library' +} + +tasks.withType(JavaCompile) { + options.encoding = 'UTF-8' +} + +eclipse { + classpath { + downloadJavadoc = true + downloadSources = true + } +} + +repositories { + jcenter() + flatDir { + dirs '/libs' + } +} + +dependencies { + compile 'SimpleCodeGenerator:Simple Code Generator:1.0.1' + testImplementation 'junit:junit:4.12' +} + +test { + useJUnit() +} \ No newline at end of file diff --git a/libs/Simple Code Generator-1.0-sources.jar b/libs/Simple Code Generator-1.0-sources.jar deleted file mode 100644 index 0cc54335..00000000 Binary files a/libs/Simple Code Generator-1.0-sources.jar and /dev/null differ diff --git a/libs/Simple Code Generator-1.0.1-sources.jar b/libs/Simple Code Generator-1.0.1-sources.jar new file mode 100644 index 00000000..3033ef5d Binary files /dev/null and b/libs/Simple Code Generator-1.0.1-sources.jar differ diff --git a/libs/Simple Code Generator-1.0.1.jar b/libs/Simple Code Generator-1.0.1.jar new file mode 100644 index 00000000..e21ac446 Binary files /dev/null and b/libs/Simple Code Generator-1.0.1.jar differ diff --git a/libs/Simple Code Generator-1.0.jar b/libs/Simple Code Generator-1.0.jar deleted file mode 100644 index 7fca31fd..00000000 Binary files a/libs/Simple Code Generator-1.0.jar and /dev/null differ diff --git a/src/main/java/speiger/src/builder/example/GlobalVariables.java b/src/main/java/speiger/src/builder/example/GlobalVariables.java index 3f982fa3..05fc9249 100644 --- a/src/main/java/speiger/src/builder/example/GlobalVariables.java +++ b/src/main/java/speiger/src/builder/example/GlobalVariables.java @@ -8,6 +8,7 @@ import java.util.Set; import java.util.function.UnaryOperator; import speiger.src.builder.mappers.ArgumentMapper; +import speiger.src.builder.mappers.IMapper; import speiger.src.builder.mappers.InjectMapper; import speiger.src.builder.mappers.LineMapper; import speiger.src.builder.mappers.SimpleMapper; @@ -15,7 +16,7 @@ import speiger.src.builder.processor.TemplateProcess; public class GlobalVariables { - List> operators = new ArrayList<>(); + List operators = new ArrayList<>(); Set flags = new LinkedHashSet<>(); ClassType type; @@ -42,13 +43,12 @@ public class GlobalVariables addSimpleMapper("JAVA_TYPE", type.getCustomJDKType().getKeyType()); addSimpleMapper("SANITY_CAST", "castTo"+type.getFileType()); } + addAnnontion("@PrimitiveOverride", "@Override"); addSimpleMapper("@PrimitiveDoc", ""); - addDeprication("@Primitive"); + addAnnontion("@Primitive", "@Deprecated"); return this; } - - public GlobalVariables createHelperVariables() { addArgumentMapper("EQUALS_KEY_TYPE", type.isObject() ? "Objects.equals(%2$s, %1$s)" : "Objects.equals(%2$s, KEY_TO_OBJ(%1$s))").removeBraces(); @@ -63,7 +63,10 @@ public class GlobalVariables addInjectMapper("CLASS_TO_KEY", "(("+type.getClassType()+")%s)."+type.getKeyType()+"Value()").removeBraces(); addSimpleMapper("APPLY", "applyAs"+type.getCustomJDKType().getNonFileType()); addInjectMapper("TO_HASH", type.isObject() ? "%s.hashCode()" : type.getClassType()+".hashCode(%s)").removeBraces(); + addSimpleMapper("CAST_KEY_ARRAY ", type.isObject() ? "(KEY_TYPE[])" : ""); + addSimpleMapper("EMPTY_KEY_ARRAY", type.isObject() ? "(KEY_TYPE[])ARRAYS.EMPTY_ARRAY" : "ARRAYS.EMPTY_ARRAY"); addInjectMapper("NEW_KEY_ARRAY", type.isObject() ? "(KEY_TYPE[])new Object[%s]" : "new KEY_TYPE[%s]").removeBraces(); + addInjectMapper("NEW_CLASS_ARRAY", type.isObject() ? "(CLASS_TYPE[])new Object[%s]" : "new CLASS_TYPE[%s]").removeBraces(); return this; } @@ -75,6 +78,9 @@ public class GlobalVariables //Final Classes addClassMapper("ARRAY_LIST", "ArrayList"); + addClassMapper("ARRAY_FIFO_QUEUE", "ArrayFIFOQueue"); + addClassMapper("ARRAY_PRIORITY_QUEUE", "ArrayPriorityQueue"); + addClassMapper("HEAP_PRIORITY_QUEUE", "HeapPriorityQueue"); addClassMapper("LINKED_CUSTOM_HASH_SET", "LinkedOpenCustomHashSet"); addClassMapper("LINKED_HASH_SET", "LinkedOpenHashSet"); addClassMapper("CUSTOM_HASH_SET", "OpenCustomHashSet"); @@ -105,6 +111,8 @@ public class GlobalVariables addClassMapper("LIST_ITER", "ListIter"); addClassMapper("LIST", "List"); addClassMapper("NAVIGABLE_SET", "NavigableSet"); + addClassMapper("PRIORITY_QUEUE", "PriorityQueue"); + addClassMapper("PRIORITY_DEQUEUE", "PriorityDequeue"); addClassMapper("SORTED_SET", "SortedSet"); addClassMapper("SET", "Set"); addClassMapper("STRATEGY", "Strategy"); @@ -129,7 +137,12 @@ public class GlobalVariables addFunctionMapper("NEXT", "next"); addSimpleMapper("TO_ARRAY", "to"+type.getNonFileType()+"Array"); addFunctionMapper("GET_KEY", "get"); + addFunctionMapper("ENQUEUE_FIRST", "enqueueFirst"); + addFunctionMapper("ENQUEUE", "enqueue"); + addFunctionMapper("DEQUEUE_LAST", "dequeueLast"); + addFunctionMapper("DEQUEUE", "dequeue"); addFunctionMapper("REMOVE_KEY", "rem"); + addFunctionMapper("REMOVE_LAST", "removeLast"); addFunctionMapper("REMOVE", "remove"); addFunctionMapper("PREVIOUS", "previous"); addFunctionMapper("PEEK", "peek"); @@ -175,38 +188,38 @@ public class GlobalVariables private void addClassMapper(String pattern, String replacement) { - operators.add(new SimpleMapper(pattern, type.getFileType()+replacement)); + operators.add(new SimpleMapper(type.name()+"["+pattern+"]", pattern, type.getFileType()+replacement)); } private void addAbstractMapper(String pattern, String replacement) { - operators.add(new SimpleMapper(pattern, String.format(replacement, type.getFileType()))); + operators.add(new SimpleMapper(type.name()+"["+pattern+"]", pattern, String.format(replacement, type.getFileType()))); } private void addFunctionMapper(String pattern, String replacement) { - operators.add(new SimpleMapper(pattern, replacement+type.getNonFileType())); + operators.add(new SimpleMapper(type.name()+"["+pattern+"]", pattern, replacement+type.getNonFileType())); } private void addFunctionMappers(String pattern, String replacement) { - operators.add(new SimpleMapper(pattern, String.format(replacement, type.getNonFileType()))); + operators.add(new SimpleMapper(type.name()+"["+pattern+"]", pattern, String.format(replacement, type.getNonFileType()))); } private void addSimpleMapper(String pattern, String replacement) { - operators.add(new SimpleMapper(pattern, replacement)); + operators.add(new SimpleMapper(type.name()+"["+pattern+"]", pattern, replacement)); } - private void addDeprication(String pattern) + private void addAnnontion(String pattern, String value) { - if(type == ClassType.OBJECT) operators.add(new LineMapper(pattern)); - else operators.add(new SimpleMapper(pattern, "@Deprecated")); + if(type == ClassType.OBJECT) operators.add(new LineMapper(type.name()+"["+pattern+"]", pattern)); + else operators.add(new SimpleMapper(type.name()+"["+pattern+"]", pattern, value)); } private InjectMapper addInjectMapper(String pattern, String replacement) { - InjectMapper mapper = new InjectMapper(pattern, replacement); + InjectMapper mapper = new InjectMapper(type.name()+"["+pattern+"]", pattern, replacement); operators.add(mapper); return mapper; } @@ -218,7 +231,7 @@ public class GlobalVariables private ArgumentMapper addArgumentMapper(String pattern, String replacement, String splitter) { - ArgumentMapper mapper = new ArgumentMapper(pattern, replacement, splitter); + ArgumentMapper mapper = new ArgumentMapper(type.name()+"["+pattern+"]", pattern, replacement, splitter); operators.add(mapper); return mapper; } diff --git a/src/main/java/speiger/src/builder/example/TestBuilder.java b/src/main/java/speiger/src/builder/example/TestBuilder.java index 1ac536ed..433a8828 100644 --- a/src/main/java/speiger/src/builder/example/TestBuilder.java +++ b/src/main/java/speiger/src/builder/example/TestBuilder.java @@ -37,6 +37,12 @@ public class TestBuilder extends TemplateProcessor return true; } + @Override + protected boolean debugUnusedMappers() + { + return false; + } + @Override protected void init() { @@ -55,20 +61,19 @@ public class TestBuilder extends TemplateProcessor nameRemapper.put("AbstractCollection", "Abstract%sCollection"); nameRemapper.put("AbstractSet", "Abstract%sSet"); nameRemapper.put("AbstractList", "Abstract%sList"); - blocked.put("Consumer", EnumSet.of(ClassType.OBJECT)); - blocked.put("Comparator", EnumSet.of(ClassType.OBJECT)); - blocked.put("Stack", EnumSet.of(ClassType.OBJECT)); - blocked.put("Sets", EnumSet.of(ClassType.BOOLEAN)); - blocked.put("ArraySet", EnumSet.of(ClassType.BOOLEAN)); - blocked.put("AVLTreeSet", EnumSet.of(ClassType.BOOLEAN)); - blocked.put("RBTreeSet", EnumSet.of(ClassType.BOOLEAN)); - blocked.put("RBTreeSet", EnumSet.of(ClassType.BOOLEAN)); - blocked.put("SortedSet", EnumSet.of(ClassType.BOOLEAN)); - blocked.put("NavigableSet", EnumSet.of(ClassType.BOOLEAN)); - blocked.put("OpenHashSet", EnumSet.of(ClassType.BOOLEAN)); - blocked.put("OpenCustomHashSet", EnumSet.of(ClassType.BOOLEAN)); - blocked.put("LinkedOpenHashSet", EnumSet.of(ClassType.BOOLEAN)); - blocked.put("LinkedOpenCustomHashSet", EnumSet.of(ClassType.BOOLEAN)); + addBlockage(ClassType.OBJECT, "Consumer", "Comparator", "Stack"); + addBlockage(ClassType.BOOLEAN, "Sets", "ArraySet", "AVLTreeSet", "RBTreeSet", "SortedSet", "NavigableSet", "OpenHashSet", "OpenCustomHashSet", "LinkedOpenHashSet", "LinkedOpenCustomHashSet"); + } + + protected void addBlockage(ClassType type, String...args) { + for(String s : args) { + EnumSet set = blocked.get(s); + if(set == null) { + set = EnumSet.noneOf(ClassType.class); + blocked.put(s, set); + } + set.add(type); + } } @Override @@ -89,7 +94,7 @@ public class TestBuilder extends TemplateProcessor { try { - new TestBuilder().process(false); + new TestBuilder().process(false); } catch(InterruptedException e) { diff --git a/src/main/resources/speiger/assets/collections/templates/collections/AbstractCollection.template b/src/main/resources/speiger/assets/collections/templates/collections/AbstractCollection.template index 21e0b64e..8a0b0f20 100644 --- a/src/main/resources/speiger/assets/collections/templates/collections/AbstractCollection.template +++ b/src/main/resources/speiger/assets/collections/templates/collections/AbstractCollection.template @@ -27,9 +27,7 @@ public abstract class ABSTRACT_COLLECTION KEY_GENERIC_TYPE extends AbstractColle @Override public boolean addAll(COLLECTION KEY_GENERIC_TYPE c) { boolean modified = false; - for(KEY_TYPE e : c) { - modified |= add(e); - } + for(ITERATOR KEY_GENERIC_TYPE iter = c.iterator();iter.hasNext();modified |= add(iter.NEXT())); return modified; } @@ -49,7 +47,7 @@ public abstract class ABSTRACT_COLLECTION KEY_GENERIC_TYPE extends AbstractColle */ @Override public boolean contains(KEY_TYPE e) { - for(KEY_TYPE entry : this) { if(EQUALS(entry, e)) return true; } + for(ITERATOR KEY_GENERIC_TYPE iter = iterator();iter.hasNext();) { if(EQUALS(iter.NEXT(), e)) return true; } return false; } @@ -75,8 +73,8 @@ public abstract class ABSTRACT_COLLECTION KEY_GENERIC_TYPE extends AbstractColle @Override public boolean containsAll(COLLECTION KEY_GENERIC_TYPE c) { Objects.requireNonNull(c); - for(KEY_TYPE e : c) - if(!contains(e)) + for(ITERATOR KEY_GENERIC_TYPE iter = c.iterator();iter.hasNext();) + if(!contains(iter.NEXT())) return false; return true; } @@ -107,8 +105,8 @@ public abstract class ABSTRACT_COLLECTION KEY_GENERIC_TYPE extends AbstractColle @Override public boolean containsAny(COLLECTION KEY_GENERIC_TYPE c) { Objects.requireNonNull(c); - for(KEY_TYPE e : c) - if(contains(e)) + for(ITERATOR KEY_GENERIC_TYPE iter = c.iterator();iter.hasNext();) + if(contains(iter.NEXT())) return true; return false; } diff --git a/src/main/resources/speiger/assets/collections/templates/lists/AbstractList.template b/src/main/resources/speiger/assets/collections/templates/lists/AbstractList.template index dce61f00..956b1203 100644 --- a/src/main/resources/speiger/assets/collections/templates/lists/AbstractList.template +++ b/src/main/resources/speiger/assets/collections/templates/lists/AbstractList.template @@ -43,8 +43,7 @@ public abstract class ABSTRACT_LIST KEY_GENERIC_TYPE extends ABSTRACT_COLLECTION @Override public boolean addAll(COLLECTION KEY_GENERIC_TYPE c) { boolean modified = false; - for(KEY_TYPE e : c) - modified |= add(e); + for(ITERATOR KEY_GENERIC_TYPE iter = c.iterator();iter.hasNext();modified |= add(iter.NEXT())); return modified; } @@ -56,8 +55,7 @@ public abstract class ABSTRACT_LIST KEY_GENERIC_TYPE extends ABSTRACT_COLLECTION @Override public boolean addAll(LIST KEY_GENERIC_TYPE c) { boolean modified = false; - for(KEY_TYPE e : c) - modified |= add(e); + for(ITERATOR KEY_GENERIC_TYPE iter = c.iterator();iter.hasNext();modified |= add(iter.NEXT())); return modified; } diff --git a/src/main/resources/speiger/assets/collections/templates/lists/ArrayList.template b/src/main/resources/speiger/assets/collections/templates/lists/ArrayList.template index 5a80a8bb..5e7a3d07 100644 --- a/src/main/resources/speiger/assets/collections/templates/lists/ArrayList.template +++ b/src/main/resources/speiger/assets/collections/templates/lists/ArrayList.template @@ -65,11 +65,7 @@ public class ARRAY_LIST KEY_GENERIC_TYPE extends ABSTRACT_LIST KEY_GENERIC_TYPE * Creates a new ArrayList with a Empty array. */ public ARRAY_LIST() { -#if TYPE_OBJECT - data = (KEY_TYPE[])ARRAYS.EMPTY_ARRAY; -#else - data = ARRAYS.EMPTY_ARRAY; -#endif + data = EMPTY_KEY_ARRAY; } /** @@ -880,11 +876,7 @@ public class ARRAY_LIST KEY_GENERIC_TYPE extends ABSTRACT_LIST KEY_GENERIC_TYPE public boolean trim(int size) { if(size > size() || size() == data.length) return false; int value = Math.max(size, size()); -#if TYPE_OBJECT - data = value == 0 ? (KEY_TYPE[])ARRAYS.EMPTY_ARRAY : Arrays.copyOf(data, value); -#else - data = value == 0 ? ARRAYS.EMPTY_ARRAY : Arrays.copyOf(data, value); -#endif + data = value == 0 ? EMPTY_KEY_ARRAY : Arrays.copyOf(data, value); return true; } diff --git a/src/main/resources/speiger/assets/collections/templates/queues/ArrayFIFOQueue.template b/src/main/resources/speiger/assets/collections/templates/queues/ArrayFIFOQueue.template new file mode 100644 index 00000000..c7aa2c0b --- /dev/null +++ b/src/main/resources/speiger/assets/collections/templates/queues/ArrayFIFOQueue.template @@ -0,0 +1,275 @@ +package speiger.src.collections.PACKAGE.queues; + +#if TYPE_OBJECT +import java.util.Arrays; +import java.util.Comparator; +#endif +import java.util.NoSuchElementException; + +import speiger.src.collections.PACKAGE.collections.ITERATOR; +#if !TYPE_OBJECT +import speiger.src.collections.PACKAGE.functions.COMPARATOR; +#endif +import speiger.src.collections.utils.ITrimmable; + +public class ARRAY_FIFO_QUEUE KEY_GENERIC_TYPE implements PRIORITY_DEQUEUE KEY_GENERIC_TYPE, ITrimmable +{ + private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8; + public static final int MIN_CAPACITY = 4; + protected transient KEY_TYPE[] array; + protected int first; + protected int last; + + public ARRAY_FIFO_QUEUE(KEY_TYPE[] values) { + this(values, 0, values.length); + } + + public ARRAY_FIFO_QUEUE(KEY_TYPE[] values, int size) { + this(values, 0, 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(1); + array = values; + first = offset; + last = (offset + size) % array.length; + if(array.length == size) expand(); + } + + public ARRAY_FIFO_QUEUE(int capacity) { + if (capacity < 0) throw new IllegalArgumentException("Initial capacity (" + capacity + ") is negative"); + array = NEW_KEY_ARRAY(Math.max(1, capacity)); + } + + 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 TYPE_OBJECT + Arrays.fill(array, null); +#endif + first = last = 0; + } + + @Override + public void ENQUEUE(KEY_TYPE e) { + array[last] = e; + last = ++last % array.length; + if(last == first) expand(); + } + + @Override + public void ENQUEUE_FIRST(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 + first = ++first % array.length; + reduce(); + return data; + } + + @Override + public KEY_TYPE DEQUEUE_LAST() { + 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(); + return array[(first + index) % array.length]; + } + + @Override + public boolean REMOVE(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 COMPARATOR KEY_SUPER_GENERIC_TYPE comparator() { return null; } + + @Override + public boolean trim(int size) { + int newSize = Math.max(size, size()); + if(newSize >= 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; + } + + @Override + public KEY_TYPE[] TO_ARRAY(KEY_TYPE[] input) { + if(input == null || input.length < size()) input = NEW_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; + } + +#if !TYPE_OBJECT + @Override + public CLASS_TYPE[] toArray(CLASS_TYPE[] input) { + if(input == null || input.length < size()) input = NEW_CLASS_ARRAY(size()); + if (first <= last) { + for(int i = 0,m=last-first;i MIN_CAPACITY && size <= array.length / 4) resize(size, array.length / 2); + } + + 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() { + KEY_TYPE value = array[index]; + removeIndex(index++); + return value; + } + } +} \ No newline at end of file diff --git a/src/main/resources/speiger/assets/collections/templates/queues/ArrayPriorityQueue.template b/src/main/resources/speiger/assets/collections/templates/queues/ArrayPriorityQueue.template new file mode 100644 index 00000000..a7b9c74e --- /dev/null +++ b/src/main/resources/speiger/assets/collections/templates/queues/ArrayPriorityQueue.template @@ -0,0 +1,220 @@ +package speiger.src.collections.PACKAGE.queues; + +import java.util.Arrays; +import java.util.NoSuchElementException; +#if TYPE_OBJECT +import java.util.Comparator; +import java.util.Objects; +#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; +#endif +import speiger.src.collections.PACKAGE.utils.ARRAYS; + +public class ARRAY_PRIORITY_QUEUE KEY_GENERIC_TYPE implements PRIORITY_QUEUE KEY_GENERIC_TYPE +{ + protected transient KEY_TYPE[] array = EMPTY_KEY_ARRAY; + protected int size; + protected int firstIndex = -1; + protected COMPARATOR KEY_SUPER_GENERIC_TYPE comparator; + + public ARRAY_PRIORITY_QUEUE() { + this(0, null); + } + + public ARRAY_PRIORITY_QUEUE(COMPARATOR KEY_SUPER_GENERIC_TYPE comp) { + this(0, comp); + } + + public ARRAY_PRIORITY_QUEUE(int size, COMPARATOR KEY_SUPER_GENERIC_TYPE comp) { + if(size > 0) array = NEW_KEY_ARRAY(size); + this.size = size; + comparator = comp; + } + + public ARRAY_PRIORITY_QUEUE(KEY_TYPE[] array) { + this(array, array.length); + } + + public ARRAY_PRIORITY_QUEUE(KEY_TYPE[] array, int size) { + this.array = Arrays.copyOf(array, size); + this.size = size; + } + + public ARRAY_PRIORITY_QUEUE(KEY_TYPE[] array, COMPARATOR KEY_SUPER_GENERIC_TYPE comp) { + this(array, array.length, comp); + } + + 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; + } + + public ARRAY_PRIORITY_QUEUE(COLLECTION KEY_GENERIC_TYPE c) { + array = CAST_KEY_ARRAY c.TO_ARRAY(); + size = c.size(); + } + + 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; + } + + public static GENERIC_BRACES ARRAY_PRIORITY_QUEUE KEY_GENERIC_TYPE wrap(KEY_TYPE[] array) { + return wrap(array, array.length); + } + + public static GENERIC_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; + } + + public static GENERIC_BRACES ARRAY_PRIORITY_QUEUE KEY_GENERIC_TYPE wrap(KEY_TYPE[] array, COMPARATOR KEY_SUPER_GENERIC_TYPE comp) { + return wrap(array, array.length, comp); + } + + public static GENERIC_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, size+1); + if(firstIndex != -1){ + int compare = comparator == null ? COMPARE_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 PEEK(int index) { + if(index < 0 || index >= size) throw new NoSuchElementException(); + return array[index]; + } + + @Override + public boolean REMOVE(KEY_TYPE e) { + for(int i = 0;i=0;i--) + if(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(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 ITERATOR KEY_GENERIC_TYPE iterator() { + return new Iter(); + } + + @Override + public COMPARATOR KEY_SUPER_GENERIC_TYPE comparator() { + return comparator; + } + + @Override + public KEY_TYPE[] TO_ARRAY(KEY_TYPE[] input) { + if(input == null || input.length < size()) input = NEW_KEY_ARRAY(size()); + System.arraycopy(array, 0, input, 0, size()); + return input; + } + +#if !TYPE_OBJECT + @Override + public CLASS_TYPE[] toArray(CLASS_TYPE[] input) { + if(input == null || input.length < size()) input = new CLASS_TYPE[size()]; + for(int i = 0;i=0;i--) { + if(COMPARE_TO_KEY(array[i], value) < 0) + value = array[index = i]; + } + } + else { + for(int i = index;firstIndex == -1 && i>=0;i--) { + if(comparator.compare(array[i], value) < 0) + value = array[index = i]; + } + } + firstIndex = index; + } + return firstIndex; + } + + public class Iter implements ITERATOR KEY_GENERIC_TYPE { + @Override + public boolean hasNext() { + return !isEmpty(); + } + + @Override + public KEY_TYPE NEXT() { + return DEQUEUE(); + } + } +} \ No newline at end of file diff --git a/src/main/resources/speiger/assets/collections/templates/queues/HeapPriorityQueue.template b/src/main/resources/speiger/assets/collections/templates/queues/HeapPriorityQueue.template new file mode 100644 index 00000000..41fbb903 --- /dev/null +++ b/src/main/resources/speiger/assets/collections/templates/queues/HeapPriorityQueue.template @@ -0,0 +1,199 @@ +package speiger.src.collections.PACKAGE.queues; + +import java.util.Arrays; +import java.util.NoSuchElementException; +#if TYPE_OBJECT +import java.util.Comparator; +import java.util.Objects; +#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; +#endif +import speiger.src.collections.PACKAGE.utils.ARRAYS; + +public class HEAP_PRIORITY_QUEUE KEY_GENERIC_TYPE implements PRIORITY_QUEUE KEY_GENERIC_TYPE +{ + protected transient KEY_TYPE[] array = EMPTY_KEY_ARRAY; + protected int size; + protected COMPARATOR KEY_SUPER_GENERIC_TYPE comparator; + + public HEAP_PRIORITY_QUEUE() { + this(0, null); + } + + public HEAP_PRIORITY_QUEUE(COMPARATOR KEY_SUPER_GENERIC_TYPE comp) { + this(0, comp); + } + + public HEAP_PRIORITY_QUEUE(int size, COMPARATOR KEY_SUPER_GENERIC_TYPE comp) { + if(size > 0) array = NEW_KEY_ARRAY(size); + this.size = size; + comparator = comp; + } + + public HEAP_PRIORITY_QUEUE(KEY_TYPE[] array) { + this(array, array.length); + } + + public HEAP_PRIORITY_QUEUE(KEY_TYPE[] array, int size) { + this.array = Arrays.copyOf(array, size); + this.size = size; + ARRAYS.heapify(array, size, null); + } + + public HEAP_PRIORITY_QUEUE(KEY_TYPE[] array, COMPARATOR KEY_SUPER_GENERIC_TYPE comp) { + this(array, array.length, comp); + } + + 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); + } + + public HEAP_PRIORITY_QUEUE(COLLECTION KEY_GENERIC_TYPE c) { + array = CAST_KEY_ARRAY c.TO_ARRAY(); + size = c.size(); + ARRAYS.heapify(array, size, 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); + } + + public static GENERIC_BRACES HEAP_PRIORITY_QUEUE KEY_GENERIC_TYPE wrap(KEY_TYPE[] array) { + return wrap(array, array.length); + } + + public static GENERIC_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; + } + + public static GENERIC_BRACES HEAP_PRIORITY_QUEUE KEY_GENERIC_TYPE wrap(KEY_TYPE[] array, COMPARATOR KEY_SUPER_GENERIC_TYPE comp) { + return wrap(array, array.length, comp); + } + + public static GENERIC_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, 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 REMOVE(KEY_TYPE e) { + for(int i = 0;i=0;i--) + if(EQUALS(e, array[i])) return removeIndex(i); + return false; + } + + protected boolean removeIndex(int index) { + array[index] = array[--size]; +#if TYPE_OBJECT + array[size] = null; +#endif + if(size != index) ARRAYS.shiftDown(array, size, index, comparator); + return true; + } + + @Override + public void onChanged() { + if(size <= 0) return; + ARRAYS.shiftDown(array, size, 0, comparator); + } + + @Override + public COMPARATOR KEY_SUPER_GENERIC_TYPE comparator() { + return comparator; + } + + @Override + public KEY_TYPE[] TO_ARRAY(KEY_TYPE[] input) { + if(input == null || input.length < size()) input = NEW_KEY_ARRAY(size()); + System.arraycopy(array, 0, input, 0, size()); + return input; + } + +#if !TYPE_OBJECT + @Override + public CLASS_TYPE[] toArray(CLASS_TYPE[] input) { + if(input == null || input.length < size()) input = new CLASS_TYPE[size()]; + for(int i = 0;i +#else +public interface PRIORITY_QUEUE KEY_GENERIC_TYPE extends ObjectPriorityQueue, ITERABLE KEY_GENERIC_TYPE +#endif +{ +#if TYPE_OBJECT + public default boolean isEmpty() { return size() <= 0; } + public int size(); + public void clear(); + +#endif + public void ENQUEUE(KEY_TYPE e); + public KEY_TYPE DEQUEUE(); + + public KEY_TYPE PEEK(int index); + public default KEY_TYPE FIRST_KEY() { return peek(0); } + public default KEY_TYPE LAST_KEY() { return peek(size()-1); } + + public boolean REMOVE(KEY_TYPE e); + public boolean REMOVE_LAST(KEY_TYPE e); + + public void onChanged(); + + @PrimitiveOverride + public COMPARATOR KEY_SUPER_GENERIC_TYPE comparator(); + + public default KEY_TYPE[] TO_ARRAY() { return TO_ARRAY(NEW_KEY_ARRAY(size())); } + public KEY_TYPE[] TO_ARRAY(KEY_TYPE[] input); + +#if !TYPE_OBJECT + public default void enqueue(CLASS_TYPE e) { ENQUEUE(OBJ_TO_KEY(e)); } + public default CLASS_TYPE dequeue() { return KEY_TO_OBJ(DEQUEUE()); } + + public default CLASS_TYPE peek(int index) { return KEY_TO_OBJ(PEEK(index)); } + public default CLASS_TYPE first() { return peek(0); } + public default CLASS_TYPE last() { return peek(size()-1); } + + public default boolean remove(CLASS_TYPE e) { return REMOVE(OBJ_TO_KEY(e)); } + public default boolean removeLast(CLASS_TYPE e) { return REMOVE_LAST(OBJ_TO_KEY(e)); } + + @Deprecated + public default CLASS_TYPE[] toArray() { return toArray(new CLASS_TYPE[size()]); } + @Deprecated + public CLASS_TYPE[] toArray(CLASS_TYPE[] input); + +#endif +} diff --git a/src/main/resources/speiger/assets/collections/templates/sets/AbstractSet.template b/src/main/resources/speiger/assets/collections/templates/sets/AbstractSet.template index d0730f33..73694be3 100644 --- a/src/main/resources/speiger/assets/collections/templates/sets/AbstractSet.template +++ b/src/main/resources/speiger/assets/collections/templates/sets/AbstractSet.template @@ -14,11 +14,7 @@ public abstract class ABSTRACT_SET KEY_GENERIC_TYPE extends ABSTRACT_COLLECTION int hashCode = 1; ITERATOR KEY_GENERIC_TYPE i = iterator(); while(i.hasNext()) -#if TYPE_OBJECT - hashCode = 31 * hashCode + i.next().hashCode(); -#else hashCode = 31 * hashCode + TO_HASH(i.NEXT()); -#endif return hashCode; } diff --git a/src/main/resources/speiger/assets/collections/templates/sets/ArraySet.template b/src/main/resources/speiger/assets/collections/templates/sets/ArraySet.template index 3d9ce424..8e7f7898 100644 --- a/src/main/resources/speiger/assets/collections/templates/sets/ArraySet.template +++ b/src/main/resources/speiger/assets/collections/templates/sets/ArraySet.template @@ -23,11 +23,7 @@ public class ARRAY_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_TYPE im protected int size = 0; public ARRAY_SET() { -#if TYPE_OBJECT - data = (KEY_TYPE[])ARRAYS.EMPTY_ARRAY; -#else - data = ARRAYS.EMPTY_ARRAY; -#endif + data = EMPTY_KEY_ARRAY; } public ARRAY_SET(int capacity) { diff --git a/src/main/resources/speiger/assets/collections/templates/utils/Arrays.template b/src/main/resources/speiger/assets/collections/templates/utils/Arrays.template index 020c0d68..208a56b1 100644 --- a/src/main/resources/speiger/assets/collections/templates/utils/Arrays.template +++ b/src/main/resources/speiger/assets/collections/templates/utils/Arrays.template @@ -100,12 +100,70 @@ public class ARRAYS * @param length the lenght the array should be. * @return a Array with the requested type and length */ - public static KEY_GENERIC_TYPE KEY_TYPE[] newArray(Class clz, int length) { + public static GENERIC_BRACES KEY_TYPE[] newArray(Class clz, int length) { if(clz == Object.class) return (KEY_TYPE[])new Object[length]; return (KEY_TYPE[]) java.lang.reflect.Array.newInstance(clz, length); } #endif + public static GENERIC_BRACES int shiftDown(KEY_TYPE[] data, int size, int index, COMPARATOR KEY_SUPER_GENERIC_TYPE comp) { + int half = size >>> 1; + KEY_TYPE value = data[index]; + if(comp != null) { + while(index < half) { + int child = (index << 1) + 1; + KEY_TYPE childValue = data[child]; + int right = child+1; + if(right < size && comp.compare(data[right], childValue) < 0) childValue = data[child = right]; + if(comp.compare(value, childValue) <= 0) break; + data[index] = childValue; + index = child; + } + } + else { + while(index < half) { + int child = (index << 1) + 1; + KEY_TYPE childValue = data[child]; + int right = child+1; + if(right < size && COMPARE_TO_KEY(data[right], childValue) < 0) childValue = data[child = right]; + if(COMPARE_TO_KEY(value, childValue) <= 0) break; + data[index] = childValue; + index = child; + } + } + data[index] = value; + return index; + } + + public static GENERIC_BRACES int shiftUp(KEY_TYPE[] data, int index, COMPARATOR KEY_SUPER_GENERIC_TYPE comp) { + KEY_TYPE value = data[index]; + if(comp != null) { + while(index > 0) { + int parent = (index - 1) >>> 1; + KEY_TYPE parentValue = data[parent]; + if(comp.compare(value, parentValue) >= 0) break; + data[index] = parentValue; + index = parent; + } + } + else { + while(index > 0) { + int parent = (index - 1) >>> 1; + KEY_TYPE parentValue = data[parent]; + if(COMPARE_TO_KEY(value, parentValue) >= 0) break; + data[index] = parentValue; + index = parent; + } + } + data[index] = value; + return index; + } + + public static GENERIC_BRACES KEY_TYPE[] heapify(KEY_TYPE[] data, int size, COMPARATOR KEY_SUPER_GENERIC_TYPE comp) { + for(int i = (size >>> 1) - 1;i>=0;shiftDown(data, size, i--, comp)); + return data; + } + public static GENERIC_BRACES KEY_TYPE[] shuffle(KEY_TYPE[] array) { return shuffle(array, SanityChecks.getRandom()); } diff --git a/src/test/java/speiger/src/collections/ints/base/BaseIntPriorityQueueTest.java b/src/test/java/speiger/src/collections/ints/base/BaseIntPriorityQueueTest.java new file mode 100644 index 00000000..2b11dbe2 --- /dev/null +++ b/src/test/java/speiger/src/collections/ints/base/BaseIntPriorityQueueTest.java @@ -0,0 +1,114 @@ +package speiger.src.collections.ints.base; + +import static org.junit.Assert.assertArrayEquals; +import static org.junit.Assert.assertEquals; + +import java.util.EnumSet; + +import org.junit.Assert; +import org.junit.Test; + +import speiger.src.collections.ints.queues.IntPriorityQueue; +import speiger.src.collections.tests.IterableTest; +import speiger.src.collections.tests.PriorityQueueTest; + +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); } + + @Test + public void testEnqueue() { + if(getValidPriorityQueueTests().contains(PriorityQueueTest.IN_OUT)) { + IntPriorityQueue queue = create(EMPTY_ARRAY); + for(int i = 0;i<100;i++) { + queue.enqueueInt(i); + Assert.assertEquals(i, queue.lastInt()); + } + for(int i = 0;i<100;i++) { + Assert.assertEquals(i, queue.firstInt()); + Assert.assertEquals(99, queue.lastInt()); + Assert.assertEquals(i, queue.dequeueInt()); + } + } + } + + @Test + public void testPeek() { + if(getValidPriorityQueueTests().contains(PriorityQueueTest.PEEK)) { + IntPriorityQueue queue = create(EMPTY_ARRAY); + for(int i = 0;i<100;i++) { + queue.enqueueInt(i); + Assert.assertEquals(i, queue.lastInt()); + } + for(int i = 0;i<100;i++) { + assertEquals(i, queue.peekInt(i)); + } + } + } + + @Test + public void testRemove() { + if(getValidPriorityQueueTests().contains(PriorityQueueTest.REMOVE)) { + IntPriorityQueue queue = create(EMPTY_ARRAY); + for(int i = 0;i<100;i++) { + queue.enqueueInt(i); + Assert.assertEquals(i, queue.lastInt()); + } + queue.removeInt(40); + for(int i = 0;i<99;i++) { + if(i >= 40) assertEquals(i + 1, queue.dequeueInt()); + else assertEquals(i, queue.dequeueInt()); + } + for(int i = 0;i<100;i++) { + queue.enqueueInt(i); + Assert.assertEquals(i, queue.lastInt()); + } + queue.removeLastInt(40); + for(int i = 0;i<99;i++) { + if(i >= 40) assertEquals(i + 1, queue.dequeueInt()); + else assertEquals(i, queue.dequeueInt()); + } + } + } + + @Test + @SuppressWarnings("deprecation") + public void testToArray() { + if(getValidPriorityQueueTests().contains(PriorityQueueTest.TO_ARRAY)) { + IntPriorityQueue q = create(EMPTY_ARRAY); + Integer[] ref = new Integer[100]; + Integer[] shiftArray = new Integer[100]; + int[] primRef = new int[100]; + int[] shiftPrimArray = new int[100]; + for(int i = 0; i < 100; i++) { + q.enqueue(i); + assertEquals(i, q.lastInt()); + ref[i] = Integer.valueOf(i); + primRef[i] = i; + shiftPrimArray[(i+80) % 100] = i; + shiftArray[(i+80) % 100] = Integer.valueOf(i); + } + assertArrayEquals(q.toArray(), ref); + assertArrayEquals(q.toArray(new Integer[100]), ref); + assertArrayEquals(q.toArray(null), ref); + assertArrayEquals(q.toIntArray(), primRef); + assertArrayEquals(q.toIntArray(new int[100]), primRef); + assertArrayEquals(q.toIntArray(null), primRef); + IntPriorityQueue other = create(q.toIntArray()); + for(int i = 0;i<100;i++) { + assertEquals(other.peekInt(i), primRef[i]); + } + for(int i = 0;i<20;i++) { + other.dequeueInt(); + other.enqueue(i); + } + assertArrayEquals(other.toIntArray(), shiftPrimArray); + assertArrayEquals(other.toIntArray(new int[100]), shiftPrimArray); + assertArrayEquals(other.toArray(), shiftArray); + } + } +} diff --git a/src/test/java/speiger/src/collections/ints/queues/IntArrayFIFOQueueTests.java b/src/test/java/speiger/src/collections/ints/queues/IntArrayFIFOQueueTests.java new file mode 100644 index 00000000..1dff9547 --- /dev/null +++ b/src/test/java/speiger/src/collections/ints/queues/IntArrayFIFOQueueTests.java @@ -0,0 +1,9 @@ +package speiger.src.collections.ints.queues; + +import speiger.src.collections.ints.base.BaseIntPriorityQueueTest; + +public class IntArrayFIFOQueueTests extends BaseIntPriorityQueueTest +{ + @Override + protected IntPriorityQueue create(int[] data){return new IntArrayFIFOQueue(data);} +} diff --git a/src/test/java/speiger/src/collections/tests/PriorityQueueTest.java b/src/test/java/speiger/src/collections/tests/PriorityQueueTest.java new file mode 100644 index 00000000..755d1801 --- /dev/null +++ b/src/test/java/speiger/src/collections/tests/PriorityQueueTest.java @@ -0,0 +1,9 @@ +package speiger.src.collections.tests; + +public enum PriorityQueueTest +{ + IN_OUT, + PEEK, + REMOVE, + TO_ARRAY, +} \ No newline at end of file