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.
This commit is contained in:
2023-06-29 18:30:22 +02:00
parent a89c812c06
commit 274d37c4d6
31 changed files with 2792 additions and 2272 deletions
@@ -1,459 +1,468 @@
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 removeFirst(KEY_TYPE e) {
if(first == last) return false;
for(int i = 0,m=size();i<m;i++) {
int index = (first + i) % array.length;
if(e == array[index])
return removeIndex(index);
}
return false;
}
@Override
public boolean removeLast(KEY_TYPE e) {
if(first == last) return false;
for(int i = size()-1;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<m;i++)
action.accept(array[(first + i) % array.length]);
clearAndTrim(0);
}
@Override
public void forEachIndexed(BI_FROM_INT_CONSUMER KEY_GENERIC_TYPE action) {
Objects.requireNonNull(action);
if(first == last) return;
for(int i = 0,m=size();i<m;i++)
action.accept(i, array[(first + i) % array.length]);
clearAndTrim(0);
}
@Override
public <E> void forEach(E input, BI_FROM_OBJECT_CONSUMER KSK_GENERIC_TYPE<E> action) {
Objects.requireNonNull(action);
if(first == last) return;
for(int i = 0,m=size();i<m;i++)
action.accept(input, array[(first + i) % array.length]);
clearAndTrim(0);
}
@Override
public boolean matchesAny(PREDICATE KEY_GENERIC_TYPE filter) {
Objects.requireNonNull(filter);
for(int i = 0,m=size();i<m;i++) {
if(filter.test(array[(first + i) % array.length])) return true;
}
return false;
}
@Override
public boolean matchesNone(PREDICATE KEY_GENERIC_TYPE filter) {
Objects.requireNonNull(filter);
for(int i = 0,m=size();i<m;i++) {
if(filter.test(array[(first + i) % array.length])) return false;
}
return true;
}
@Override
public boolean matchesAll(PREDICATE KEY_GENERIC_TYPE filter) {
Objects.requireNonNull(filter);
for(int i = 0,m=size();i<m;i++) {
if(!filter.test(array[(first + i) % array.length])) return false;
}
return true;
}
@Override
public KEY_TYPE findFirst(PREDICATE KEY_GENERIC_TYPE filter) {
Objects.requireNonNull(filter);
for(int i = 0,m=size();i<m;i++) {
int index = (first + i) % array.length;
if(filter.test(array[index])) {
KEY_TYPE data = array[index];
removeIndex(index);
return data;
}
}
return EMPTY_VALUE;
}
#if !TYPE_OBJECT
@Override
public KEY_TYPE reduce(KEY_TYPE identity, UNARY_OPERATOR KEY_KEY_GENERIC_TYPE operator) {
Objects.requireNonNull(operator);
KEY_TYPE state = identity;
for(int i = 0,m=size();i<m;i++) {
state = operator.APPLY_VALUE(state, array[(first + i) % array.length]);
}
return state;
}
#else
@Override
public <KEY_SPECIAL_TYPE> KEY_SPECIAL_TYPE reduce(KEY_SPECIAL_TYPE identity, BiFunction<KEY_SPECIAL_TYPE, KEY_TYPE, KEY_SPECIAL_TYPE> operator) {
Objects.requireNonNull(operator);
KEY_SPECIAL_TYPE state = identity;
for(int i = 0,m=size();i<m;i++) {
state = operator.APPLY_VALUE(state, array[(first + i) % array.length]);
}
return state;
}
#endif
@Override
public KEY_TYPE reduce(UNARY_OPERATOR KEY_KEY_GENERIC_TYPE operator) {
Objects.requireNonNull(operator);
KEY_TYPE state = EMPTY_VALUE;
boolean empty = true;
for(int i = 0,m=size();i<m;i++) {
if(empty) {
empty = false;
state = array[(first + i) % array.length];
continue;
}
state = operator.APPLY_VALUE(state, array[(first + i) % array.length]);
}
return state;
}
@Override
public int count(PREDICATE KEY_GENERIC_TYPE filter) {
Objects.requireNonNull(filter);
int result = 0;
for(int i = 0,m=size();i<m;i++) {
if(filter.test(array[(first + i) % array.length])) result++;
}
return result;
}
@Override
public boolean trim(int size) {
int newSize = Math.max(Math.max(size, size()), minCapacity);
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;
}
/**
* 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<E> 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<m;i++) {
if(e == array[(first + i) % array.length]) return true;
}
return false;
}
@Override
public boolean removeFirst(KEY_TYPE e) {
if(first == last) return false;
for(int i = 0,m=size();i<m;i++) {
int index = (first + i) % array.length;
if(e == array[index])
return removeIndex(index);
}
return false;
}
@Override
public boolean removeLast(KEY_TYPE e) {
if(first == last) return false;
for(int i = size()-1;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<m;i++)
action.accept(array[(first + i) % array.length]);
clearAndTrim(0);
}
@Override
public void forEachIndexed(BI_FROM_INT_CONSUMER KEY_GENERIC_TYPE action) {
Objects.requireNonNull(action);
if(first == last) return;
for(int i = 0,m=size();i<m;i++)
action.accept(i, array[(first + i) % array.length]);
clearAndTrim(0);
}
@Override
public <E> void forEach(E input, BI_FROM_OBJECT_CONSUMER KSK_GENERIC_TYPE<E> action) {
Objects.requireNonNull(action);
if(first == last) return;
for(int i = 0,m=size();i<m;i++)
action.accept(input, array[(first + i) % array.length]);
clearAndTrim(0);
}
@Override
public boolean matchesAny(PREDICATE KEY_GENERIC_TYPE filter) {
Objects.requireNonNull(filter);
for(int i = 0,m=size();i<m;i++) {
if(filter.test(array[(first + i) % array.length])) return true;
}
return false;
}
@Override
public boolean matchesNone(PREDICATE KEY_GENERIC_TYPE filter) {
Objects.requireNonNull(filter);
for(int i = 0,m=size();i<m;i++) {
if(filter.test(array[(first + i) % array.length])) return false;
}
return true;
}
@Override
public boolean matchesAll(PREDICATE KEY_GENERIC_TYPE filter) {
Objects.requireNonNull(filter);
for(int i = 0,m=size();i<m;i++) {
if(!filter.test(array[(first + i) % array.length])) return false;
}
return true;
}
@Override
public KEY_TYPE findFirst(PREDICATE KEY_GENERIC_TYPE filter) {
Objects.requireNonNull(filter);
for(int i = 0,m=size();i<m;i++) {
int index = (first + i) % array.length;
if(filter.test(array[index])) {
KEY_TYPE data = array[index];
removeIndex(index);
return data;
}
}
return EMPTY_VALUE;
}
#if !TYPE_OBJECT
@Override
public KEY_TYPE reduce(KEY_TYPE identity, UNARY_OPERATOR KEY_KEY_GENERIC_TYPE operator) {
Objects.requireNonNull(operator);
KEY_TYPE state = identity;
for(int i = 0,m=size();i<m;i++) {
state = operator.APPLY_VALUE(state, array[(first + i) % array.length]);
}
return state;
}
#else
@Override
public <KEY_SPECIAL_TYPE> KEY_SPECIAL_TYPE reduce(KEY_SPECIAL_TYPE identity, BiFunction<KEY_SPECIAL_TYPE, KEY_TYPE, KEY_SPECIAL_TYPE> operator) {
Objects.requireNonNull(operator);
KEY_SPECIAL_TYPE state = identity;
for(int i = 0,m=size();i<m;i++) {
state = operator.APPLY_VALUE(state, array[(first + i) % array.length]);
}
return state;
}
#endif
@Override
public KEY_TYPE reduce(UNARY_OPERATOR KEY_KEY_GENERIC_TYPE operator) {
Objects.requireNonNull(operator);
KEY_TYPE state = EMPTY_VALUE;
boolean empty = true;
for(int i = 0,m=size();i<m;i++) {
if(empty) {
empty = false;
state = array[(first + i) % array.length];
continue;
}
state = operator.APPLY_VALUE(state, array[(first + i) % array.length]);
}
return state;
}
@Override
public int count(PREDICATE KEY_GENERIC_TYPE filter) {
Objects.requireNonNull(filter);
int result = 0;
for(int i = 0,m=size();i<m;i++) {
if(filter.test(array[(first + i) % array.length])) result++;
}
return result;
}
@Override
public boolean trim(int size) {
int newSize = Math.max(Math.max(size, size()), minCapacity);
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;
}
/**
* 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<E> 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;
}
}
}
@@ -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<size;i++)
if(KEY_EQUALS(e, array[i])) return removeIndex(i);
return false;
}
@Override
public boolean removeLast(KEY_TYPE e) {
for(int i = size-1;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<m;i++) action.accept(dequeue());
}
@Override
public void forEachIndexed(BI_FROM_INT_CONSUMER KEY_GENERIC_TYPE action) {
Objects.requireNonNull(action);
for(int i = 0,m=size;i<m;i++) action.accept(i, dequeue());
}
@Override
public <E> void forEach(E input, BI_FROM_OBJECT_CONSUMER KSK_GENERIC_TYPE<E> action) {
Objects.requireNonNull(action);
for(int i = 0,m=size;i<m;i++) action.accept(input, dequeue());
}
@Override
public boolean matchesAny(PREDICATE KEY_GENERIC_TYPE filter) {
Objects.requireNonNull(filter);
for(int i = 0;i<size;i++) {
if(filter.test(array[i])) return true;
}
return false;
}
@Override
public boolean matchesNone(PREDICATE KEY_GENERIC_TYPE filter) {
Objects.requireNonNull(filter);
for(int i = 0;i<size;i++) {
if(filter.test(array[i])) return false;
}
return true;
}
@Override
public boolean matchesAll(PREDICATE KEY_GENERIC_TYPE filter) {
Objects.requireNonNull(filter);
for(int i = 0;i<size;i++) {
if(!filter.test(array[i])) return false;
}
return true;
}
#if !TYPE_OBJECT
@Override
public KEY_TYPE reduce(KEY_TYPE identity, UNARY_OPERATOR KEY_KEY_GENERIC_TYPE operator) {
Objects.requireNonNull(operator);
KEY_TYPE state = identity;
for(int i = 0;i<size;i++) {
state = operator.APPLY_VALUE(state, array[i]);
}
return state;
}
#else
@Override
public <KEY_SPECIAL_TYPE> KEY_SPECIAL_TYPE reduce(KEY_SPECIAL_TYPE identity, BiFunction<KEY_SPECIAL_TYPE, KEY_TYPE, KEY_SPECIAL_TYPE> operator) {
Objects.requireNonNull(operator);
KEY_SPECIAL_TYPE state = identity;
for(int i = 0;i<size;i++) {
state = operator.APPLY_VALUE(state, array[i]);
}
return state;
}
#endif
@Override
public KEY_TYPE reduce(UNARY_OPERATOR KEY_KEY_GENERIC_TYPE operator) {
Objects.requireNonNull(operator);
KEY_TYPE state = EMPTY_VALUE;
boolean empty = true;
for(int i = 0;i<size;i++) {
if(empty) {
empty = false;
state = array[i];
continue;
}
state = operator.APPLY_VALUE(state, array[i]);
}
return state;
}
@Override
public KEY_TYPE findFirst(PREDICATE KEY_GENERIC_TYPE filter) {
Objects.requireNonNull(filter);
for(int i = 0;i<size;i++) {
if(filter.test(array[i])) {
KEY_TYPE data = array[i];
removeIndex(i);
return data;
}
}
return EMPTY_VALUE;
}
@Override
public int count(PREDICATE KEY_GENERIC_TYPE filter) {
Objects.requireNonNull(filter);
int result = 0;
for(int i = 0;i<size;i++) {
if(filter.test(array[i])) result++;
}
return result;
}
@Override
public ITERATOR KEY_GENERIC_TYPE iterator() {
return new Iter();
}
@Override
public ARRAY_PRIORITY_QUEUE KEY_GENERIC_TYPE copy() {
ARRAY_PRIORITY_QUEUE KEY_GENERIC_TYPE queue = new ARRAY_PRIORITY_QUEUEBRACES();
queue.firstIndex = firstIndex;
queue.size = size;
queue.comparator = comparator;
queue.array = Arrays.copyOf(array, array.length);
return queue;
}
@Override
public COMPARATOR KEY_SUPER_GENERIC_TYPE comparator() {
return comparator;
}
@Override
public GENERIC_SPECIAL_KEY_BRACES<E> 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<size;i++)
if(KEY_EQUALS(e, array[i])) return true;
return false;
}
@Override
public boolean removeFirst(KEY_TYPE e) {
for(int i = 0;i<size;i++)
if(KEY_EQUALS(e, array[i])) return removeIndex(i);
return false;
}
@Override
public boolean removeLast(KEY_TYPE e) {
for(int i = size-1;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<m;i++) action.accept(dequeue());
}
@Override
public void forEachIndexed(BI_FROM_INT_CONSUMER KEY_GENERIC_TYPE action) {
Objects.requireNonNull(action);
for(int i = 0,m=size;i<m;i++) action.accept(i, dequeue());
}
@Override
public <E> void forEach(E input, BI_FROM_OBJECT_CONSUMER KSK_GENERIC_TYPE<E> action) {
Objects.requireNonNull(action);
for(int i = 0,m=size;i<m;i++) action.accept(input, dequeue());
}
@Override
public boolean matchesAny(PREDICATE KEY_GENERIC_TYPE filter) {
Objects.requireNonNull(filter);
for(int i = 0;i<size;i++) {
if(filter.test(array[i])) return true;
}
return false;
}
@Override
public boolean matchesNone(PREDICATE KEY_GENERIC_TYPE filter) {
Objects.requireNonNull(filter);
for(int i = 0;i<size;i++) {
if(filter.test(array[i])) return false;
}
return true;
}
@Override
public boolean matchesAll(PREDICATE KEY_GENERIC_TYPE filter) {
Objects.requireNonNull(filter);
for(int i = 0;i<size;i++) {
if(!filter.test(array[i])) return false;
}
return true;
}
#if !TYPE_OBJECT
@Override
public KEY_TYPE reduce(KEY_TYPE identity, UNARY_OPERATOR KEY_KEY_GENERIC_TYPE operator) {
Objects.requireNonNull(operator);
KEY_TYPE state = identity;
for(int i = 0;i<size;i++) {
state = operator.APPLY_VALUE(state, array[i]);
}
return state;
}
#else
@Override
public <KEY_SPECIAL_TYPE> KEY_SPECIAL_TYPE reduce(KEY_SPECIAL_TYPE identity, BiFunction<KEY_SPECIAL_TYPE, KEY_TYPE, KEY_SPECIAL_TYPE> operator) {
Objects.requireNonNull(operator);
KEY_SPECIAL_TYPE state = identity;
for(int i = 0;i<size;i++) {
state = operator.APPLY_VALUE(state, array[i]);
}
return state;
}
#endif
@Override
public KEY_TYPE reduce(UNARY_OPERATOR KEY_KEY_GENERIC_TYPE operator) {
Objects.requireNonNull(operator);
KEY_TYPE state = EMPTY_VALUE;
boolean empty = true;
for(int i = 0;i<size;i++) {
if(empty) {
empty = false;
state = array[i];
continue;
}
state = operator.APPLY_VALUE(state, array[i]);
}
return state;
}
@Override
public KEY_TYPE findFirst(PREDICATE KEY_GENERIC_TYPE filter) {
Objects.requireNonNull(filter);
for(int i = 0;i<size;i++) {
if(filter.test(array[i])) {
KEY_TYPE data = array[i];
removeIndex(i);
return data;
}
}
return EMPTY_VALUE;
}
@Override
public int count(PREDICATE KEY_GENERIC_TYPE filter) {
Objects.requireNonNull(filter);
int result = 0;
for(int i = 0;i<size;i++) {
if(filter.test(array[i])) result++;
}
return result;
}
@Override
public ITERATOR KEY_GENERIC_TYPE iterator() {
return new Iter();
}
@Override
public ARRAY_PRIORITY_QUEUE KEY_GENERIC_TYPE copy() {
ARRAY_PRIORITY_QUEUE KEY_GENERIC_TYPE queue = new ARRAY_PRIORITY_QUEUEBRACES();
queue.firstIndex = firstIndex;
queue.size = size;
queue.comparator = comparator;
queue.array = Arrays.copyOf(array, array.length);
return queue;
}
@Override
public COMPARATOR KEY_SUPER_GENERIC_TYPE comparator() {
return comparator;
}
@Override
public GENERIC_SPECIAL_KEY_BRACES<E> 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();
}
}
}
@@ -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<size;i++)
if(KEY_EQUALS(e, array[i])) return removeIndex(i);
return false;
}
@Override
public boolean removeLast(KEY_TYPE e) {
for(int i = size-1;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<m;i++) action.accept(dequeue());
}
@Override
public void forEachIndexed(BI_FROM_INT_CONSUMER KEY_GENERIC_TYPE action) {
Objects.requireNonNull(action);
for(int i = 0,m=size;i<m;i++) action.accept(i, dequeue());
}
@Override
public <E> void forEach(E input, BI_FROM_OBJECT_CONSUMER KSK_GENERIC_TYPE<E> action) {
Objects.requireNonNull(action);
for(int i = 0,m=size;i<m;i++) action.accept(input, dequeue());
}
@Override
public boolean matchesAny(PREDICATE KEY_GENERIC_TYPE filter) {
Objects.requireNonNull(filter);
for(int i = 0;i<size;i++) {
if(filter.test(array[i])) return true;
}
return false;
}
@Override
public boolean matchesNone(PREDICATE KEY_GENERIC_TYPE filter) {
Objects.requireNonNull(filter);
for(int i = 0;i<size;i++) {
if(filter.test(array[i])) return false;
}
return true;
}
@Override
public boolean matchesAll(PREDICATE KEY_GENERIC_TYPE filter) {
Objects.requireNonNull(filter);
for(int i = 0;i<size;i++) {
if(!filter.test(array[i])) return false;
}
return true;
}
#if !TYPE_OBJECT
@Override
public KEY_TYPE reduce(KEY_TYPE identity, UNARY_OPERATOR KEY_KEY_GENERIC_TYPE operator) {
Objects.requireNonNull(operator);
KEY_TYPE state = identity;
for(int i = 0;i<size;i++) {
state = operator.APPLY_VALUE(state, array[i]);
}
return state;
}
#else
@Override
public <KEY_SPECIAL_TYPE> KEY_SPECIAL_TYPE reduce(KEY_SPECIAL_TYPE identity, BiFunction<KEY_SPECIAL_TYPE, KEY_TYPE, KEY_SPECIAL_TYPE> operator) {
Objects.requireNonNull(operator);
KEY_SPECIAL_TYPE state = identity;
for(int i = 0;i<size;i++) {
state = operator.APPLY_VALUE(state, array[i]);
}
return state;
}
#endif
@Override
public KEY_TYPE reduce(UNARY_OPERATOR KEY_KEY_GENERIC_TYPE operator) {
Objects.requireNonNull(operator);
KEY_TYPE state = EMPTY_VALUE;
boolean empty = true;
for(int i = 0;i<size;i++) {
if(empty) {
empty = false;
state = array[i];
continue;
}
state = operator.APPLY_VALUE(state, array[i]);
}
return state;
}
@Override
public KEY_TYPE findFirst(PREDICATE KEY_GENERIC_TYPE filter) {
Objects.requireNonNull(filter);
for(int i = 0;i<size;i++) {
if(filter.test(array[i])) {
KEY_TYPE data = array[i];
removeIndex(i);
return data;
}
}
return EMPTY_VALUE;
}
@Override
public int count(PREDICATE KEY_GENERIC_TYPE filter) {
Objects.requireNonNull(filter);
int result = 0;
for(int i = 0;i<size;i++) {
if(filter.test(array[i])) result++;
}
return result;
}
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 HEAP_PRIORITY_QUEUE KEY_GENERIC_TYPE copy() {
HEAP_PRIORITY_QUEUE KEY_GENERIC_TYPE queue = new HEAP_PRIORITY_QUEUEBRACES();
queue.size = size;
queue.comparator = comparator;
queue.array = Arrays.copyOf(array, array.length);
return queue;
}
@Override
public COMPARATOR KEY_SUPER_GENERIC_TYPE comparator() {
return comparator;
}
@Override
public GENERIC_SPECIAL_KEY_BRACES<E> 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<size;i++)
if(KEY_EQUALS(e, array[i])) return true;
return false;
}
@Override
public boolean removeFirst(KEY_TYPE e) {
for(int i = 0;i<size;i++)
if(KEY_EQUALS(e, array[i])) return removeIndex(i);
return false;
}
@Override
public boolean removeLast(KEY_TYPE e) {
for(int i = size-1;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<m;i++) action.accept(dequeue());
}
@Override
public void forEachIndexed(BI_FROM_INT_CONSUMER KEY_GENERIC_TYPE action) {
Objects.requireNonNull(action);
for(int i = 0,m=size;i<m;i++) action.accept(i, dequeue());
}
@Override
public <E> void forEach(E input, BI_FROM_OBJECT_CONSUMER KSK_GENERIC_TYPE<E> action) {
Objects.requireNonNull(action);
for(int i = 0,m=size;i<m;i++) action.accept(input, dequeue());
}
@Override
public boolean matchesAny(PREDICATE KEY_GENERIC_TYPE filter) {
Objects.requireNonNull(filter);
for(int i = 0;i<size;i++) {
if(filter.test(array[i])) return true;
}
return false;
}
@Override
public boolean matchesNone(PREDICATE KEY_GENERIC_TYPE filter) {
Objects.requireNonNull(filter);
for(int i = 0;i<size;i++) {
if(filter.test(array[i])) return false;
}
return true;
}
@Override
public boolean matchesAll(PREDICATE KEY_GENERIC_TYPE filter) {
Objects.requireNonNull(filter);
for(int i = 0;i<size;i++) {
if(!filter.test(array[i])) return false;
}
return true;
}
#if !TYPE_OBJECT
@Override
public KEY_TYPE reduce(KEY_TYPE identity, UNARY_OPERATOR KEY_KEY_GENERIC_TYPE operator) {
Objects.requireNonNull(operator);
KEY_TYPE state = identity;
for(int i = 0;i<size;i++) {
state = operator.APPLY_VALUE(state, array[i]);
}
return state;
}
#else
@Override
public <KEY_SPECIAL_TYPE> KEY_SPECIAL_TYPE reduce(KEY_SPECIAL_TYPE identity, BiFunction<KEY_SPECIAL_TYPE, KEY_TYPE, KEY_SPECIAL_TYPE> operator) {
Objects.requireNonNull(operator);
KEY_SPECIAL_TYPE state = identity;
for(int i = 0;i<size;i++) {
state = operator.APPLY_VALUE(state, array[i]);
}
return state;
}
#endif
@Override
public KEY_TYPE reduce(UNARY_OPERATOR KEY_KEY_GENERIC_TYPE operator) {
Objects.requireNonNull(operator);
KEY_TYPE state = EMPTY_VALUE;
boolean empty = true;
for(int i = 0;i<size;i++) {
if(empty) {
empty = false;
state = array[i];
continue;
}
state = operator.APPLY_VALUE(state, array[i]);
}
return state;
}
@Override
public KEY_TYPE findFirst(PREDICATE KEY_GENERIC_TYPE filter) {
Objects.requireNonNull(filter);
for(int i = 0;i<size;i++) {
if(filter.test(array[i])) {
KEY_TYPE data = array[i];
removeIndex(i);
return data;
}
}
return EMPTY_VALUE;
}
@Override
public int count(PREDICATE KEY_GENERIC_TYPE filter) {
Objects.requireNonNull(filter);
int result = 0;
for(int i = 0;i<size;i++) {
if(filter.test(array[i])) result++;
}
return result;
}
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 HEAP_PRIORITY_QUEUE KEY_GENERIC_TYPE copy() {
HEAP_PRIORITY_QUEUE KEY_GENERIC_TYPE queue = new HEAP_PRIORITY_QUEUEBRACES();
queue.size = size;
queue.comparator = comparator;
queue.array = Arrays.copyOf(array, array.length);
return queue;
}
@Override
public COMPARATOR KEY_SUPER_GENERIC_TYPE comparator() {
return comparator;
}
@Override
public GENERIC_SPECIAL_KEY_BRACES<E> 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();
}
}
}
@@ -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