New Features and bugfixes.

- Fixed: AbstractCollection bulk adding methods now link to the
specialized implementations.
- Fixed: A bug with getElements in ArrayList.
- Fixed: PriorityQueue remove/toArray function were renamed so they fit
better with other interfaces. (remove => removeFirst and toArray uses a
different genericType)
- Added: LinkedList which is a List/PriorityDequeue/Stack which allows
for more optimized use-cases and reduced boxing/unboxing.
- Added: Tests for LinkedList
This commit is contained in:
Speiger 2021-08-12 14:31:29 +02:00
parent 73916f4fd9
commit 45d118a77a
13 changed files with 1182 additions and 23 deletions

View File

@ -4,6 +4,11 @@
### Version 0.3.3 ### Version 0.3.3
- Added: Flat/Mapping function for Iterables/Iterators to help avoid streams for cleaner looking code - Added: Flat/Mapping function for Iterables/Iterators to help avoid streams for cleaner looking code
- Fixed: AVLTrees pollFirst/Last is now keeping orders and is fixed - Fixed: AVLTrees pollFirst/Last is now keeping orders and is fixed
- Fixed: AbstractCollection bulk adding methods now link to the specialized implementations.
- Fixed: A bug with getElements in ArrayList.
- Fixed: PriorityQueue remove/toArray function were renamed so they fit better with other interfaces. (remove => removeFirst and toArray uses a different genericType)
- Added: LinkedList which is a List/PriorityDequeue/Stack which allows for more optimized use-cases and reduced boxing/unboxing.
- Added: Tests for LinkedList
### Version 0.3.2 ### Version 0.3.2
- Fixed: Map.put wasn't referring to primitive variants. - Fixed: Map.put wasn't referring to primitive variants.

View File

@ -35,14 +35,18 @@ public class GlobalVariables
addSimpleMapper("CLASS_TYPE", type.getClassType()); addSimpleMapper("CLASS_TYPE", type.getClassType());
addSimpleMapper("CLASS_VALUE_TYPE", valueType.getClassValueType()); addSimpleMapper("CLASS_VALUE_TYPE", valueType.getClassValueType());
addSimpleMapper("KEY_TYPE", type.getKeyType()); addSimpleMapper("KEY_TYPE", type.getKeyType());
addSimpleMapper("KEY_SPECIAL_TYPE", type.isObject() ? "E" : type.getKeyType());
addSimpleMapper("VALUE_TYPE", valueType.getValueType()); addSimpleMapper("VALUE_TYPE", valueType.getValueType());
addSimpleMapper("VALUE_SPECIAL_TYPE", valueType.isObject() ? "E" : valueType.getKeyType());
addSimpleMapper("EMPTY_KEY_VALUE", type.getEmptyValue()); addSimpleMapper("EMPTY_KEY_VALUE", type.getEmptyValue());
addSimpleMapper("EMPTY_VALUE", valueType.getEmptyValue()); addSimpleMapper("EMPTY_VALUE", valueType.getEmptyValue());
addSimpleMapper(" KEY_GENERIC_TYPE", type.isObject() ? "<"+type.getKeyType()+">" : ""); addSimpleMapper(" KEY_GENERIC_TYPE", type.isObject() ? "<"+type.getKeyType()+">" : "");
addSimpleMapper(" KEY_GENERIC_SPECIAL_TYPE", type.isObject() ? " <E>" : "");
addSimpleMapper(" KEY_KEY_GENERIC_TYPE", type.isObject() ? "<"+type.getKeyType()+", "+type.getKeyType()+">" : ""); addSimpleMapper(" KEY_KEY_GENERIC_TYPE", type.isObject() ? "<"+type.getKeyType()+", "+type.getKeyType()+">" : "");
addSimpleMapper(" VALUE_GENERIC_TYPE", valueType.isObject() ? "<"+valueType.getValueType()+">" : ""); addSimpleMapper(" VALUE_GENERIC_TYPE", valueType.isObject() ? "<"+valueType.getValueType()+">" : "");
addSimpleMapper(" VALUE_GENERIC_SPECIAL_TYPE", valueType.isObject() ? " <E>" : "");
addSimpleMapper(" VALUE_VALUE_GENERIC_TYPE", valueType.isObject() ? "<"+valueType.getValueType()+", "+valueType.getValueType()+">" : ""); addSimpleMapper(" VALUE_VALUE_GENERIC_TYPE", valueType.isObject() ? "<"+valueType.getValueType()+", "+valueType.getValueType()+">" : "");
addSimpleMapper(" KEY_VALUE_GENERIC_TYPE", type.isObject() ? (valueType.isObject() ? "<"+type.getKeyType()+", "+valueType.getValueType()+">" : "<"+type.getKeyType()+">") : (valueType.isObject() ? "<"+valueType.getValueType()+">" : "")); addSimpleMapper(" KEY_VALUE_GENERIC_TYPE", type.isObject() ? (valueType.isObject() ? "<"+type.getKeyType()+", "+valueType.getValueType()+">" : "<"+type.getKeyType()+">") : (valueType.isObject() ? "<"+valueType.getValueType()+">" : ""));
addSimpleMapper(" KEY_VALUE_VALUE_GENERIC_TYPE", type.isObject() ? (valueType.isObject() ? "<"+type.getKeyType()+", "+valueType.getValueType()+", "+valueType.getValueType()+">" : "<"+type.getKeyType()+">") : (valueType.isObject() ? "<"+valueType.getValueType()+", "+valueType.getValueType()+">" : "")); addSimpleMapper(" KEY_VALUE_VALUE_GENERIC_TYPE", type.isObject() ? (valueType.isObject() ? "<"+type.getKeyType()+", "+valueType.getValueType()+", "+valueType.getValueType()+">" : "<"+type.getKeyType()+">") : (valueType.isObject() ? "<"+valueType.getValueType()+", "+valueType.getValueType()+">" : ""));
@ -111,6 +115,7 @@ public class GlobalVariables
addSimpleMapper("CAST_"+fix+"_ARRAY ", type.isObject() ? "("+fix+"_TYPE[])" : ""); addSimpleMapper("CAST_"+fix+"_ARRAY ", type.isObject() ? "("+fix+"_TYPE[])" : "");
addSimpleMapper("EMPTY_"+fix+"_ARRAY", type.isObject() ? "("+fix+"_TYPE[])ARRAYS.EMPTY_ARRAY" : "ARRAYS.EMPTY_ARRAY"); addSimpleMapper("EMPTY_"+fix+"_ARRAY", type.isObject() ? "("+fix+"_TYPE[])ARRAYS.EMPTY_ARRAY" : "ARRAYS.EMPTY_ARRAY");
addInjectMapper("NEW_"+fix+"_ARRAY", type.isObject() ? "("+fix+"_TYPE[])new Object[%s]" : "new "+fix+"_TYPE[%s]").removeBraces(); addInjectMapper("NEW_"+fix+"_ARRAY", type.isObject() ? "("+fix+"_TYPE[])new Object[%s]" : "new "+fix+"_TYPE[%s]").removeBraces();
addInjectMapper("NEW_SPECIAL_"+fix+"_ARRAY", type.isObject() ? "(E[])new Object[%s]" : "new "+fix+"_TYPE[%s]").removeBraces();
addInjectMapper("NEW_CLASS"+(value ? "_VALUE" : "")+"_ARRAY", type.isObject() ? "(CLASS_TYPE[])new Object[%s]" : "new CLASS_TYPE[%s]").removeBraces(); addInjectMapper("NEW_CLASS"+(value ? "_VALUE" : "")+"_ARRAY", type.isObject() ? "(CLASS_TYPE[])new Object[%s]" : "new CLASS_TYPE[%s]").removeBraces();
} }
@ -132,6 +137,7 @@ public class GlobalVariables
//Final Classes //Final Classes
addClassMapper("ARRAY_LIST", "ArrayList"); addClassMapper("ARRAY_LIST", "ArrayList");
addClassMapper("LINKED_LIST", "LinkedList");
addAbstractMapper("IMMUTABLE_LIST", "Immutable%sList"); addAbstractMapper("IMMUTABLE_LIST", "Immutable%sList");
addClassMapper("ARRAY_FIFO_QUEUE", "ArrayFIFOQueue"); addClassMapper("ARRAY_FIFO_QUEUE", "ArrayFIFOQueue");
addClassMapper("ARRAY_PRIORITY_QUEUE", "ArrayPriorityQueue"); addClassMapper("ARRAY_PRIORITY_QUEUE", "ArrayPriorityQueue");

View File

@ -43,9 +43,7 @@ public abstract class ABSTRACT_LIST KEY_GENERIC_TYPE extends ABSTRACT_COLLECTION
*/ */
@Override @Override
public boolean addAll(COLLECTION KEY_GENERIC_TYPE c) { public boolean addAll(COLLECTION KEY_GENERIC_TYPE c) {
boolean modified = false; return addAll(size(), c);
for(ITERATOR KEY_GENERIC_TYPE iter = c.iterator();iter.hasNext();modified |= add(iter.NEXT()));
return modified;
} }
/** /**
@ -55,9 +53,18 @@ public abstract class ABSTRACT_LIST KEY_GENERIC_TYPE extends ABSTRACT_COLLECTION
*/ */
@Override @Override
public boolean addAll(LIST KEY_GENERIC_TYPE c) { public boolean addAll(LIST KEY_GENERIC_TYPE c) {
boolean modified = false; return addAll(size(), c);
for(ITERATOR KEY_GENERIC_TYPE iter = c.iterator();iter.hasNext();modified |= add(iter.NEXT())); }
return modified;
/** {@inheritDoc}
* <p>This default implementation delegates to the corresponding type-specific function.
* @deprecated Please use the corresponding type-specific function instead.
*/
@Override
@Deprecated
public boolean addAll(Collection<? extends CLASS_TYPE> c)
{
return c instanceof COLLECTION ? addAll((COLLECTION KEY_GENERIC_TYPE)c) : addAll(size(), c);
} }
/** /**

View File

@ -310,7 +310,8 @@ public class ARRAY_LIST KEY_GENERIC_TYPE extends ABSTRACT_LIST KEY_GENERIC_TYPE
*/ */
@Override @Override
public KEY_TYPE[] getElements(int from, KEY_TYPE[] a, int offset, int length) { public KEY_TYPE[] getElements(int from, KEY_TYPE[] a, int offset, int length) {
SanityChecks.checkArrayCapacity(size, offset, length); SanityChecks.checkArrayCapacity(size, from, length);
SanityChecks.checkArrayCapacity(a.length, offset, length);
System.arraycopy(data, from, a, offset, length); System.arraycopy(data, from, a, offset, length);
return a; return a;
} }
@ -631,6 +632,7 @@ public class ARRAY_LIST KEY_GENERIC_TYPE extends ABSTRACT_LIST KEY_GENERIC_TYPE
*/ */
@Override @Override
public void REPLACE(JAVA_UNARY_OPERATOR o) { public void REPLACE(JAVA_UNARY_OPERATOR o) {
Objects.requireNonNull(o);
for(int i = 0;i<size;i++) for(int i = 0;i<size;i++)
#if TYPE_BYTE || TYPE_SHORT || TYPE_CHAR || TYPE_FLOAT #if TYPE_BYTE || TYPE_SHORT || TYPE_CHAR || TYPE_FLOAT
data[i] = SanityChecks.SANITY_CAST(o.APPLY_CAST(data[i])); data[i] = SanityChecks.SANITY_CAST(o.APPLY_CAST(data[i]));
@ -673,6 +675,15 @@ public class ARRAY_LIST KEY_GENERIC_TYPE extends ABSTRACT_LIST KEY_GENERIC_TYPE
return true; return true;
} }
#else
@Override
public boolean remove(Object type) {
int index = indexOf(type);
if(index == -1) return false;
REMOVE(index);
return true;
}
#endif #endif
/** /**
* A Type-Specific pop function to reduce (un)boxing * A Type-Specific pop function to reduce (un)boxing

View File

@ -145,7 +145,7 @@ public class ARRAY_FIFO_QUEUE KEY_GENERIC_TYPE implements PRIORITY_DEQUEUE KEY_G
} }
@Override @Override
public boolean remove(KEY_TYPE e) { public boolean removeFirst(KEY_TYPE e) {
if(first == last) return false; if(first == last) return false;
for(int i = 0,m=size();i<m;i++) { for(int i = 0,m=size();i<m;i++) {
int index = (first + i) % array.length; int index = (first + i) % array.length;
@ -254,8 +254,8 @@ public class ARRAY_FIFO_QUEUE KEY_GENERIC_TYPE implements PRIORITY_DEQUEUE KEY_G
} }
@Override @Override
public KEY_TYPE[] TO_ARRAY(KEY_TYPE[] input) { public KEY_GENERIC_SPECIAL_TYPE KEY_SPECIAL_TYPE[] TO_ARRAY(KEY_SPECIAL_TYPE[] input) {
if(input == null || input.length < size()) input = NEW_KEY_ARRAY(size()); if(input == null || input.length < size()) input = NEW_SPECIAL_KEY_ARRAY(size());
if (first <= last) System.arraycopy(array, first, input, 0, last - first); if (first <= last) System.arraycopy(array, first, input, 0, last - first);
else { else {
System.arraycopy(array, first, input, 0, array.length - first); System.arraycopy(array, first, input, 0, array.length - first);

View File

@ -210,7 +210,7 @@ public class ARRAY_PRIORITY_QUEUE KEY_GENERIC_TYPE implements PRIORITY_QUEUE KEY
} }
@Override @Override
public boolean remove(KEY_TYPE e) { public boolean removeFirst(KEY_TYPE e) {
for(int i = 0;i<size;i++) for(int i = 0;i<size;i++)
if(KEY_EQUALS(e, array[i])) return removeIndex(i); if(KEY_EQUALS(e, array[i])) return removeIndex(i);
return false; return false;
@ -262,8 +262,8 @@ public class ARRAY_PRIORITY_QUEUE KEY_GENERIC_TYPE implements PRIORITY_QUEUE KEY
} }
@Override @Override
public KEY_TYPE[] TO_ARRAY(KEY_TYPE[] input) { public KEY_GENERIC_SPECIAL_TYPE KEY_SPECIAL_TYPE[] TO_ARRAY(KEY_SPECIAL_TYPE[] input) {
if(input == null || input.length < size()) input = NEW_KEY_ARRAY(size()); if(input == null || input.length < size()) input = NEW_SPECIAL_KEY_ARRAY(size());
System.arraycopy(array, 0, input, 0, size()); System.arraycopy(array, 0, input, 0, size());
return input; return input;
} }

View File

@ -225,7 +225,7 @@ public class HEAP_PRIORITY_QUEUE KEY_GENERIC_TYPE implements PRIORITY_QUEUE KEY_
} }
@Override @Override
public boolean remove(KEY_TYPE e) { public boolean removeFirst(KEY_TYPE e) {
for(int i = 0;i<size;i++) for(int i = 0;i<size;i++)
if(KEY_EQUALS(e, array[i])) return removeIndex(i); if(KEY_EQUALS(e, array[i])) return removeIndex(i);
return false; return false;
@ -259,8 +259,8 @@ public class HEAP_PRIORITY_QUEUE KEY_GENERIC_TYPE implements PRIORITY_QUEUE KEY_
} }
@Override @Override
public KEY_TYPE[] TO_ARRAY(KEY_TYPE[] input) { public KEY_GENERIC_SPECIAL_TYPE KEY_SPECIAL_TYPE[] TO_ARRAY(KEY_SPECIAL_TYPE[] input) {
if(input == null || input.length < size()) input = NEW_KEY_ARRAY(size()); if(input == null || input.length < size()) input = NEW_SPECIAL_KEY_ARRAY(size());
System.arraycopy(array, 0, input, 0, size()); System.arraycopy(array, 0, input, 0, size());
return input; return input;
} }

View File

@ -61,7 +61,7 @@ public interface PRIORITY_QUEUE KEY_GENERIC_TYPE extends ITERABLE KEY_GENERIC_TY
* @param e the element that should be removed * @param e the element that should be removed
* @return if a searched element was removed * @return if a searched element was removed
*/ */
public boolean remove(KEY_TYPE e); public boolean removeFirst(KEY_TYPE e);
/** /**
* Removes the last found element in the queue * Removes the last found element in the queue
* @param e the element that should be removed * @param e the element that should be removed
@ -87,14 +87,16 @@ public interface PRIORITY_QUEUE KEY_GENERIC_TYPE extends ITERABLE KEY_GENERIC_TY
#endif #endif
/** /**
* A method to drop the contents of the Queue without clearing the queue * A method to drop the contents of the Queue without clearing the queue
* @Type(E)
* @return the contents of the queue into a seperate array. * @return the contents of the queue into a seperate array.
*/ */
public default KEY_TYPE[] TO_ARRAY() { return TO_ARRAY(NEW_KEY_ARRAY(size())); } public default KEY_GENERIC_SPECIAL_TYPE KEY_SPECIAL_TYPE[] TO_ARRAY() { return TO_ARRAY(NEW_SPECIAL_KEY_ARRAY(size())); }
/** /**
* A method to drop the contents of the Queue without clearing the queue * A method to drop the contents of the Queue without clearing the queue
* @param input where the elements should be inserted to. If it does not fit then it creates a new appropiatly created array * @param input where the elements should be inserted to. If it does not fit then it creates a new appropiatly created array
* @Type(E)
* @return the contents of the queue into a seperate array. * @return the contents of the queue into a seperate array.
* @note if the Type is generic then a Object Array is created instead of a Type Array * @note if the Type is generic then a Object Array is created instead of a Type Array
*/ */
public KEY_TYPE[] TO_ARRAY(KEY_TYPE[] input); public KEY_GENERIC_SPECIAL_TYPE KEY_SPECIAL_TYPE[] TO_ARRAY(KEY_SPECIAL_TYPE[] input);
} }

View File

@ -2,7 +2,9 @@ package speiger.src.collections.PACKAGE.utils;
import java.util.Iterator; import java.util.Iterator;
import java.util.NoSuchElementException; import java.util.NoSuchElementException;
#if TYPE_OBJECT
import java.util.function.Function; import java.util.function.Function;
#endif
import speiger.src.collections.PACKAGE.collections.ITERATOR; import speiger.src.collections.PACKAGE.collections.ITERATOR;
import speiger.src.collections.PACKAGE.lists.ARRAY_LIST; import speiger.src.collections.PACKAGE.lists.ARRAY_LIST;

View File

@ -91,7 +91,7 @@ public class PRIORITY_QUEUES
@Override @Override
public KEY_TYPE peek(int index) { synchronized(mutex) { return queue.peek(index); } } public KEY_TYPE peek(int index) { synchronized(mutex) { return queue.peek(index); } }
@Override @Override
public boolean remove(KEY_TYPE e) { synchronized(mutex) { return queue.remove(e); } } public boolean removeFirst(KEY_TYPE e) { synchronized(mutex) { return queue.removeFirst(e); } }
@Override @Override
public boolean removeLast(KEY_TYPE e) { synchronized(mutex) { return queue.removeLast(e); } } public boolean removeLast(KEY_TYPE e) { synchronized(mutex) { return queue.removeLast(e); } }
@Override @Override
@ -99,7 +99,7 @@ public class PRIORITY_QUEUES
@Override @Override
public COMPARATOR KEY_SUPER_GENERIC_TYPE comparator() { synchronized(mutex) { return queue.comparator(); } } public COMPARATOR KEY_SUPER_GENERIC_TYPE comparator() { synchronized(mutex) { return queue.comparator(); } }
@Override @Override
public KEY_TYPE[] TO_ARRAY(KEY_TYPE[] input) { synchronized(mutex) { return queue.TO_ARRAY(input); } } public KEY_GENERIC_SPECIAL_TYPE KEY_SPECIAL_TYPE[] TO_ARRAY(KEY_SPECIAL_TYPE[] input) { synchronized(mutex) { return queue.TO_ARRAY(input); } }
} }
/** /**

View File

@ -66,7 +66,7 @@ public abstract class BaseIntPriorityQueueTest extends BaseIntIterableTest
for(int i = 0;i<100;i++) { for(int i = 0;i<100;i++) {
queue.enqueue(i); queue.enqueue(i);
} }
queue.remove(40); queue.removeFirst(40);
for(int i = 0;i<99;i++) { for(int i = 0;i<99;i++) {
if(i >= 40) Assert.assertEquals(i + 1, queue.dequeue()); if(i >= 40) Assert.assertEquals(i + 1, queue.dequeue());
else Assert.assertEquals(i, queue.dequeue()); else Assert.assertEquals(i, queue.dequeue());

View File

@ -0,0 +1,44 @@
package speiger.src.collections.ints.lists;
import org.junit.Test;
import speiger.src.collections.ints.base.BaseIntListTest;
import speiger.src.collections.ints.base.BaseIntPriorityQueueTest;
import speiger.src.collections.ints.base.IIntStackTests;
import speiger.src.collections.ints.queues.IntPriorityQueue;
/**
* @author Speiger
*
*/
public class IntLinkedListTest extends BaseIntListTest implements IIntStackTests
{
@Override
public IntLinkedList create(int[] data) {
return new IntLinkedList(data);
}
@Test
@Override
public void testPush() {
IIntStackTests.super.testPush();
}
@Test
@Override
public void testPop() {
IIntStackTests.super.testPop();
}
/**
* @author Speiger
*/
public static class IntLinkedListQueueTest extends BaseIntPriorityQueueTest {
@Override
protected IntPriorityQueue create(int[] data) {
return new IntLinkedList(data);
}
}
}