Project is now buildable.

-Moved: Code generation is in its own sourceset.
-Fixed: Bugs that caused that the project isnt buildable.
-Changed: Made build.gradle to a standard.
This commit is contained in:
2021-01-29 11:41:48 +01:00
parent 0cb07398f9
commit aaee550ea9
57 changed files with 132 additions and 86 deletions
@@ -0,0 +1,206 @@
package speiger.src.collections.PACKAGE.collections;
import java.util.Collection;
import java.util.Objects;
import java.util.AbstractCollection;
import speiger.src.collections.PACKAGE.collections.COLLECTION;
#if !TYPE_OBJECT
import speiger.src.collections.PACKAGE.utils.ITERATORS;
#endif
public abstract class ABSTRACT_COLLECTION KEY_GENERIC_TYPE extends AbstractCollection<CLASS_TYPE> implements COLLECTION KEY_GENERIC_TYPE
{
@Override
public abstract ITERATOR KEY_GENERIC_TYPE iterator();
#if !TYPE_OBJECT
/** {@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 add(CLASS_TYPE e) { return COLLECTION.super.add(e); }
#endif
@Override
public boolean addAll(COLLECTION KEY_GENERIC_TYPE c) {
boolean modified = false;
for(ITERATOR KEY_GENERIC_TYPE iter = c.iterator();iter.hasNext();modified |= add(iter.NEXT()));
return modified;
}
#if !TYPE_OBJECT
/** {@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 contains(Object e) { return COLLECTION.super.contains(e); }
/**
* A Type-Specific implementation of contains. This implementation iterates over the elements and returns true if the value match.
* @param value that should be searched for.
* @return true if the value was found.
*/
@Override
public boolean contains(KEY_TYPE e) {
for(ITERATOR KEY_GENERIC_TYPE iter = iterator();iter.hasNext();) { if(KEY_EQUALS(iter.NEXT(), e)) return true; }
return false;
}
#endif
/** {@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) : super.addAll(c);
}
/**
* A Type-Specific implementation of containsAll. This implementation iterates over all elements and checks all elements are present in the other collection.
* @param the collection that should be checked if it contains all elements.
* @return true if all elements were found in the collection
* @throws NullPointerException if the collection is null
*/
@Override
public boolean containsAll(COLLECTION KEY_GENERIC_TYPE c) {
Objects.requireNonNull(c);
for(ITERATOR KEY_GENERIC_TYPE iter = c.iterator();iter.hasNext();)
if(!contains(iter.NEXT()))
return false;
return true;
}
/**
* This implementation iterates over the elements of the collection and checks if they are stored in this collection
* @param c the elements that should be checked for
* @return true if any element is in this collection
* @deprecated if this is a primitive collection
* @throws NullPointerException if the collection is null
*/
@Override
@Primitive
public boolean containsAny(Collection<?> c) {
Objects.requireNonNull(c);
for(Object e : c)
if(contains(e))
return true;
return false;
}
/**
* This implementation iterates over the elements of the collection and checks if they are stored in this collection.
* @param c the elements that should be checked for
* @return true if any element is in this collection
* @throws NullPointerException if the collection is null
*/
@Override
public boolean containsAny(COLLECTION KEY_GENERIC_TYPE c) {
Objects.requireNonNull(c);
for(ITERATOR KEY_GENERIC_TYPE iter = c.iterator();iter.hasNext();)
if(contains(iter.NEXT()))
return true;
return false;
}
#if !TYPE_OBJECT
/** {@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 remove(Object e) { return COLLECTION.super.remove(e); }
/**
* A Type-Specific implementation of remove. This implementation iterates over the elements until it finds the element that is searched for or it runs out of elements.
* It stops after finding the first element
* @param e the element that is searched for
* @return true if the element was found and removed.
*/
@Override
public boolean REMOVE_KEY(KEY_TYPE e) {
for(ITERATOR KEY_GENERIC_TYPE iter = iterator();iter.hasNext();) {
if(KEY_EQUALS(iter.NEXT(), e)) {
iter.remove();
return true;
}
}
return false;
}
#endif
/**
* A Type-Specific implementation of removeAll. This Implementation iterates over all elements and removes them as they were found in the other collection.
* @param c the elements that should be deleted
* @return true if the collection was modified.
* @throws NullPointerException if the collection is null
*/
@Override
public boolean removeAll(COLLECTION KEY_GENERIC_TYPE c) {
Objects.requireNonNull(c);
boolean modified = false;
for(ITERATOR KEY_GENERIC_TYPE iter = iterator();iter.hasNext();) {
if(c.contains(iter.NEXT())) {
iter.remove();
modified = true;
}
}
return modified;
}
/**
* A Type-Specific implementation of retainAll. This Implementation iterates over all elements and removes them as they were not found in the other collection.
* @param c the elements that should be kept
* @return true if the collection was modified.
* @throws NullPointerException if the collection is null
*/
@Override
public boolean retainAll(COLLECTION KEY_GENERIC_TYPE c) {
Objects.requireNonNull(c);
if(c.isEmpty()) {
boolean modified = !isEmpty();
clear();
return modified;
}
boolean modified = false;
for(ITERATOR KEY_GENERIC_TYPE iter = iterator();iter.hasNext();) {
if(!c.contains(iter.NEXT())) {
iter.remove();
modified = true;
}
}
return modified;
}
#if !TYPE_OBJECT
/**
* A Type-Specific implementation of toArray that links to {@link #TO_ARRAY(KEY_TYPE[])} with a newly created array.
* @return an array containing all of the elements in this collection
*/
@Override
public KEY_TYPE[] TO_ARRAY() {
return TO_ARRAY(new KEY_TYPE[size()]);
}
/**
* A Type-Specific implementation of toArray. This implementation iterates over all elements and unwraps them into primitive type.
* @param a array that the elements should be injected to. If null or to small a new array with the right size is created
* @return an array containing all of the elements in this collection
*/
@Override
public KEY_TYPE[] TO_ARRAY(KEY_TYPE[] a) {
if(a == null || a.length < size()) a = new KEY_TYPE[size()];
ITERATORS.unwrap(a, iterator());
return a;
}
#endif
}
@@ -0,0 +1,62 @@
package speiger.src.collections.PACKAGE.collections;
#if !TYPE_OBJECT
import speiger.src.collections.objects.collections.ObjectBidirectionalIterator;
/**
* A Type-Specific {@link ObjectBidirectionalIterator} to reduce (un)boxing
*/
public interface BI_ITERATOR KEY_GENERIC_TYPE extends ITERATOR KEY_GENERIC_TYPE, ObjectBidirectionalIterator<CLASS_TYPE>
#else
/**
* This is a basically a {@link ListIterator} without the index functions.
* Allowing to have a simple Bidirectional Iterator without having to keep track of the Iteration index.
*/
public interface BI_ITERATOR KEY_GENERIC_TYPE extends ITERATOR KEY_GENERIC_TYPE
#endif
{
/**
* Returns true if the Iterator has a Previous element
* @return true if the Iterator has a Previouse element
*/
public boolean hasPrevious();
/**
* Returns the Previous element of the iterator.
* @return the Previous element of the iterator.
* @throws NoSuchElementException if the iteration has no more elements
*/
public KEY_TYPE PREVIOUS();
#if !TYPE_OBJECT
/** {@inheritDoc}
* <p>This default implementation delegates to the corresponding type-specific function.
* @deprecated Please use the corresponding type-specific function instead.
*/
@Override
@Deprecated
public default CLASS_TYPE previous() {
return KEY_TO_OBJ(PREVIOUS());
}
/**
* {@inheritDoc}
*/
@Override
default int skip(int amount)
{
return ITERATOR.super.skip(amount);
}
#endif
/**
* Reverses the Given amount of elements if possible. A Optimization function to reverse elements faster if the implementation allows it.
* @param amount the amount of elements that should be reversed
* @return the amount of elements that were reversed
*/
public default int back(int amount) {
if(amount < 0) throw new IllegalStateException("Can't go forward");
int i = 0;
for(;i<amount && hasPrevious();previous(),i++);
return i;
}
}
@@ -0,0 +1,174 @@
package speiger.src.collections.PACKAGE.collections;
import java.util.Collection;
#if PRIMITIVES
import java.util.Objects;
import java.util.function.JAVA_PREDICATE;
import java.util.function.Predicate;
#endif
#if TYPE_BYTE || TYPE_SHORT || TYPE_CHAR || TYPE_FLOAT
import speiger.src.collections.utils.SanityChecks;
#endif
/**
* A Type-Specific {@link Collection} that reduces (un)boxing
*/
public interface COLLECTION KEY_GENERIC_TYPE extends Collection<CLASS_TYPE>, ITERABLE KEY_GENERIC_TYPE
{
#if !TYPE_OBJECT
/**
* A Type-Specific add function to reduce (un)boxing
* @see Collection#add(Object)
* @return true if the element was added to the collection
*/
public boolean add(KEY_TYPE o);
#endif
/**
* A Type-Specific addAll function to reduce (un)boxing
* @see Collection#addAll(Collection)
* @return true if elements were added into the collection
*/
public boolean addAll(COLLECTION KEY_GENERIC_TYPE c);
#if !TYPE_OBJECT
/**
* A Type-Specific contains function to reduce (un)boxing
* @see Collection#contains(Object)
* @return true if the element is found in the collection
*/
public boolean contains(KEY_TYPE o);
#endif
/**
* A Type-Specific containsAll function to reduce (un)boxing
* @see Collection#containsAll(Object)
* @return true if all the element is found in the collection
*/
public boolean containsAll(COLLECTION KEY_GENERIC_TYPE c);
/**
* A Type-Specific containsAny function to reduce (un)boxing
* @see #containsAny(Collection)
* @return true if any element was found
*/
public boolean containsAny(COLLECTION KEY_GENERIC_TYPE c);
/**
* Returns true if any element of the Collection is found in the provided collection.
* A Small Optimization function to find out of any element is present when comparing collections and not all of them.
* @return true if any element was found.
*/
@Primitive
public boolean containsAny(Collection<?> c);
#if !TYPE_OBJECT
/**
* A Type-Specific remove function that reduces (un)boxing.
* @return true if the element was removed
* @see Collection#remove(Object)
*/
public boolean REMOVE_KEY(KEY_TYPE o);
#endif
/**
* A Type-Specific removeAll function that reduces (un)boxing.
* @return true if any element was removed
* @see Collection#removeAll(Collection)
*/
public boolean removeAll(COLLECTION KEY_GENERIC_TYPE c);
/**
* A Type-Specific retainAll function that reduces (un)boxing.
* @return true if any element was removed
* @see Collection#retainAll(Collection)
*/
public boolean retainAll(COLLECTION KEY_GENERIC_TYPE c);
#if !TYPE_OBJECT
/**
* A Type-Specific toArray function that delegates to {@link #TO_ARRAY(KEY_TYPE[])} with a newly created array.
* @return an array containing all of the elements in this collection
* @see Collection#toArray()
*/
public KEY_TYPE[] TO_ARRAY();
/**
* A Type-Specific toArray function that reduces (un)boxing.
* @param a array that the elements should be injected to. If null or to small a new array with the right size is created
* @return an array containing all of the elements in this collection
* @see Collection#toArray(Object[])
*/
public KEY_TYPE[] TO_ARRAY(KEY_TYPE[] a);
#if PRIMITIVES
/** {@inheritDoc}
* <p>This default implementation delegates to the corresponding type-specific function.
* @deprecated Please use the corresponding type-specific function instead.
*/
@Override
@Deprecated
public default boolean removeIf(Predicate<? super CLASS_TYPE> filter) {
Objects.requireNonNull(filter);
#if TYPE_BYTE || TYPE_SHORT || TYPE_CHAR || TYPE_FLOAT
return remIf(v -> filter.test(KEY_TO_OBJ(SanityChecks.SANITY_CAST(v))));
#else
return remIf(v -> filter.test(KEY_TO_OBJ(v)));
#endif
}
/**
* A Type-Specific removeIf function to reduce (un)boxing.
* <p>Removes elements that were selected by the filter
* @see Collection#removeIf(Predicate)
* @param filter Filters the elements that should be removed
* @throws NullPointerException if filter is null
*/
public default boolean remIf(JAVA_PREDICATE filter) {
Objects.requireNonNull(filter);
boolean removed = false;
final ITERATOR each = iterator();
while (each.hasNext()) {
if (filter.test(each.NEXT())) {
each.remove();
removed = true;
}
}
return removed;
}
#endif
/** {@inheritDoc}
* <p>This default implementation delegates to the corresponding type-specific function.
* @deprecated Please use the corresponding type-specific function instead.
*/
@Override
@Deprecated
public default boolean add(CLASS_TYPE o) { return add(OBJ_TO_KEY(o)); }
/** {@inheritDoc}
* <p>This default implementation delegates to the corresponding type-specific function.
* @deprecated Please use the corresponding type-specific function instead.
*/
@Override
@Deprecated
public default boolean contains(Object o) { return o != null && contains(CLASS_TO_KEY(o)); }
/** {@inheritDoc}
* <p>This default implementation delegates to the corresponding type-specific function.
* @deprecated Please use the corresponding type-specific function instead.
*/
@Override
@Deprecated
public default boolean remove(Object o) { return o != null && REMOVE_KEY(CLASS_TO_KEY(o)); }
#endif
/**
* Returns a Type-Specific Iterator to reduce (un)boxing
* @return a iterator of the collection
* @see Collection#iterator()
*/
@Override
public ITERATOR KEY_GENERIC_TYPE iterator();
}
@@ -0,0 +1,53 @@
package speiger.src.collections.PACKAGE.collections;
#if !TYPE_OBJECT
import java.util.Objects;
import java.util.function.Consumer;
import speiger.src.collections.PACKAGE.functions.CONSUMER;
#endif
/**
* A Type-Specific {@link Iterable} that reduces (un)boxing
*/
public interface ITERABLE KEY_GENERIC_TYPE extends Iterable<CLASS_TYPE>
{
/**
* Returns an iterator over elements of type {@code T}.
*
* @return an Iterator.
*/
@Override
ITERATOR KEY_GENERIC_TYPE iterator();
#if !TYPE_OBJECT
/**
* A Type Specific foreach function that reduces (un)boxing
*
* @implSpec
* <p>The default implementation behaves as if:
* <pre>{@code
* iterator().forEachRemaining(action);
* }</pre>
*
* @param action The action to be performed for each element
* @throws NullPointerException if the specified action is null
* @see Iterable#forEach(Consumer)
*/
default void forEach(CONSUMER action) {
Objects.requireNonNull(action);
iterator().forEachRemaining(action);
}
/** {@inheritDoc}
* <p>This default implementation delegates to the corresponding type-specific function.
* @deprecated Please use the corresponding type-specific function instead.
*/
@Deprecated
@Override
default void forEach(Consumer<? super CLASS_TYPE> action) {
Objects.requireNonNull(action);
iterator().forEachRemaining(action);
}
#endif
}
@@ -0,0 +1,79 @@
package speiger.src.collections.PACKAGE.collections;
import java.util.Iterator;
#if !TYPE_OBJECT
import java.util.Objects;
import java.util.function.Consumer;
import speiger.src.collections.PACKAGE.functions.CONSUMER;
#endif
/**
* A Type-Specific {@link Iterator} that reduces (un)boxing
*/
public interface ITERATOR KEY_GENERIC_TYPE extends Iterator<CLASS_TYPE>
{
#if !TYPE_OBJECT
/**
* Returns the next element in the iteration.
*
* @return the next element in the iteration
* @throws NoSuchElementException if the iteration has no more elements
* @see Iterator#next()
*/
public KEY_TYPE NEXT();
/** {@inheritDoc}
* <p>This default implementation delegates to the corresponding type-specific function.
* @deprecated Please use the corresponding type-specific function instead.
*/
@Override
@Deprecated
public default CLASS_TYPE next() { return KEY_TO_OBJ(NEXT()); }
/**
* Performs the given action for each remaining element until all elements
* have been processed or the action throws an exception. Actions are
* performed in the order of iteration, if that order is specified.
* Exceptions thrown by the action are relayed to the caller.
*
* @implSpec
* <p>The default implementation behaves as if:
* <pre>{@code
* while (hasNext()) action.accept(NEXT());
* }</pre>
*
* @param action The action to be performed for each element
* @throws NullPointerException if the specified action is null
* @see Iterator#forEachRemaining(Consumer)
*/
public default void forEachRemaining(CONSUMER action) {
Objects.requireNonNull(action);
while(hasNext()) { action.accept(NEXT()); }
}
/** {@inheritDoc}
* <p>This default implementation delegates to the corresponding type-specific function.
* @deprecated Please use the corresponding type-specific function instead.
*/
@Deprecated
@Override
default void forEachRemaining(Consumer<? super CLASS_TYPE> action) {
Objects.requireNonNull(action);
forEachRemaining(action::accept);
}
#endif
/**
* Skips the Given amount of elements if possible. A Optimization function to skip elements faster if the implementation allows it.
* @param amount the amount of elements that should be skipped
* @return the amount of elements that were skipped
*/
default int skip(int amount) {
if(amount < 0) throw new IllegalStateException("Negative Numbers are not allowed");
int i = 0;
for(;i<amount && hasNext();NEXT(), i++);
return i;
}
}
@@ -0,0 +1,80 @@
package speiger.src.collections.PACKAGE.collections;
import speiger.src.collections.utils.Stack;
/**
* A Type-Specific {@link Stack} that reduces (un)boxing
*/
public interface STACK extends Stack<CLASS_TYPE>
{
/**
* Inserts a given Object on top of the stack
* @param e the Object to insert
* @see Stack#push(Object)
*/
public void PUSH(KEY_TYPE e);
/**
* Removes the Object on top of the stack.
* @return the element that is on top of the stack
* @throws ArrayIndexOutOfBoundsException if the stack is empty
* @see Stack#pop()
*/
public KEY_TYPE POP();
/**
* Provides the Object on top of the stack
* @return the element that is on top of the stack
* @throws ArrayIndexOutOfBoundsException if the stack is empty
* @see Stack#top()
*/
public default KEY_TYPE TOP() {
return PEEK(0);
}
/**
* Provides the Selected Object from the stack.
* Top to bottom
* @param index of the element that should be provided
* @return the element that was requested
* @throws ArrayIndexOutOfBoundsException if the index is out of bounds
* @see Stack#peek(int)
*/
public KEY_TYPE PEEK(int index);
#if !OBJECT_TYPE
/** {@inheritDoc}
* <p>This default implementation delegates to the corresponding type-specific function.
* @deprecated Please use the corresponding type-specific function instead.
*/
@Override
@Deprecated
public default void push(CLASS_TYPE e) { PUSH(OBJ_TO_KEY(e)); }
/** {@inheritDoc}
* <p>This default implementation delegates to the corresponding type-specific function.
* @deprecated Please use the corresponding type-specific function instead.
*/
@Override
@Deprecated
public default CLASS_TYPE pop() { return KEY_TO_OBJ(POP()); }
/** {@inheritDoc}
* <p>This default implementation delegates to the corresponding type-specific function.
* @deprecated Please use the corresponding type-specific function instead.
*/
@Override
@Deprecated
public default CLASS_TYPE top() {
return peek(size() - 1);
}
/** {@inheritDoc}
* <p>This default implementation delegates to the corresponding type-specific function.
* @deprecated Please use the corresponding type-specific function instead.
*/
@Override
@Deprecated
public default CLASS_TYPE peek(int index) { return KEY_TO_OBJ(PEEK(index)); }
#endif
}
@@ -0,0 +1,59 @@
package speiger.src.collections.PACKAGE.functions;
import java.util.Comparator;
import java.util.Objects;
/**
* Type-Specific Class for Comparator to reduce (un)boxing
*/
public interface COMPARATOR extends Comparator<CLASS_TYPE>
{
/**
* Type-Specific compare function to reduce (un)boxing
* @see Comparator#compare(Object, Object)
*/
int compare(KEY_TYPE o1, KEY_TYPE o2);
/** {@inheritDoc}
* <p>This default implementation delegates to the corresponding type-specific function.
* @deprecated Please use the corresponding type-specific function instead.
*/
@Override
@Deprecated
default int compare(CLASS_TYPE o1, CLASS_TYPE o2) {
return compare(OBJ_TO_KEY(o1), OBJ_TO_KEY(o2));
}
/**
* A Wrapper function to convert a Non-Type-Specific Comparator to a Type-Specific-Comparator
* @param c comparator to convert
* @return the wrapper of the comparator
* @throws NullPointerException if the comparator is null
*/
public static COMPARATOR of(Comparator<CLASS_TYPE> c) {
Objects.requireNonNull(c);
return (K, V) -> c.compare(KEY_TO_OBJ(K), KEY_TO_OBJ(V));
}
public default COMPARATOR reversed() {
return new Reversed(this);
}
static class Reversed implements COMPARATOR
{
COMPARATOR original;
public Reversed(COMPARATOR original) {
this.original = original;
}
public int compare(KEY_TYPE o1, KEY_TYPE o2) {
return original.compare(o2, o1);
}
@Override
public COMPARATOR reversed() {
return original;
}
}
}
@@ -0,0 +1,59 @@
package speiger.src.collections.PACKAGE.functions;
import java.util.Objects;
import java.util.function.Consumer;
/**
* Type-Specific Consumer interface that reduces (un)boxing and allows to merge other consumer types into this interface
*/
@FunctionalInterface
#if JDK_TYPE && !TYPE_BOOLEAN
public interface CONSUMER extends Consumer<CLASS_TYPE>, JAVA_CONSUMER
#else
public interface CONSUMER extends Consumer<CLASS_TYPE>
#endif
{
/**
* Type-Specific function to reduce (un)boxing.
* Performs this operation on the given argument.
*
* @param t the input argument
*/
void accept(KEY_TYPE t);
public default CONSUMER andThen(CONSUMER after) {
Objects.requireNonNull(after);
return T -> {accept(T); after.accept(T);};
}
/** {@inheritDoc}
* <p>This default implementation delegates to the corresponding type-specific function.
* @deprecated Please use the corresponding type-specific function instead.
*/
@Override
@Deprecated
default void accept(CLASS_TYPE t) { accept(OBJ_TO_KEY(t)); }
/** {@inheritDoc}
* <p>This default implementation delegates to the corresponding type-specific function.
* @deprecated Please use the corresponding type-specific function instead.
*/
@Override
@Deprecated
default CONSUMER andThen(Consumer<? super CLASS_TYPE> after) {
Objects.requireNonNull(after);
return T -> {accept(T); after.accept(KEY_TO_OBJ(T));};
}
#if JDK_TYPE && PRIMITIVES
/** {@inheritDoc}
* <p>This default implementation delegates to the corresponding type-specific function.
* @deprecated Please use the corresponding type-specific function instead.
*/
@Override
@Deprecated
default CONSUMER andThen(JAVA_CONSUMER after) {
Objects.requireNonNull(after);
return T -> {accept(T); after.accept(T);};
}
#endif
}
@@ -0,0 +1,35 @@
package speiger.src.collections.PACKAGE.functions.consumer;
import java.util.Objects;
import java.util.function.BiConsumer;
public interface BI_CONSUMER KEY_VALUE_GENERIC_TYPE extends BiConsumer<CLASS_TYPE, CLASS_VALUE_TYPE>
{
void accept(KEY_TYPE k, VALUE_TYPE v);
public default BI_CONSUMER KEY_VALUE_GENERIC_TYPE andThen(BI_CONSUMER KEY_VALUE_GENERIC_TYPE after) {
Objects.requireNonNull(after);
return (K, V) -> {accept(K, V); after.accept(K, V);};
}
#if !TYPE_OBJECT || !VALUE_OBJECT
/** {@inheritDoc}
* <p>This default implementation delegates to the corresponding type-specific function.
* @deprecated Please use the corresponding type-specific function instead.
*/
@Override
@Deprecated
default void accept(CLASS_TYPE k, CLASS_VALUE_TYPE v) { accept(OBJ_TO_KEY(k), OBJ_TO_VALUE(v)); }
/** {@inheritDoc}
* <p>This default implementation delegates to the corresponding type-specific function.
* @deprecated Please use the corresponding type-specific function instead.
*/
@Override
@Deprecated
default BI_CONSUMER KEY_VALUE_GENERIC_TYPE andThen(BiConsumer<? super CLASS_TYPE, ? super CLASS_VALUE_TYPE> after) {
Objects.requireNonNull(after);
return (K, V) -> {accept(K, V); after.accept(KEY_TO_OBJ(K), VALUE_TO_OBJ(V));};
}
#endif
}
@@ -0,0 +1,59 @@
package speiger.src.collections.PACKAGE.functions.function;
#if JDK_FUNCTION && VALUE_BOOLEAN
import java.util.Objects;
#endif
@FunctionalInterface
#if JDK_FUNCTION
public interface FUNCTION KEY_VALUE_GENERIC_TYPE extends JAVA_FUNCTION KEY_VALUE_GENERIC_TYPE
#else
public interface FUNCTION KEY_VALUE_GENERIC_TYPE
#endif
{
public VALUE_TYPE GET_VALUE(KEY_TYPE k);
#if JDK_FUNCTION
#if VALUE_BOOLEAN
@Override
public default VALUE_TYPE test(KEY_TYPE k) { return GET_VALUE(k); }
public default FUNCTION KEY_VALUE_GENERIC_TYPE andType(FUNCTION KEY_VALUE_GENERIC_TYPE other) {
Objects.requireNonNull(other);
return T -> GET_VALUE(T) && other.GET_VALUE(T);
}
@Override
@Deprecated
public default FUNCTION KEY_VALUE_GENERIC_TYPE and(JAVA_FUNCTION KEY_VALUE_SUPER_GENERIC_TYPE other) {
Objects.requireNonNull(other);
return T -> GET_VALUE(T) && other.test(T);
}
@Override
public default FUNCTION KEY_VALUE_GENERIC_TYPE negate() {
return T -> !GET_VALUE(T);
}
public default FUNCTION KEY_VALUE_GENERIC_TYPE orType(FUNCTION KEY_VALUE_GENERIC_TYPE other) {
Objects.requireNonNull(other);
return T -> GET_VALUE(T) || other.GET_VALUE(T);
}
@Override
@Deprecated
public default FUNCTION KEY_VALUE_GENERIC_TYPE or(JAVA_FUNCTION KEY_VALUE_SUPER_GENERIC_TYPE other) {
Objects.requireNonNull(other);
return T -> GET_VALUE(T) || other.test(T);
}
#else if VALUE_OBJECT
@Override
public default VALUE_TYPE apply(KEY_TYPE k) { return GET_VALUE(k); }
#else
@Override
public default VALUE_TYPE APPLY_VALUE(KEY_TYPE k) { return GET_VALUE(k); }
#endif
#endif
}
@@ -0,0 +1,25 @@
package speiger.src.collections.PACKAGE.functions.function;
import java.util.function.BiFunction;
#if !SAME_TYPE || TYPE_BOOLEAN || !JDK_TYPE
public interface UNARY_OPERATOR KEY_VALUE_GENERIC_TYPE extends BiFunction<CLASS_TYPE, CLASS_VALUE_TYPE, CLASS_VALUE_TYPE>
#else
#if SAME_TYPE && TYPE_OBJECT
public interface UNARY_OPERATOR KEY_VALUE_GENERIC_TYPE extends BiFunction<CLASS_TYPE, CLASS_VALUE_TYPE, CLASS_VALUE_TYPE>
#else
public interface UNARY_OPERATOR KEY_VALUE_GENERIC_TYPE extends BiFunction<CLASS_TYPE, CLASS_VALUE_TYPE, CLASS_VALUE_TYPE>, JAVA_BINARY_OPERATOR
#endif
#endif
{
#if TYPE_OBJECT && VALUE_OBJECT
#else if SAME_TYPE && !TYPE_OBJECT && JDK_TYPE && !TYPE_BOOLEAN
@Override
public default CLASS_VALUE_TYPE apply(CLASS_TYPE k, CLASS_VALUE_TYPE v) { return VALUE_TO_OBJ(APPLY_VALUE(OBJ_TO_KEY(k), OBJ_TO_VALUE(v))); }
#else
public VALUE_TYPE APPLY_VALUE(KEY_TYPE k, VALUE_TYPE v);
@Override
public default CLASS_VALUE_TYPE apply(CLASS_TYPE k, CLASS_VALUE_TYPE v) { return VALUE_TO_OBJ(APPLY_VALUE(OBJ_TO_KEY(k), OBJ_TO_VALUE(v))); }
#endif
}
@@ -0,0 +1,433 @@
package speiger.src.collections.PACKAGE.lists;
import java.util.Collection;
import java.util.List;
import java.util.ListIterator;
import java.util.Objects;
import speiger.src.collections.PACKAGE.collections.ABSTRACT_COLLECTION;
import speiger.src.collections.PACKAGE.collections.COLLECTION;
import speiger.src.collections.PACKAGE.collections.ITERATOR;
/**
* Abstract implementation of the {@link LIST} interface.
*/
public abstract class ABSTRACT_LIST KEY_GENERIC_TYPE extends ABSTRACT_COLLECTION KEY_GENERIC_TYPE implements LIST KEY_GENERIC_TYPE
{
#if !TYPE_OBJECT
/**
* A Type-Specific implementation of add function that delegates to {@link #add(int, KEY_TYPE)}
*/
@Override
public boolean add(KEY_TYPE e) {
add(size(), e);
return true;
}
/** {@inheritDoc}
* <p>This default implementation delegates to the corresponding type-specific function.
* @deprecated Please use the corresponding type-specific function instead.
*/
@Override
@Deprecated
public void add(int index, CLASS_TYPE element) {
add(index, OBJ_TO_KEY(element));
}
#endif
/**
* A Type-Specific implementation that iterates over the elements and adds them.
* @param c the elements that wants to be added
* @return true if the list was modified
*/
@Override
public boolean addAll(COLLECTION KEY_GENERIC_TYPE c) {
boolean modified = false;
for(ITERATOR KEY_GENERIC_TYPE iter = c.iterator();iter.hasNext();modified |= add(iter.NEXT()));
return modified;
}
/**
* A Type-Specific implementation that iterates over the elements and adds them.
* @param c the elements that wants to be added
* @return true if the list was modified
*/
@Override
public boolean addAll(LIST KEY_GENERIC_TYPE c) {
boolean modified = false;
for(ITERATOR KEY_GENERIC_TYPE iter = c.iterator();iter.hasNext();modified |= add(iter.NEXT()));
return modified;
}
/**
* The IndexOf implementation iterates over all elements and compares them to the search value.
* @param e the value that the index is searched for.
* @return index of the value that was searched for. -1 if not found
* @deprecated it is highly suggested not to use this with Primitives because of boxing. But it is still supported because of ObjectComparason that are custom objects and allow to find the contents.
*/
@Override
@Primitive
public int indexOf(Object o) {
LIST_ITERATOR KEY_GENERIC_TYPE iter = listIterator();
#if TYPE_OBJECT
if(o == null) {
while(iter.hasNext()) {
if(iter.NEXT() == null)
return iter.previousIndex();
}
return -1;
}
#else
if(o == null) return -1;
#endif
while(iter.hasNext()) {
if(EQUALS_KEY_TYPE(iter.NEXT(), o))
return iter.previousIndex();
}
return -1;
}
/**
* The lastIndexOf implementation iterates over all elements and compares them to the search value.
* @param e the value that the index is searched for.
* @return the last index of the value that was searched for. -1 if not found
* @deprecated it is highly suggested not to use this with Primitives because of boxing. But it is still supported because of ObjectComparason that are custom objects and allow to find the contents.
*/
@Override
@Primitive
public int lastIndexOf(Object o) {
LIST_ITERATOR KEY_GENERIC_TYPE iter = listIterator(size());
#if TYPE_OBJECT
if(o == null) {
while(iter.hasPrevious()) {
if(iter.PREVIOUS() == null)
return iter.nextIndex();
}
return -1;
}
#else
if(o == null) return -1;
#endif
while(iter.hasPrevious()) {
if(EQUALS_KEY_TYPE(iter.PREVIOUS(), o))
return iter.nextIndex();
}
return -1;
}
#if !TYPE_OBJECT
/**
* The indexOf implementation iterates over all elements and compares them to the search value.
* @param e the value that the index is searched for.
* @return index of the value that was searched for. -1 if not found
*/
@Override
public int indexOf(KEY_TYPE e) {
LIST_ITERATOR KEY_GENERIC_TYPE iter = listIterator();
while(iter.hasNext()) {
if(KEY_EQUALS(iter.NEXT(), e))
return iter.previousIndex();
}
return -1;
}
/**
* The lastIndexOf implementation iterates over all elements and compares them to the search value.
* @param e the value that the index is searched for.
* @return the last index of the value that was searched for. -1 if not found
*/
@Override
public int lastIndexOf(KEY_TYPE e) {
LIST_ITERATOR KEY_GENERIC_TYPE iter = listIterator(size());
while(iter.hasPrevious()) {
if(KEY_EQUALS(iter.PREVIOUS(), e))
return iter.nextIndex();
}
return -1;
}
#endif
/**
* Compares if the list are the same.
*/
@Override
public boolean equals(Object o) {
if (o == this)
return true;
if (!(o instanceof List))
return false;
List<?> l = (List<?>)o;
if(l.size() != size()) return false;
#if !TYPE_OBJECT
if(l instanceof LIST)
{
LIST_ITERATOR e1 = listIterator();
LIST_ITERATOR e2 = ((LIST)l).listIterator();
while (e1.hasNext() && e2.hasNext()) {
if(!(KEY_EQUALS(e1.NEXT(), e2.NEXT())))
return false;
}
return !(e1.hasNext() || e2.hasNext());
}
#endif
ListIterator<CLASS_TYPE> e1 = listIterator();
ListIterator<?> e2 = l.listIterator();
while (e1.hasNext() && e2.hasNext()) {
if(!Objects.equals(e1.next(), e2.next()))
return false;
}
return !(e1.hasNext() || e2.hasNext());
}
/**
* Generates the hashcode based on the values stored in the list.
*/
@Override
public int hashCode() {
int hashCode = 1;
LIST_ITERATOR KEY_GENERIC_TYPE i = listIterator();
while(i.hasNext())
#if TYPE_OBJECT
hashCode = 31 * hashCode + i.next().hashCode();
#else
hashCode = 31 * hashCode + KEY_TO_HASH(i.NEXT());
#endif
return hashCode;
}
@Override
public LIST KEY_GENERIC_TYPE subList(int fromIndex, int toIndex) {
return new SUB_LIST(this, fromIndex, toIndex);
}
@Override
public ITERATOR KEY_GENERIC_TYPE iterator() {
return listIterator(0);
}
@Override
public LIST_ITERATOR KEY_GENERIC_TYPE listIterator() {
return listIterator(0);
}
@Override
public LIST_ITERATOR KEY_GENERIC_TYPE listIterator(int index) {
return new LIST_ITER(index);
}
@Override
public void size(int size) {
while(size > size()) add(EMPTY_KEY_VALUE);
while(size < size()) REMOVE(size() - 1);
}
private class SUB_LIST extends ABSTRACT_LIST KEY_GENERIC_TYPE {
ABSTRACT_LIST KEY_GENERIC_TYPE l;
int offset;
int size;
SUB_LIST(ABSTRACT_LIST KEY_GENERIC_TYPE l, int from, int to) {
if (from < 0) throw new IndexOutOfBoundsException("fromIndex = " + from);
else if (to > l.size()) throw new IndexOutOfBoundsException("toIndex = " + to);
else if (from > to) throw new IllegalArgumentException("fromIndex(" + from + ") > toIndex(" + to + ")");
this.l = l;
offset = from;
size = to - from;
}
@Override
public void add(int index, KEY_TYPE e) {
checkAddRange(index);
l.add(index+offset, e);
size++;
}
@Override
public boolean addAll(int index, Collection<? extends CLASS_TYPE> c) {
checkAddRange(index);
int size = c.size();
if(size == 0) return false;
l.addAll(index + offset, l);
offset += size;
return true;
}
@Override
public boolean addAll(int index, COLLECTION KEY_GENERIC_TYPE c) {
checkAddRange(index);
int size = c.size();
if(size == 0) return false;
l.addAll(index + offset, l);
offset += size;
return true;
}
@Override
public boolean addAll(int index, LIST KEY_GENERIC_TYPE c) {
checkAddRange(index);
int size = c.size();
if(size == 0) return false;
l.addAll(index + offset, l);
offset += size;
return true;
}
@Override
public void addElements(int from, KEY_TYPE[] a, int offset, int length) {
checkRange(from);
l.addElements(from + this.offset, a, offset, length);
size += length;
}
@Override
public KEY_TYPE[] getElements(int from, KEY_TYPE[] a, int offset, int length) {
checkRange(from);
return l.getElements(from + this.offset, a, offset, length);
}
@Override
public void removeElements(int from, int to) {
checkRange(from);
checkRange(to);
l.removeElements(from + offset, to + offset);
size -= to - from;
}
#if TYPE_OBJECT
@Override
public <K> K[] extractElements(int from, int to, Class<K> clz) {
checkRange(from);
checkRange(to);
K[] a = l.extractElements(from + offset, to + offset, clz);
size -= to - from;
return a;
}
#else
@Override
public KEY_TYPE[] extractElements(int from, int to) {
checkRange(from);
checkRange(to);
KEY_TYPE[] a = l.extractElements(from + offset, to + offset);
size -= to - from;
return a;
}
#endif
@Override
public KEY_TYPE GET_KEY(int index) {
checkRange(index);
return l.GET_KEY(index + offset);
}
@Override
public KEY_TYPE set(int index, KEY_TYPE e) {
checkRange(index);
return l.set(index + offset, e);
}
@Override
public KEY_TYPE REMOVE(int index) {
checkRange(index);
size--;
return l.REMOVE(index + offset);
}
@Override
public int size() {
return size;
}
private void checkRange(int index) {
if (index < 0 || index >= size)
throw new IndexOutOfBoundsException("Index: " + index + ", Size: " + size);
}
private void checkAddRange(int index) {
if (index < 0 || index > size)
throw new IndexOutOfBoundsException("Index: " + index + ", Size: " + size);
}
}
private class LIST_ITER implements LIST_ITERATOR KEY_GENERIC_TYPE {
int index;
int lastReturned = -1;
LIST_ITER(int index) {
this.index = index;
}
@Override
public boolean hasNext() {
return index < size();
}
@Override
public KEY_TYPE NEXT() {
lastReturned = index;
return GET_KEY(index++);
}
@Override
public boolean hasPrevious() {
return index > 0;
}
@Override
public KEY_TYPE PREVIOUS() {
lastReturned = index;
return GET_KEY(index--);
}
@Override
public int nextIndex() {
return index;
}
@Override
public int previousIndex() {
return index-1;
}
@Override
public void remove() {
if(lastReturned == -1)
throw new IllegalStateException();
ABSTRACT_LIST.this.REMOVE(lastReturned);
if(lastReturned < index)
index--;
lastReturned = -1;
}
@Override
public void set(KEY_TYPE e) {
if(lastReturned == -1)
throw new IllegalStateException();
ABSTRACT_LIST.this.set(lastReturned, e);
}
@Override
public void add(KEY_TYPE e) {
if(lastReturned == -1)
throw new IllegalStateException();
ABSTRACT_LIST.this.add(index++, e);
lastReturned = -1;
}
@Override
public int skip(int amount) {
if(amount < 0) throw new IllegalStateException("Negative Numbers are not allowed");
int steps = Math.min(amount, (size() - 1) - index);
index += steps;
return steps;
}
@Override
public int back(int amount) {
if(amount < 0) throw new IllegalStateException("Negative Numbers are not allowed");
int steps = Math.min(amount, index);
index -= steps;
return steps;
}
}
}
@@ -0,0 +1,909 @@
package speiger.src.collections.PACKAGE.lists;
import java.util.Arrays;
#if TYPE_OBJECT
import java.util.Comparator;
#endif
import java.util.Collection;
import java.util.Iterator;
import java.util.Objects;
#if TYPE_OBJECT
import java.util.function.Consumer;
#endif
import java.util.function.Predicate;
import java.util.function.UnaryOperator;
#if PRIMITIVES
import java.util.function.JAVA_PREDICATE;
import java.util.function.JAVA_UNARY_OPERATOR;
#endif
import speiger.src.collections.PACKAGE.collections.COLLECTION;
#if !TYPE_OBJECT
import speiger.src.collections.PACKAGE.collections.STACK;
#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.PACKAGE.utils.ARRAYS;
import speiger.src.collections.PACKAGE.utils.ITERATORS;
#if TYPE_OBJECT
import speiger.src.collections.utils.Stack;
#else
import speiger.src.collections.objects.utils.ObjectArrays;
#endif
import speiger.src.collections.PACKAGE.utils.IARRAY;
import speiger.src.collections.utils.SanityChecks;
#if TYPE_OBJECT
/**
* A Type-Specific Array-based implementation of list that is written to reduce (un)boxing
*
* <p>This implementation is optimized to improve how data is processed with interfaces like {@link IARRAY}, {@link Stack}
* and with optimized functions that use type-specific implementations for primitives and optimized logic for bulkactions.
*/
public class ARRAY_LIST KEY_GENERIC_TYPE extends ABSTRACT_LIST KEY_GENERIC_TYPE implements IARRAY<KEY_TYPE>, Stack<KEY_TYPE>
#else
/**
* A Type-Specific Array-based implementation of list that is written to reduce (un)boxing
*
* <p>This implementation is optimized to improve how data is processed with interfaces like {@link IARRAY}, {@link STACK}
* and with optimized functions that use type-specific implementations for primitives and optimized logic for bulkactions.
*/
public class ARRAY_LIST KEY_GENERIC_TYPE extends ABSTRACT_LIST KEY_GENERIC_TYPE implements IARRAY, STACK
#endif
{
static final int DEFAULT_ARRAY_SIZE = 10;
/** The backing array */
protected transient KEY_TYPE[] data;
/** The current size of the elements stored in the backing array */
protected int size = 0;
/**
* Creates a new ArrayList with a Empty array.
*/
public ARRAY_LIST() {
data = EMPTY_KEY_ARRAY;
}
/**
* Creates a new ArrayList with the specific requested size
*/
public ARRAY_LIST(int size) {
data = NEW_KEY_ARRAY(size);
}
/**
* Creates a new ArrayList a copy with the contents of the Collection.
*/
public ARRAY_LIST(Collection<? extends CLASS_TYPE> c) {
this(c.size());
size = ITERATORS.unwrap(data, c.iterator());
}
/**
* Creates a new ArrayList a copy with the contents of the Collection.
*/
public ARRAY_LIST(COLLECTION KEY_GENERIC_TYPE c) {
this(c.size());
size = ITERATORS.unwrap(data, c.iterator());
}
/**
* Creates a new ArrayList a copy with the contents of the List.
*/
public ARRAY_LIST(LIST KEY_GENERIC_TYPE l) {
this(l.size());
size = l.size();
l.getElements(0, data, 0, size);
}
/**
* Creates a new ArrayList with a Copy of the array
*/
public ARRAY_LIST(KEY_TYPE[] a) {
this(a, 0, a.length);
}
/**
* Creates a new ArrayList with a Copy of the array with a custom length
*/
public ARRAY_LIST(KEY_TYPE[] a, int length) {
this(a, 0, length);
}
/**
* Creates a new ArrayList with a Copy of the array with in the custom range.
*/
public ARRAY_LIST(KEY_TYPE[] a, int offset, int length) {
this(length);
SanityChecks.checkArrayCapacity(a.length, offset, length);
System.arraycopy(a, offset, data, 0, length);
size = length;
}
/**
* Creates a wrapped arraylist that uses the array as backing array
*/
public static GENERIC_KEY_BRACES ARRAY_LIST KEY_GENERIC_TYPE wrap(KEY_TYPE[] a) {
return wrap(a, a.length);
}
/**
* Creates a wrapped arraylist that uses the array as backing array and a custom fillsize
*/
public static GENERIC_KEY_BRACES ARRAY_LIST KEY_GENERIC_TYPE wrap(KEY_TYPE[] a, int length) {
SanityChecks.checkArrayCapacity(a.length, 0, length);
ARRAY_LIST KEY_GENERIC_TYPE list = new ARRAY_LISTBRACES();
list.data = a;
list.size = length;
return list;
}
#if TYPE_OBJECT
/**
* Creates a new ArrayList with a EmptyObject array of the Type requested
*/
public static GENERIC_KEY_BRACES ARRAY_LIST KEY_GENERIC_TYPE of(Class<KEY_TYPE> c) {
ARRAY_LIST KEY_GENERIC_TYPE list = new ARRAY_LISTBRACES();
list.data = (KEY_TYPE[])ObjectArrays.newArray(c.getClass().getComponentType(), 0);
return list;
}
#endif
/**
* Appends the specified element to the end of this list.
*
* @param e element to be appended to this list
* @return <tt>true</tt> (as specified by {@link Collection#add})
*/
@Override
public boolean add(KEY_TYPE e) {
grow(size + 1);
data[size++] = e;
return true;
}
/**
* Appends the specified element to the end of this Stack.
* @param e element to be appended to this Stack
*/
@Override
public void PUSH(KEY_TYPE e) {
add(e);
}
/**
* Appends the specified element to the index of the list
* @param index the index where to append the element to
* @param e the element to append to the list
* @throws IndexOutOfBoundsException if index is outside of the lists range
*/
@Override
public void add(int index, KEY_TYPE e) {
checkAddRange(index);
grow(size + 1);
if(index != size) System.arraycopy(data, index, data, index+1, size - index);
data[index] = e;
size++;
}
/**
* Appends the specified elements to the index of the list.
* This function may delegate to more appropiate function if nessesary
* @param index the index where to append the elements to
* @param e the elements to append to the list
* @throws IndexOutOfBoundsException if index is outside of the lists range
* @deprecated if type is primitive
*/
@Override
@Primitive
public boolean addAll(int index, Collection<? extends CLASS_TYPE> c) {
if(c instanceof COLLECTION) return addAll(index, (COLLECTION KEY_GENERIC_TYPE)c);
int add = c.size();
if(add <= 0) return false;
grow(size + add);
if(index != size) System.arraycopy(data, index, data, index+add, size - index);
size+=add;
Iterator<? extends CLASS_TYPE> iter = c.iterator();
while(add != 0) data[index++] = OBJ_TO_KEY(iter.next());
return true;
}
/**
* Appends the specified elements to the index of the list.
* This function may delegate to more appropiate function if nessesary
* @param index the index where to append the elements to
* @param e the elements to append to the list
* @throws IndexOutOfBoundsException if index is outside of the lists range
* @deprecated if type is primitive
*/
@Override
public boolean addAll(int index, COLLECTION KEY_GENERIC_TYPE c) {
if(c instanceof LIST) return addAll(index, (LIST KEY_GENERIC_TYPE)c);
int add = c.size();
if(add <= 0) return false;
grow(size + add);
if(index != size) System.arraycopy(data, index, data, index+add, size - index);
size+=add;
ITERATOR KEY_GENERIC_TYPE iter = c.iterator();
while(add-- != 0) data[index++] = iter.NEXT();
return true;
}
/**
* Appends the specified elements to the index of the list.
* @param index the index where to append the elements to
* @param e the elements to append to the list
* @throws IndexOutOfBoundsException if index is outside of the lists range
* @deprecated if type is primitive
*/
@Override
public boolean addAll(int index, LIST KEY_GENERIC_TYPE c) {
int add = c.size();
if(add <= 0) return false;
checkAddRange(index);
grow(size + add);
if(index != size) System.arraycopy(data, index, data, index+add, size - index);
size+=add;
c.getElements(0, data, index, c.size());
return true;
}
/**
* Appends the specified array elements to the index of the list.
* @param from the index where to append the elements to
* @param a the elements to append to the list
* @param offset where to start ino the array
* @param length the amount of elements to insert
* @throws IndexOutOfBoundsException if index is outside of the lists range
* @deprecated if type is primitive
*/
@Override
public void addElements(int from, KEY_TYPE[] a, int offset, int length) {
if(length <= 0) return;
checkAddRange(from);
grow(size + length);
if(from != size) System.arraycopy(data, from, data, from+length, size - length);
size+=length;
System.arraycopy(a, offset, data, from, length);
}
/**
* A function to fast fetch elements from the list
* @param from index where the list should be fetching elements from
* @param a the array where the values should be inserted to
* @param offset the startIndex of where the array should be written to
* @param length the number of elements the values should be fetched from
* @returns the inputArray
* @throws NullPointerException if the array is null
* @throws IndexOutOfBoundsException if from is outside of the lists range
* @throws IllegalStateException if offset or length are smaller then 0 or exceed the array length
*/
@Override
public KEY_TYPE[] getElements(int from, KEY_TYPE[] a, int offset, int length) {
SanityChecks.checkArrayCapacity(size, offset, length);
System.arraycopy(data, from, a, offset, length);
return a;
}
/**
* a function to fast remove elements from the list.
* @param from the start index of where the elements should be removed from (inclusive)
* @param to the end index of where the elements should be removed to (exclusive)
*/
@Override
public void removeElements(int from, int to) {
checkRange(from);
checkAddRange(to);
int length = to - from;
if(length <= 0) return;
if(to != size) System.arraycopy(data, to, data, from, size - to);
#if TYPE_OBJECT
for(int i = 0;i<length;i++)
data[i+to] = null;
#endif
size -= length;
}
#if TYPE_OBJECT
/**
* A function to fast extract elements out of the list, this removes the elements that were fetched.
* @param from the start index of where the elements should be fetched from (inclusive)
* @param to the end index of where the elements should be fetched to (exclusive)
* @param type the type of the OutputArray
* @return a array of the elements that were fetched
*/
@Override
public <K> K[] extractElements(int from, int to, Class<K> type) {
checkRange(from);
checkAddRange(to);
int length = to - from;
K[] a = ARRAYS.newArray(type, length);
if(length <= 0) return a;
System.arraycopy(data, from, a, 0, length);
if(to != size) System.arraycopy(data, to, data, from, size - to);
for(int i = 0;i<length;i++)
data[i+to] = null;
size -= length;
return a;
}
#else
/**
* A function to fast extract elements out of the list, this removes the elements that were fetched.
* @param from the start index of where the elements should be fetched from (inclusive)
* @param to the end index of where the elements should be fetched to (exclusive)
* @return a array of the elements that were fetched
*/
@Override
public KEY_TYPE[] extractElements(int from, int to) {
int length = to - from;
if(length <= 0) return ARRAYS.EMPTY_ARRAY;
KEY_TYPE[] a = new KEY_TYPE[length];
System.arraycopy(data, from, a, 0, length);
if(to != size) System.arraycopy(data, to, data, from, size - to);
size -= length;
return a;
}
#endif
/**
* A function to find if the Element is present in this list.
* @param e the element that is searched for
* @return if the element was found.
* @deprecated if type-specific but still supported because of special edgecase Object-Comparason features
*/
@Override
@Primitive
public boolean contains(Object o) {
return indexOf(o) != -1;
}
/**
* A function to find the index of a given element
* @param e the element that is searched for
* @return the index of the element if found. (if not found then -1)
* @deprecated if type-specific but still supported because of special edgecase Object-Comparason features
*/
@Override
@Primitive
public int indexOf(Object o) {
#if TYPE_OBJECT
if(o == null) {
for(int i = 0;i<size;i++)
if(data[i] == null) return i;
return -1;
}
#else
if(o == null) return -1;
#endif
for(int i = 0;i<size;i++) {
if(EQUALS_KEY_TYPE(data[i], o)) return i;
}
return -1;
}
/**
* A function to find the last index of a given element
* @param e the element that is searched for
* @return the last index of the element if found. (if not found then -1)
* @deprecated if type-specific but still supported because of special edgecase Object-Comparason features
*/
@Override
@Primitive
public int lastIndexOf(Object o) {
#if TYPE_OBJECT
if(o == null) {
for(int i = size - 1;i>=0;i--)
if(data[i] == null) return i;
return -1;
}
#else
if(o == null) return -1;
#endif
for(int i = size - 1;i>=0;i--) {
if(EQUALS_KEY_TYPE(data[i], o)) return i;
}
return -1;
}
#if TYPE_OBJECT
/**
* Sorts the elements specified by the Natural order either by using the Comparator or the elements
* @see List#sort(Comparator)
* @see ARRAYS#stableSort(KEY_TYPE[], Comparator)
*/
@Override
public void sort(Comparator<? super CLASS_TYPE> c) {
if(c != null) ARRAYS.stableSort(data, size, c);
else ARRAYS.stableSort((Comparable[])data, size);
}
/**
* Sorts the elements specified by the Natural order either by using the Comparator or the elements using a unstable sort
* @see List#sort(Comparator)
* @see ARRAYS#unstableSort(KEY_TYPE[], Comparator)
*/
@Override
public void unstableSort(Comparator<? super CLASS_TYPE> c) {
if(c != null) ARRAYS.unstableSort(data, size, c);
else ARRAYS.unstableSort((Comparable[])data, size);
}
#else
/**
* A Type Specific implementation of the Collection#contains function.
* @param the element that is searched for.
* @returns if the element was found
*/
@Override
public boolean contains(KEY_TYPE e) {
return indexOf(e) != -1;
}
/**
* A Type-Specific function to find the index of a given element
* @param e the element that is searched for
* @return the index of the element if found. (if not found then -1)
*/
@Override
public int indexOf(KEY_TYPE e) {
for(int i = 0;i<size;i++) {
if(KEY_EQUALS(data[i], e)) return i;
}
return -1;
}
/**
* A Type-Specific function to find the last index of a given element
* @param e the element that is searched for
* @return the last index of the element if found. (if not found then -1)
*/
@Override
public int lastIndexOf(KEY_TYPE e) {
for(int i = size - 1;i>=0;i--) {
if(KEY_EQUALS(data[i], e)) return i;
}
return -1;
}
/**
* Sorts the elements specified by the Natural order either by using the Comparator or the elements
* @see List#sort(Comparator)
* @see ARRAYS#stableSort(KEY_TYPE[], Comparator)
*/
@Override
public void sort(COMPARATOR c) {
if(c != null) ARRAYS.stableSort(data, size, c);
else ARRAYS.stableSort(data, size);
}
/**
* Sorts the elements specified by the Natural order either by using the Comparator or the elements using a unstable sort
* @see List#sort(Comparator)
* @see ARRAYS#unstableSort(KEY_TYPE[], Comparator)
*/
@Override
public void unstableSort(COMPARATOR c) {
if(c != null) ARRAYS.unstableSort(data, size, c);
else ARRAYS.unstableSort(data, size);
}
#endif
/**
* A Type-Specific get function to reduce (un)boxing
* @param index the index of the element to fetch
* @return the value of the requested index
* @throws IndexOutOfBoundsException if the index is out of range
*/
@Override
public KEY_TYPE GET_KEY(int index) {
checkRange(index);
return data[index];
}
/**
* Provides the Selected Object from the stack.
* Top to bottom
* @param index of the element that should be provided
* @return the element that was requested
* @throws ArrayIndexOutOfBoundsException if the index is out of bounds
* @see Stack#peek(int)
*/
@Override
public KEY_TYPE PEEK(int index) {
checkRange((size() - 1) - index);
return data[(size() - 1) - index];
}
/**
* Provides the Underlying Array in the Implementation
* @return underlying Array
* @throws ClassCastException if the return type does not match the underlying array. (Only for Object Implementations)
*/
@Override
public KEY_TYPE[] elements() {
return data;
}
/**
* A Type Specific foreach function that reduces (un)boxing
*
* @implSpec
* <p>The default implementation behaves as if:
* <pre>{@code
* for(int i = 0;i<size;i++)
* action.accept(data[i]);
* }</pre>
*
* @param action The action to be performed for each element
* @throws NullPointerException if the specified action is null
* @see Iterable#forEach(Consumer)
*/
@Override
public void forEach(CONSUMER KEY_SUPER_GENERIC_TYPE action) {
Objects.requireNonNull(action);
for(int i = 0;i<size;i++)
action.accept(data[i]);
}
/**
* A Type-Specific set function to reduce (un)boxing
* @param index the index of the element to set
* @param e the value that should be set
* @return the previous element
* @throws IndexOutOfBoundsException if the index is out of range
*/
@Override
public KEY_TYPE set(int index, KEY_TYPE e) {
checkRange(index);
KEY_TYPE old = data[index];
data[index] = e;
return old;
}
/**
* A function to replace all values in the list
* @param o the action to replace the values
* @throws NullPointerException if o is null
*/
@Override
@Primitive
public void replaceAll(UnaryOperator<CLASS_TYPE> o) {
#if PRIMITIVES
Objects.requireNonNull(o);
#if TYPE_BYTE || TYPE_SHORT || TYPE_CHAR || TYPE_FLOAT
REPLACE(T -> OBJ_TO_KEY(o.apply(KEY_TO_OBJ(SanityChecks.SANITY_CAST(T)))));
#else
REPLACE(T -> OBJ_TO_KEY(o.apply(KEY_TO_OBJ(T))));
#endif
#else
Objects.requireNonNull(o);
for(int i = 0;i<size;i++)
data[i] = OBJ_TO_KEY(o.apply(KEY_TO_OBJ(data[i])));
#endif
}
#if PRIMITIVES
/**
* A Type-Specific replace function to reduce (un)boxing
* @param o the action to replace the values
* @throws NullPointerException if o is null
*/
@Override
public void REPLACE(JAVA_UNARY_OPERATOR o) {
for(int i = 0;i<size;i++)
#if TYPE_BYTE || TYPE_SHORT || TYPE_CHAR || TYPE_FLOAT
data[i] = SanityChecks.SANITY_CAST(o.APPLY_CAST(data[i]));
#else
data[i] = o.APPLY(data[i]);
#endif
}
#endif
/**
* A Type-Specific remove function to reduce (un)boxing
* @param index the index of the element to fetch
* @return the value of the requested index
* @throws IndexOutOfBoundsException if the index is out of range
*/
@Override
public KEY_TYPE REMOVE(int index) {
checkRange(index);
KEY_TYPE old = data[index];
size--;
if(index != size) System.arraycopy(data, index+1, data, index, size - index);
#if TYPE_OBJECT
data[size] = null;
#endif
return old;
}
#if !TYPE_OBJECT
/**
* A Type-Specific implementation of remove. This implementation iterates over the elements until it finds the element that is searched for or it runs out of elements.
* It stops after finding the first element
* @param e the element that is searched for
* @return true if the element was found and removed.
*/
@Override
public boolean REMOVE_KEY(KEY_TYPE type) {
int index = indexOf(type);
if(index == -1) return false;
REMOVE(index);
return true;
}
#endif
/**
* A Type-Specific pop function to reduce (un)boxing
* @param index the index of the element to fetch
* @return the value of the requested index
* @throws IndexOutOfBoundsException if the index is out of range
*/
@Override
public KEY_TYPE POP() {
return REMOVE(size() - 1);
}
/**
* A function to remove all elements that were provided in the other collection
* This function might delegate to a more appropiate function if nessesary
* @param c the elements that should be removed
* @return true if the collection was modified
* @throws NullPointerException if the collection is null
* @deprecated if the collection is type-specific
*/
@Override
@Primitive
public boolean removeAll(Collection<?> c) {
if(c.isEmpty()) return false;
boolean modified = false;
int j = 0;
for(int i = 0;i<size;i++) {
if(!c.contains(KEY_TO_OBJ(data[i]))) data[j++] = data[i];
else modified = true;
}
#if TYPE_OBJECT
Arrays.fill(data, j, size, null);
#endif
size = j;
return modified;
}
/**
* A function to retain all elements that were provided in the other collection
* This function might delegate to a more appropiate function if nessesary
* @param c the elements that should be kept. If empty, ARRAY_LIST#clear is called.
* @return true if the collection was modified
* @throws NullPointerException if the collection is null
* @deprecated if the collection is type-specific
*/
@Override
@Primitive
public boolean retainAll(Collection<?> c) {
if(c.isEmpty()) {
boolean modifed = size > 0;
clear();
return modifed;
}
boolean modified = false;
int j = 0;
for(int i = 0;i<size;i++) {
if(c.contains(KEY_TO_OBJ(data[i]))) data[j++] = data[i];
else modified = true;
}
#if TYPE_OBJECT
Arrays.fill(data, j, size, null);
#endif
size = j;
return modified;
}
/**
* A optimized List#removeIf(Predicate) that more quickly removes elements from the list then the ArrayList implementation
* @param filter the filter to remove elements
* @return true if the list was modified
* @deprecated if Type-Specific, use #remIf instead
*/
@Override
@Primitive
public boolean removeIf(Predicate<? super CLASS_TYPE> filter) {
Objects.requireNonNull(filter);
boolean modified = false;
int j = 0;
for(int i = 0;i<size;i++) {
if(!filter.test(KEY_TO_OBJ(data[i]))) data[j++] = data[i];
else modified = true;
}
#if TYPE_OBJECT
Arrays.fill(data, j, size, null);
#endif
size = j;
return modified;
}
/**
* A function to remove all elements that were provided in the other collection
* @param c the elements that should be removed
* @return true if the collection was modified
* @throws NullPointerException if the collection is null
*/
@Override
public boolean removeAll(COLLECTION KEY_GENERIC_TYPE c) {
if(c.isEmpty()) return false;
boolean modified = false;
int j = 0;
for(int i = 0;i<size;i++) {
if(!c.contains(data[i])) data[j++] = data[i];
else modified = true;
}
#if TYPE_OBJECT
Arrays.fill(data, j, size, null);
#endif
size = j;
return modified;
}
/**
* A function to retain all elements that were provided in the other collection
* This function might delegate to a more appropiate function if nessesary
* @param c the elements that should be kept. If empty, ARRAY_LIST#clear is called.
* @return true if the collection was modified
* @throws NullPointerException if the collection is null
*/
@Override
public boolean retainAll(COLLECTION KEY_GENERIC_TYPE c) {
if(c.isEmpty()) {
boolean modifed = size > 0;
clear();
return modifed;
}
boolean modified = false;
int j = 0;
for(int i = 0;i<size;i++) {
if(c.contains(data[i])) data[j++] = data[i];
else modified = true;
}
#if TYPE_OBJECT
Arrays.fill(data, j, size, null);
#endif
size = j;
return modified;
}
#if PRIMITIVES
/**
* A optimized List#removeIf(Predicate) that more quickly removes elements from the list then the ArrayList implementation
* @param filter the filter to remove elements
* @return true if the list was modified
*/
@Override
public boolean remIf(JAVA_PREDICATE filter) {
Objects.requireNonNull(filter);
boolean modified = false;
int j = 0;
for(int i = 0;i<size;i++) {
if(!filter.test(data[i])) data[j++] = data[i];
else modified = true;
}
size = j;
return modified;
}
#endif
/**
* A toArray implementation that ensures the Array itself is a Object.
* @return a Array of the elements in the list
*/
@Override
@Primitive
public Object[] toArray() {
Object[] obj = new Object[size];
for(int i = 0;i<size;i++)
obj[i] = KEY_TO_OBJ(data[i]);
return obj;
}
/**
* A toArray implementation that ensures the Array itself is a Object.
* @param a original array. If null a Object array with the right size is created. If to small the Array of the same type is created with the right size
* @return a Array of the elements in the list
*/
@Override
@Primitive
public <E> E[] toArray(E[] a) {
if(a == null) a = (E[])new Object[size];
else if(a.length < size) a = (E[])ObjectArrays.newArray(a.getClass().getComponentType(), size);
for(int i = 0;i<size;i++)
a[i] = (E)KEY_TO_OBJ(data[i]);
return a;
}
#if !TYPE_OBJECT
@Override
public KEY_TYPE[] TO_ARRAY(KEY_TYPE[] a) {
if(a.length < size) a = new KEY_TYPE[size];
System.arraycopy(data, 0, a, 0, size);
return a;
}
#endif
/**
* A function to return the size of the list
* @return the size of elements in the list
*/
@Override
public int size() {
return size;
}
/**
* A function to ensure the elements are within the requested size.
* If smaller then the stored elements they get removed as needed.
* If bigger it is ensured that enough room is provided depending on the implementation
* @param size the requested amount of elements/room for elements
*/
@Override
public void size(int size) {
if(size > data.length)
data = Arrays.copyOf(data, size);
else if(size < size() && size >= 0)
Arrays.fill(data, size, size(), EMPTY_KEY_VALUE);
this.size = size;
}
/**
* A function to clear all elements in the list.
*/
@Override
public void clear() {
#if TYPE_OBJECT
for(int i = 0;i<size;data[i] = null,i++);
#endif
size = 0;
}
/**
* Trims the original collection down to the size of the current elements or the requested size depending which is bigger
* @param size the requested trim size.
*/
@Override
public boolean trim(int size) {
if(size > size() || size() == data.length) return false;
int value = Math.max(size, size());
data = value == 0 ? EMPTY_KEY_ARRAY : Arrays.copyOf(data, value);
return true;
}
/**
* Increases the capacity of this implementation instance, if necessary,
* to ensure that it can hold at least the number of elements specified by
* the minimum capacity argument.
*
* @param size the desired minimum capacity
*/
@Override
public void ensureCapacity(int size) {
grow(size);
}
protected void grow(int capacity) {
if(capacity < data.length) return;
data = Arrays.copyOf(data, data == ARRAYS.EMPTY_ARRAY ? DEFAULT_ARRAY_SIZE : (int)Math.max(Math.min((long)data.length + (data.length >> 1), SanityChecks.MAX_ARRAY_SIZE), capacity));
}
protected void checkRange(int index) {
if (index < 0 || index >= size)
throw new IndexOutOfBoundsException("Index: " + index + ", Size: " + size);
}
protected void checkAddRange(int index) {
if (index < 0 || index > size)
throw new IndexOutOfBoundsException("Index: " + index + ", Size: " + size);
}
}
@@ -0,0 +1,426 @@
package speiger.src.collections.PACKAGE.lists;
import java.util.List;
#if !TYPE_OBJECT && !TYPE_BOOLEAN
import java.util.Objects;
import java.util.function.JAVA_UNARY_OPERATOR;
import java.util.function.UnaryOperator;
#else if TYPE_OBJECT
import java.util.Objects;
import java.util.function.UnaryOperator;
#endif
import java.util.Comparator;
import speiger.src.collections.PACKAGE.collections.COLLECTION;
#if !TYPE_OBJECT
import speiger.src.collections.PACKAGE.functions.COMPARATOR;
#endif
import speiger.src.collections.PACKAGE.utils.ARRAYS;
#if TYPE_BYTE || TYPE_SHORT || TYPE_CHAR || TYPE_FLOAT
import speiger.src.collections.utils.SanityChecks;
#endif
public interface LIST KEY_GENERIC_TYPE extends COLLECTION KEY_GENERIC_TYPE, List<CLASS_TYPE>
{
#if !TYPE_OBJECT
/**
* A Type-Specific add Function to reduce (un)boxing
* @param e the element to add
* @return true if the list was modified
* @see List#add(Object)
*/
@Override
public boolean add(KEY_TYPE e);
/**
* A Type-Specific add Function to reduce (un)boxing
* @param e the element to add
* @param index index at which the specified element is to be inserted
* @see List#add(int, Object)
*/
public void add(int index, KEY_TYPE e);
#endif
/**
* A Type-Specific addAll Function to reduce (un)boxing
* @param c the elements that need to be added
* @param index index at which the specified elements is to be inserted
* @return true if the list was modified
* @see List#addAll(int, Object)
*/
public boolean addAll(int index, COLLECTION KEY_GENERIC_TYPE c);
/**
* A Type-Specific and optimized addAll function that allows a faster transfer of elements
* @param c the elements that need to be added
* @return true if the list was modified
*/
public boolean addAll(LIST KEY_GENERIC_TYPE c);
/**
* A Type-Specific and optimized addAll function that allows a faster transfer of elements
* @param c the elements that need to be added
* @param index index at which the specified elements is to be inserted
* @return true if the list was modified
*/
public boolean addAll(int index, LIST KEY_GENERIC_TYPE c);
#if !TYPE_OBJECT
/**
* A Type-Specific get function to reduce (un)boxing
* @param index the index of the value that is requested
* @return the value at the given index
* @throws IndexOutOfBoundsException if the index is not within the list range
* @see List#get(int)
*/
public KEY_TYPE GET_KEY(int index);
/**
* A Type-Specific set function to reduce (un)boxing
* @param index index of the element to replace
* @param element element to be stored at the specified position
* @return the element previously at the specified position
* @throws IndexOutOfBoundsException if the index is not within the list range
* @see List#set(int, Object)
*/
public KEY_TYPE set(int index, KEY_TYPE e);
/**
* A Type-Specific remove function to reduce (un)boxing
* @param index the index of the element to be removed
* @return the element previously at the specified position
* @see List#remove(int)
*/
public KEY_TYPE REMOVE(int index);
/**
* A Type-Specific indexOf function to reduce (un)boxing
* @param e the element that is searched for
* @return the index of the element if found. (if not found then -1)
* @note does not support null values
*/
public int indexOf(KEY_TYPE e);
/**
* A Type-Specific lastIndexOf function to reduce (un)boxing
* @param e the element that is searched for
* @return the lastIndex of the element if found. (if not found then -1)
* @note does not support null values
*/
public int lastIndexOf(KEY_TYPE e);
#if !TYPE_BOOLEAN
/**
* A Type-Specific replace function to reduce (un)boxing
* @param o the action to replace the values
* @throws NullPointerException if o is null
*/
public default void REPLACE(JAVA_UNARY_OPERATOR o) {
Objects.requireNonNull(o);
LIST_ITERATOR iter = listIterator();
while (iter.hasNext())
#if TYPE_BYTE || TYPE_SHORT || TYPE_CHAR || TYPE_FLOAT
iter.set(SanityChecks.SANITY_CAST(o.APPLY_CAST(iter.NEXT())));
#else
iter.set(o.APPLY(iter.NEXT()));
#endif
}
#endif
#else
/**
* A function to replace all values in the list
* @param o the action to replace the values
* @throws NullPointerException if o is null
*/
@Override
public default void replaceAll(UnaryOperator<CLASS_TYPE> o) {
Objects.requireNonNull(o);
LIST_ITERATOR KEY_GENERIC_TYPE iter = listIterator();
while (iter.hasNext()) iter.set(o.apply(iter.NEXT()));
}
#endif
/**
* A function to fast add elements to the list
* @param from the index where the elements should be added into the list
* @param a the elements that should be added
* @throws IndexOutOfBoundsException if from is outside of the lists range
*/
public default void addElements(int from, KEY_TYPE[] a) { addElements(from, a, 0, a.length); }
/**
* A function to fast add elements to the list
* @param from the index where the elements should be added into the list
* @param a the elements that should be added
* @param offset the start index of the array should be read from
* @param length how many elements should be read from
* @throws IndexOutOfBoundsException if from is outside of the lists range
* @throws IllegalStateException if offset or length are smaller then 0 or exceed the array length
*/
public void addElements(int from, KEY_TYPE[] a, int offset, int length);
/**
* A function to fast fetch elements from the list
* @param from index where the list should be fetching elements from
* @param a the array where the values should be inserted to
* @returns the inputArray
* @throws NullPointerException if the array is null
* @throws IndexOutOfBoundsException if from is outside of the lists range
* @throws IllegalStateException if offset or length are smaller then 0 or exceed the array length
*/
public default KEY_TYPE[] getElements(int from, KEY_TYPE[] a) { return getElements(from, a, 0, a.length); }
/**
* A function to fast fetch elements from the list
* @param from index where the list should be fetching elements from
* @param a the array where the values should be inserted to
* @param offset the startIndex of where the array should be written to
* @param length the number of elements the values should be fetched from
* @returns the inputArray
* @throws NullPointerException if the array is null
* @throws IndexOutOfBoundsException if from is outside of the lists range
* @throws IllegalStateException if offset or length are smaller then 0 or exceed the array length
*/
public KEY_TYPE[] getElements(int from, KEY_TYPE[] a, int offset, int length);
/**
* a function to fast remove elements from the list.
* @param from the start index of where the elements should be removed from (inclusive)
* @param to the end index of where the elements should be removed to (exclusive)
*/
public void removeElements(int from, int to);
#if TYPE_OBJECT
/**
* A function to fast extract elements out of the list, this removes the elements that were fetched.
* @param from the start index of where the elements should be fetched from (inclusive)
* @param to the end index of where the elements should be fetched to (exclusive)
* @param type the type of the OutputArray
* @return a array of the elements that were fetched
*/
public <K> K[] extractElements(int from, int to, Class<K> type);
/**
* Sorts the elements specified by the Natural order either by using the Comparator or the elements
* @see List#sort(Comparator)
* @see ARRAYS#stableSort(KEY_TYPE[], Comparator)
*/
@Override
public default void sort(Comparator<? super CLASS_TYPE> c) {
KEY_TYPE[] array = (KEY_TYPE[])TO_ARRAY();
if(c != null) ARRAYS.stableSort(array, c);
else ARRAYS.stableSort((Comparable[])array);
LIST_ITERATOR KEY_GENERIC_TYPE iter = listIterator();
for (int i = 0,m=size();i<m && iter.hasNext();i++) {
iter.NEXT();
iter.set(array[i]);
}
}
/**
* Sorts the elements specified by the Natural order either by using the Comparator or the elements using a unstable sort
* @see List#sort(Comparator)
* @see ARRAYS#unstableSort(KEY_TYPE[], Comparator)
*/
public default void unstableSort(Comparator<? super CLASS_TYPE> c) {
KEY_TYPE[] array = (KEY_TYPE[])TO_ARRAY();
if(c != null) ARRAYS.unstableSort(array, c);
else ARRAYS.unstableSort((Comparable[])array);
LIST_ITERATOR KEY_GENERIC_TYPE iter = listIterator();
for (int i = 0,m=size();i<m && iter.hasNext();i++) {
iter.NEXT();
iter.set(array[i]);
}
}
#else
/**
* A function to fast extract elements out of the list, this removes the elements that were fetched.
* @param from the start index of where the elements should be fetched from (inclusive)
* @param to the end index of where the elements should be fetched to (exclusive)
* @return a array of the elements that were fetched
*/
public KEY_TYPE[] extractElements(int from, int to);
/** {@inheritDoc}
* <p>This default implementation delegates to the corresponding type-specific function.
* @deprecated Please use the corresponding type-specific function instead.
*/
@Override
@Deprecated
default void sort(Comparator<? super CLASS_TYPE> c) {
sort((K, V) -> c.compare(KEY_TO_OBJ(K), KEY_TO_OBJ(V)));
}
/**
* Sorts the elements specified by the Natural order either by using the Comparator or the elements
* @see List#sort(Comparator)
* @see ARRAYS#stableSort(KEY_TYPE[], Comparator)
*/
public default void sort(COMPARATOR c) {
KEY_TYPE[] array = TO_ARRAY();
if(c != null) ARRAYS.stableSort(array, c);
else ARRAYS.stableSort(array);
LIST_ITERATOR KEY_GENERIC_TYPE iter = listIterator();
for (int i = 0,m=size();i<m && iter.hasNext();i++) {
iter.NEXT();
iter.set(array[i]);
}
}
/** {@inheritDoc}
* <p>This default implementation delegates to the corresponding type-specific function.
* @deprecated Please use the corresponding type-specific function instead.
*/
@Deprecated
public default void unstableSort(Comparator<? super CLASS_TYPE> c) {
unstableSort((K, V) -> c.compare(KEY_TO_OBJ(K), KEY_TO_OBJ(V)));
}
/**
* Sorts the elements specified by the Natural order either by using the Comparator or the elements using a unstable sort
* @see List#sort(Comparator)
* @see ARRAYS#unstableSort(KEY_TYPE[], Comparator)
*/
public default void unstableSort(COMPARATOR c) {
KEY_TYPE[] array = TO_ARRAY();
if(c != null) ARRAYS.unstableSort(array, c);
else ARRAYS.unstableSort(array);
LIST_ITERATOR KEY_GENERIC_TYPE iter = listIterator();
for (int i = 0,m=size();i<m && iter.hasNext();i++) {
iter.NEXT();
iter.set(array[i]);
}
}
#endif
/**
* A Type-Specific Iterator of listIterator
* @see List#listIterator
*/
@Override
public LIST_ITERATOR KEY_GENERIC_TYPE listIterator();
/**
* A Type-Specific Iterator of listIterator
* @see List#listIterator(int)
*/
@Override
public LIST_ITERATOR KEY_GENERIC_TYPE listIterator(int index);
/**
* A Type-Specific List of subList
* @see List#subList(int, int)
*/
@Override
public LIST KEY_GENERIC_TYPE subList(int from, int to);
/**
* A function to ensure the elements are within the requested size.
* If smaller then the stored elements they get removed as needed.
* If bigger it is ensured that enough room is provided depending on the implementation
* @param size the requested amount of elements/room for elements
*/
public void size(int size);
#if !TYPE_OBJECT
/** {@inheritDoc}
* <p>This default implementation delegates to the corresponding type-specific function.
* @deprecated Please use the corresponding type-specific function instead.
*/
@Override
@Deprecated
public default boolean add(CLASS_TYPE e) {
return COLLECTION.super.add(e);
}
/** {@inheritDoc}
* <p>This default implementation delegates to the corresponding type-specific function.
* @deprecated Please use the corresponding type-specific function instead.
*/
@Override
@Deprecated
public default CLASS_TYPE get(int index) {
return KEY_TO_OBJ(GET_KEY(index));
}
/** {@inheritDoc}
* <p>This default implementation delegates to the corresponding type-specific function.
* @deprecated Please use the corresponding type-specific function instead.
*/
@Override
@Deprecated
public default CLASS_TYPE set(int index, CLASS_TYPE e) {
return KEY_TO_OBJ(set(index, OBJ_TO_KEY(e)));
}
/** {@inheritDoc}
* <p>This default implementation delegates to the corresponding type-specific function.
* @deprecated Please use the corresponding type-specific function instead.
*/
@Override
@Deprecated
public default int indexOf(Object o) {
return indexOf(CLASS_TO_KEY(o));
}
/** {@inheritDoc}
* <p>This default implementation delegates to the corresponding type-specific function.
* @deprecated Please use the corresponding type-specific function instead.
*/
@Override
@Deprecated
public default int lastIndexOf(Object o) {
return lastIndexOf(CLASS_TO_KEY(o));
}
/** {@inheritDoc}
* <p>This default implementation delegates to the corresponding type-specific function.
* @deprecated Please use the corresponding type-specific function instead.
*/
@Override
@Deprecated
public default boolean contains(Object o) {
return COLLECTION.super.contains(o);
}
/** {@inheritDoc}
* <p>This default implementation delegates to the corresponding type-specific function.
* @deprecated Please use the corresponding type-specific function instead.
*/
@Override
@Deprecated
public default boolean remove(Object o) {
return COLLECTION.super.remove(o);
}
/** {@inheritDoc}
* <p>This default implementation delegates to the corresponding type-specific function.
* @deprecated Please use the corresponding type-specific function instead.
*/
@Override
@Deprecated
public default CLASS_TYPE remove(int index) {
return KEY_TO_OBJ(REMOVE(index));
}
#if !TYPE_BOOLEAN
/** {@inheritDoc}
* <p>This default implementation delegates to the corresponding type-specific function.
* @deprecated Please use the corresponding type-specific function instead.
*/
@Override
@Deprecated
public default void replaceAll(UnaryOperator<CLASS_TYPE> o) {
Objects.requireNonNull(o);
#if TYPE_BYTE || TYPE_SHORT || TYPE_CHAR || TYPE_FLOAT
REPLACE(T -> OBJ_TO_KEY(o.apply(KEY_TO_OBJ((KEY_TYPE)T))));
#else
REPLACE(T -> OBJ_TO_KEY(o.apply(KEY_TO_OBJ(T))));
#endif
}
#endif
#endif
}
@@ -0,0 +1,62 @@
package speiger.src.collections.PACKAGE.lists;
import java.util.ListIterator;
import speiger.src.collections.PACKAGE.collections.BI_ITERATOR;
public interface LIST_ITERATOR KEY_GENERIC_TYPE extends ListIterator<CLASS_TYPE>, BI_ITERATOR KEY_GENERIC_TYPE
{
#if !TYPE_OBJECT
/**
* A Primitive set function to reduce (un)boxing
* @see ListIterator#set(Object)
*/
public void set(KEY_TYPE e);
/**
* A Primitive set function to reduce (un)boxing
* @see ListIterator#set(Object)
*/
public void add(KEY_TYPE e);
/** {@inheritDoc}
* <p>This default implementation delegates to the corresponding type-specific function.
* @deprecated Please use the corresponding type-specific function instead.
*/
@Override
@Deprecated
public default CLASS_TYPE previous() {
return BI_ITERATOR.super.previous();
}
/** {@inheritDoc}
* <p>This default implementation delegates to the corresponding type-specific function.
* @deprecated Please use the corresponding type-specific function instead.
*/
@Override
@Deprecated
public default CLASS_TYPE next() {
return BI_ITERATOR.super.next();
}
/** {@inheritDoc}
* <p>This default implementation delegates to the corresponding type-specific function.
* @deprecated Please use the corresponding type-specific function instead.
*/
@Override
@Deprecated
public default void set(CLASS_TYPE e) {
set(OBJ_TO_KEY(e));
}
/** {@inheritDoc}
* <p>This default implementation delegates to the corresponding type-specific function.
* @deprecated Please use the corresponding type-specific function instead.
*/
@Override
@Deprecated
public default void add(CLASS_TYPE e) {
add(OBJ_TO_KEY(e));
}
#endif
}
@@ -0,0 +1,405 @@
package speiger.src.collections.PACKAGE.maps.abstracts;
import java.util.AbstractMap;
import java.util.Map;
import java.util.Objects;
import speiger.src.collections.PACKAGE.collections.ITERATOR;
import speiger.src.collections.PACKAGE.functions.consumer.BI_CONSUMER;
import speiger.src.collections.PACKAGE.functions.function.FUNCTION;
import speiger.src.collections.PACKAGE.functions.function.UNARY_OPERATOR;
import speiger.src.collections.PACKAGE.maps.interfaces.MAP;
import speiger.src.collections.PACKAGE.sets.ABSTRACT_SET;
import speiger.src.collections.PACKAGE.sets.SET;
import speiger.src.collections.PACKAGE.utils.maps.MAPS;
import speiger.src.collections.VALUE_PACKAGE.collections.VALUE_ABSTRACT_COLLECTION;
import speiger.src.collections.VALUE_PACKAGE.collections.VALUE_COLLECTION;
#if !SAME_TYPE
import speiger.src.collections.VALUE_PACKAGE.collections.VALUE_ITERATOR;
import speiger.src.collections.VALUE_PACKAGE.functions.function.VALUE_UNARY_OPERATOR;
#endif
#if !TYPE_OBJECT && !VALUE_OBJECT
import speiger.src.collections.objects.collections.ObjectIterator;
#endif
#if !TYPE_OBJECT
import speiger.src.collections.objects.sets.ObjectSet;
#endif
public abstract class ABSTRACT_MAP KEY_VALUE_GENERIC_TYPE extends AbstractMap<CLASS_TYPE, CLASS_VALUE_TYPE> implements MAP KEY_VALUE_GENERIC_TYPE
{
protected VALUE_TYPE defaultReturnValue = EMPTY_VALUE;
@Override
public VALUE_TYPE getDefaultReturnValue() {
return defaultReturnValue;
}
@Override
public ABSTRACT_MAP KEY_VALUE_GENERIC_TYPE setDefaultReturnValue(VALUE_TYPE v) {
defaultReturnValue = v;
return this;
}
@Override
public void putAll(MAP KEY_VALUE_GENERIC_TYPE m) {
for(ObjectIterator<MAP.Entry KEY_VALUE_GENERIC_TYPE> iter = MAPS.fastIterator(m);iter.hasNext();) {
MAP.Entry KEY_VALUE_GENERIC_TYPE entry = iter.next();
put(entry.ENTRY_KEY(), entry.ENTRY_VALUE());
}
}
@Override
public void putAll(Map<? extends CLASS_TYPE, ? extends CLASS_VALUE_TYPE> m)
{
if(m instanceof MAP) putAll((MAP KEY_VALUE_GENERIC_TYPE)m);
else super.putAll(m);
}
#if TYPE_OBJECT
@Override
public boolean containsKey(Object key) {
for(ITERATOR KEY_GENERIC_TYPE iter = keySet().iterator();iter.hasNext();)
if(EQUALS_KEY_TYPE(iter.NEXT(), key)) return true;
return false;
}
#else
@Override
public boolean containsKey(KEY_TYPE key) {
for(ITERATOR KEY_GENERIC_TYPE iter = keySet().iterator();iter.hasNext();)
if(KEY_EQUALS(iter.NEXT(), key)) return true;
return false;
}
#endif
#if VALUE_OBJECT
@Override
public boolean containsValue(Object value) {
for(VALUE_ITERATOR VALUE_GENERIC_TYPE iter = values().iterator();iter.hasNext();)
if(EQUALS_VALUE_TYPE(iter.VALUE_NEXT(), value)) return true;
return false;
}
#else
@Override
public boolean containsValue(VALUE_TYPE value) {
for(VALUE_ITERATOR VALUE_GENERIC_TYPE iter = values().iterator();iter.hasNext();)
if(VALUE_EQUALS(iter.VALUE_NEXT(), value)) return true;
return false;
}
#endif
@Override
public boolean replace(KEY_TYPE key, VALUE_TYPE oldValue, VALUE_TYPE newValue) {
VALUE_TYPE curValue = get(key);
if (VALUE_EQUALS_NOT(curValue, oldValue) || (VALUE_EQUALS(curValue, getDefaultReturnValue()) && !containsKey(key))) {
return false;
}
put(key, newValue);
return true;
}
@Override
public VALUE_TYPE replace(KEY_TYPE key, VALUE_TYPE value) {
VALUE_TYPE curValue;
if (VALUE_EQUALS_NOT((curValue = get(key)), getDefaultReturnValue()) || containsKey(key)) {
curValue = put(key, value);
}
return curValue;
}
@Override
public void REPLACE_VALUES(UNARY_OPERATOR KEY_VALUE_GENERIC_TYPE mappingFunction) {
Objects.requireNonNull(mappingFunction);
for(ObjectIterator<MAP.Entry KEY_VALUE_GENERIC_TYPE> iter = MAPS.fastIterator(this);iter.hasNext();) {
MAP.Entry KEY_VALUE_GENERIC_TYPE entry = iter.next();
entry.setValue(mappingFunction.APPLY_VALUE(entry.ENTRY_KEY(), entry.ENTRY_VALUE()));
}
}
@Override
public VALUE_TYPE COMPUTE(KEY_TYPE key, UNARY_OPERATOR KEY_VALUE_GENERIC_TYPE mappingFunction) {
Objects.requireNonNull(mappingFunction);
VALUE_TYPE value = get(key);
VALUE_TYPE newValue = mappingFunction.APPLY_VALUE(key, value);
if(VALUE_EQUALS(newValue, getDefaultReturnValue())) {
if(VALUE_EQUALS_NOT(value, getDefaultReturnValue()) || containsKey(key)) {
remove(key);
return getDefaultReturnValue();
}
return getDefaultReturnValue();
}
put(key, newValue);
return newValue;
}
@Override
public VALUE_TYPE COMPUTE_IF_ABSENT(KEY_TYPE key, FUNCTION KEY_VALUE_GENERIC_TYPE mappingFunction) {
Objects.requireNonNull(mappingFunction);
VALUE_TYPE value;
if((value = get(key)) == getDefaultReturnValue()) {
VALUE_TYPE newValue = mappingFunction.GET_VALUE(key);
if(VALUE_EQUALS_NOT(newValue, getDefaultReturnValue())) {
put(key, newValue);
return newValue;
}
}
return value;
}
@Override
public VALUE_TYPE COMPUTE_IF_PRESENT(KEY_TYPE key, UNARY_OPERATOR KEY_VALUE_GENERIC_TYPE mappingFunction) {
Objects.requireNonNull(mappingFunction);
VALUE_TYPE value;
if(VALUE_EQUALS_NOT((value = get(key)), getDefaultReturnValue())) {
VALUE_TYPE newValue = mappingFunction.APPLY_VALUE(key, value);
if(VALUE_EQUALS_NOT(newValue, getDefaultReturnValue())) {
put(key, newValue);
return newValue;
}
remove(key);
}
return getDefaultReturnValue();
}
@Override
public VALUE_TYPE MERGE(KEY_TYPE key, VALUE_TYPE value, VALUE_UNARY_OPERATOR VALUE_VALUE_GENERIC_TYPE mappingFunction) {
Objects.requireNonNull(mappingFunction);
VALUE_TYPE oldValue = get(key);
VALUE_TYPE newValue = VALUE_EQUALS(oldValue, getDefaultReturnValue()) ? value : mappingFunction.APPLY_VALUE(oldValue, value);
if(VALUE_EQUALS(newValue, getDefaultReturnValue())) remove(key);
else put(key, newValue);
return newValue;
}
#if TYPE_OBJECT
@Override
public CLASS_VALUE_TYPE get(Object key) {
return VALUE_TO_OBJ(GET_VALUE((T)key));
}
@Override
public CLASS_VALUE_TYPE getOrDefault(Object key, CLASS_VALUE_TYPE defaultValue) {
CLASS_VALUE_TYPE value = get(key);
return VALUE_EQUALS_NOT(value, getDefaultReturnValue()) || containsKey(key) ? value : defaultValue;
}
#else
@Override
public CLASS_VALUE_TYPE get(Object key) {
return VALUE_TO_OBJ(key instanceof CLASS_TYPE ? GET_VALUE(CLASS_TO_KEY(key)) : getDefaultReturnValue());
}
@Override
public CLASS_VALUE_TYPE getOrDefault(Object key, CLASS_VALUE_TYPE defaultValue) {
return VALUE_TO_OBJ(key instanceof CLASS_TYPE ? getOrDefault(CLASS_TO_KEY(key), OBJ_TO_VALUE(defaultValue)) : getDefaultReturnValue());
}
@Override
public VALUE_TYPE getOrDefault(KEY_TYPE key, VALUE_TYPE defaultValue) {
VALUE_TYPE value = get(key);
return VALUE_EQUALS_NOT(value, getDefaultReturnValue()) || containsKey(key) ? value : defaultValue;
}
#endif
@Override
public void forEach(BI_CONSUMER KEY_VALUE_GENERIC_TYPE action) {
Objects.requireNonNull(action);
for(ObjectIterator<MAP.Entry KEY_VALUE_GENERIC_TYPE> iter = MAPS.fastIterator(this);iter.hasNext();) {
MAP.Entry KEY_VALUE_GENERIC_TYPE entry = iter.next();
action.accept(entry.ENTRY_KEY(), entry.ENTRY_VALUE());
}
}
@Override
public SET KEY_GENERIC_TYPE keySet() {
return new ABSTRACT_SET KEY_GENERIC_TYPE() {
#if !TYPE_OBJECT
@Override
public boolean remove(KEY_TYPE o) {
return VALUE_EQUALS_NOT(ABSTRACT_MAP.this.remove(o), getDefaultReturnValue());
}
#else
@Override
public boolean remove(Object o) {
return VALUE_EQUALS_NOT(ABSTRACT_MAP.this.remove(o), getDefaultReturnValue());
}
#endif
@Override
public boolean add(KEY_TYPE o) {
throw new UnsupportedOperationException();
}
@Override
public ITERATOR KEY_GENERIC_TYPE iterator() {
return new ITERATOR KEY_GENERIC_TYPE() {
ObjectIterator<MAP.Entry KEY_VALUE_GENERIC_TYPE> iter = MAPS.fastIterator(ABSTRACT_MAP.this);
@Override
public boolean hasNext() {
return iter.hasNext();
}
@Override
public KEY_TYPE NEXT() {
return iter.next().ENTRY_KEY();
}
@Override
public void remove() {
iter.remove();
}
};
}
@Override
public int size() {
return ABSTRACT_MAP.this.size();
}
@Override
public void clear() {
ABSTRACT_MAP.this.clear();
}
};
}
@Override
public VALUE_COLLECTION VALUE_GENERIC_TYPE values() {
return new VALUE_ABSTRACT_COLLECTION VALUE_GENERIC_TYPE() {
@Override
public boolean add(VALUE_TYPE o) {
throw new UnsupportedOperationException();
}
@Override
public int size() {
return ABSTRACT_MAP.this.size();
}
@Override
public void clear() {
ABSTRACT_MAP.this.clear();
}
@Override
public VALUE_ITERATOR VALUE_GENERIC_TYPE iterator() {
return new VALUE_ITERATOR VALUE_GENERIC_TYPE() {
ObjectIterator<MAP.Entry KEY_VALUE_GENERIC_TYPE> iter = MAPS.fastIterator(ABSTRACT_MAP.this);
@Override
public boolean hasNext() {
return iter.hasNext();
}
@Override
public VALUE_TYPE VALUE_NEXT() {
return iter.next().ENTRY_VALUE();
}
@Override
public void remove() {
iter.remove();
}
};
}
};
}
@Override
@SuppressWarnings("rawtypes")
public ObjectSet<Map.Entry<CLASS_TYPE, CLASS_VALUE_TYPE>> entrySet() {
return (ObjectSet)ENTRY_SET();
}
@Override
public boolean equals(Object o) {
if(o == this) return true;
if(o instanceof Map) {
if(size() != ((Map<?, ?>)o).size()) return false;
if(o instanceof MAP) return ENTRY_SET().containsAll(((MAP KEY_VALUE_GENERIC_TYPE)o).ENTRY_SET());
return ENTRY_SET().containsAll(((Map<?, ?>)o).entrySet());
}
return false;
}
@Override
public int hashCode() {
int hash = 0;
ObjectIterator<MAP.Entry KEY_VALUE_GENERIC_TYPE> iter = MAPS.fastIterator(this);
while(iter.hasNext()) hash += iter.next().hashCode();
return hash;
}
public static class BasicEntry KEY_VALUE_GENERIC_TYPE implements MAP.Entry KEY_VALUE_GENERIC_TYPE {
protected KEY_TYPE key;
protected VALUE_TYPE value;
public BasicEntry() {}
#if !TYPE_OBJECT
public BasicEntry(CLASS_TYPE key, CLASS_VALUE_TYPE value) {
this.key = OBJ_TO_KEY(key);
this.value = OBJ_TO_VALUE(value);
}
#endif
public BasicEntry(KEY_TYPE key, VALUE_TYPE value) {
this.key = key;
this.value = value;
}
public void set(KEY_TYPE key, VALUE_TYPE value) {
this.key = key;
this.value = value;
}
@Override
public KEY_TYPE ENTRY_KEY() {
return key;
}
@Override
public VALUE_TYPE ENTRY_VALUE() {
return value;
}
@Override
public VALUE_TYPE setValue(VALUE_TYPE value) {
throw new UnsupportedOperationException();
}
@Override
public boolean equals(Object obj) {
if(obj instanceof Map.Entry) {
if(obj instanceof MAP.Entry) {
MAP.Entry KEY_VALUE_GENERIC_TYPE entry = (MAP.Entry KEY_VALUE_GENERIC_TYPE)obj;
return KEY_EQUALS(key, entry.ENTRY_KEY()) && VALUE_EQUALS(value, entry.ENTRY_VALUE());
}
Map.Entry<?, ?> entry = (Map.Entry<?, ?>)obj;
Object key = entry.getKey();
Object value = entry.getValue();
#if TYPE_OBJECT && VALUE_OBJECT
return KEY_EQUALS(this.key, key) && VALUE_EQUALS(this.value, value);
#else if TYPE_OBJECT
return value instanceof CLASS_VALUE_TYPE && KEY_EQUALS(this.key, key) && VALUE_EQUALS(this.value, CLASS_TO_VALUE(value));
#else if VALUE_OBJECT
return key instanceof CLASS_TYPE && KEY_EQUALS(this.key, CLASS_TO_KEY(key)) && VALUE_EQUALS(this.value, value);
#else
return key instanceof CLASS_TYPE && value instanceof CLASS_VALUE_TYPE && KEY_EQUALS(this.key, CLASS_TO_KEY(key)) && VALUE_EQUALS(this.value, CLASS_TO_VALUE(value));
#endif
}
return false;
}
@Override
public int hashCode() {
return KEY_TO_HASH(key) ^ VALUE_TO_HASH(value);
}
@Override
public String toString() {
return KEY_TO_STRING(key) + "->" + VALUE_TO_STRING(value);
}
}
}
@@ -0,0 +1,999 @@
package speiger.src.collections.PACKAGE.maps.impl.customHash;
import java.util.Comparator;
import java.util.Map;
import java.util.NoSuchElementException;
import java.util.function.Consumer;
import speiger.src.collections.PACKAGE.collections.BI_ITERATOR;
#if !TYPE_OBJECT
import speiger.src.collections.PACKAGE.functions.COMPARATOR;
import speiger.src.collections.PACKAGE.functions.CONSUMER;
#endif
import speiger.src.collections.PACKAGE.functions.consumer.BI_CONSUMER;
import speiger.src.collections.PACKAGE.lists.LIST_ITERATOR;
import speiger.src.collections.PACKAGE.maps.interfaces.MAP;
import speiger.src.collections.PACKAGE.maps.interfaces.SORTED_MAP;
import speiger.src.collections.PACKAGE.sets.ABSTRACT_SET;
import speiger.src.collections.PACKAGE.sets.SORTED_SET;
import speiger.src.collections.PACKAGE.sets.SET;
import speiger.src.collections.PACKAGE.utils.STRATEGY;
import speiger.src.collections.VALUE_PACKAGE.collections.VALUE_ABSTRACT_COLLECTION;
import speiger.src.collections.VALUE_PACKAGE.collections.VALUE_COLLECTION;
import speiger.src.collections.VALUE_PACKAGE.collections.VALUE_ITERATOR;
#if !VALUE_OBJECT && !SAME_TYPE
import speiger.src.collections.VALUE_PACKAGE.functions.VALUE_CONSUMER;
import speiger.src.collections.VALUE_PACKAGE.lists.VALUE_LIST_ITERATOR;
#endif
#if !TYPE_OBJECT
import speiger.src.collections.objects.collections.ObjectBidirectionalIterator;
import speiger.src.collections.objects.lists.ObjectListIterator;
import speiger.src.collections.objects.sets.AbstractObjectSet;
import speiger.src.collections.objects.sets.ObjectSortedSet;
import speiger.src.collections.objects.sets.ObjectSet;
#endif
import speiger.src.collections.utils.HashUtil;
public class LINKED_CUSTOM_HASH_MAP KEY_VALUE_GENERIC_TYPE extends CUSTOM_HASH_MAP KEY_VALUE_GENERIC_TYPE implements SORTED_MAP KEY_VALUE_GENERIC_TYPE
{
protected transient long[] links;
protected int firstIndex = -1;
protected int lastIndex = -1;
public LINKED_CUSTOM_HASH_MAP(STRATEGY KEY_SUPER_GENERIC_TYPE strategy) {
this(HashUtil.DEFAULT_MIN_CAPACITY, HashUtil.DEFAULT_LOAD_FACTOR, strategy);
}
public LINKED_CUSTOM_HASH_MAP(int minCapacity, STRATEGY KEY_SUPER_GENERIC_TYPE strategy) {
this(minCapacity, HashUtil.DEFAULT_LOAD_FACTOR, strategy);
}
public LINKED_CUSTOM_HASH_MAP(int minCapacity, float loadFactor, STRATEGY KEY_SUPER_GENERIC_TYPE strategy) {
super(minCapacity, loadFactor, strategy);
links = new long[nullIndex + 1];
}
#if !TYPE_OBJECT || !VALUE_OBJECT
public LINKED_CUSTOM_HASH_MAP(CLASS_TYPE[] keys, CLASS_VALUE_TYPE[] values, STRATEGY KEY_SUPER_GENERIC_TYPE strategy) {
this(keys, values, HashUtil.DEFAULT_LOAD_FACTOR, strategy);
}
public LINKED_CUSTOM_HASH_MAP(CLASS_TYPE[] keys, CLASS_VALUE_TYPE[] values, float loadFactor, STRATEGY KEY_SUPER_GENERIC_TYPE strategy) {
this(keys.length, loadFactor, strategy);
if(keys.length != values.length) throw new IllegalStateException("Input Arrays are not equal size");
for(int i = 0,m=keys.length;i<m;i++) put(OBJ_TO_KEY(keys[i]), OBJ_TO_VALUE(values[i]));
}
#endif
public LINKED_CUSTOM_HASH_MAP(KEY_TYPE[] keys, VALUE_TYPE[] values, STRATEGY KEY_SUPER_GENERIC_TYPE strategy) {
this(keys, values, HashUtil.DEFAULT_LOAD_FACTOR, strategy);
}
public LINKED_CUSTOM_HASH_MAP(KEY_TYPE[] keys, VALUE_TYPE[] values, float loadFactor, STRATEGY KEY_SUPER_GENERIC_TYPE strategy) {
this(keys.length, loadFactor, strategy);
if(keys.length != values.length) throw new IllegalStateException("Input Arrays are not equal size");
for(int i = 0,m=keys.length;i<m;i++) put(keys[i], values[i]);
}
public LINKED_CUSTOM_HASH_MAP(Map<? extends CLASS_TYPE, ? extends CLASS_VALUE_TYPE> map, STRATEGY KEY_SUPER_GENERIC_TYPE strategy) {
this(map, HashUtil.DEFAULT_LOAD_FACTOR, strategy);
}
public LINKED_CUSTOM_HASH_MAP(Map<? extends CLASS_TYPE, ? extends CLASS_VALUE_TYPE> map, float loadFactor, STRATEGY KEY_SUPER_GENERIC_TYPE strategy) {
this(map.size(), loadFactor, strategy);
putAll(map);
}
public LINKED_CUSTOM_HASH_MAP(MAP KEY_VALUE_GENERIC_TYPE map, STRATEGY KEY_SUPER_GENERIC_TYPE strategy) {
this(map, HashUtil.DEFAULT_LOAD_FACTOR, strategy);
}
public LINKED_CUSTOM_HASH_MAP(MAP KEY_VALUE_GENERIC_TYPE map, float loadFactor, STRATEGY KEY_SUPER_GENERIC_TYPE strategy) {
this(map.size(), loadFactor, strategy);
putAll(map);
}
@Override
public VALUE_TYPE putAndMoveToFirst(KEY_TYPE key, VALUE_TYPE value) {
if(strategy.equals(key, EMPTY_KEY_VALUE)) {
if(containsNull) {
VALUE_TYPE lastValue = values[nullIndex];
values[nullIndex] = value;
moveToFirstIndex(nullIndex);
return lastValue;
}
values[nullIndex] = value;
containsNull = true;
onNodeAdded(nullIndex);
}
else {
int pos = HashUtil.mix(strategy.hashCode(key)) & mask;
while(!strategy.equals(keys[pos], EMPTY_KEY_VALUE)) {
if(strategy.equals(keys[pos], key)) {
VALUE_TYPE lastValue = values[pos];
values[pos] = value;
moveToFirstIndex(pos);
return lastValue;
}
pos = ++pos & mask;
}
keys[pos] = key;
values[pos] = value;
onNodeAdded(pos);
}
if(size++ >= maxFill) rehash(HashUtil.arraySize(size+1, loadFactor));
return getDefaultReturnValue();
}
@Override
public VALUE_TYPE putAndMoveToLast(KEY_TYPE key, VALUE_TYPE value) {
if(strategy.equals(key, EMPTY_KEY_VALUE)) {
if(containsNull) {
VALUE_TYPE lastValue = values[nullIndex];
values[nullIndex] = value;
moveToLastIndex(nullIndex);
return lastValue;
}
values[nullIndex] = value;
containsNull = true;
onNodeAdded(nullIndex);
}
else {
int pos = HashUtil.mix(strategy.hashCode(key)) & mask;
while(!strategy.equals(keys[pos], EMPTY_KEY_VALUE)) {
if(strategy.equals(keys[pos], key)) {
VALUE_TYPE lastValue = values[pos];
values[pos] = value;
moveToLastIndex(pos);
return lastValue;
}
pos = ++pos & mask;
}
keys[pos] = key;
values[pos] = value;
onNodeAdded(pos);
}
if(size++ >= maxFill) rehash(HashUtil.arraySize(size+1, loadFactor));
return getDefaultReturnValue();
}
@Override
public boolean moveToFirst(KEY_TYPE key) {
if(strategy.equals(FIRST_ENTRY_KEY(), key)) return false;
if(strategy.equals(key, EMPTY_KEY_VALUE)) {
if(containsNull) {
moveToFirstIndex(nullIndex);
return true;
}
}
else {
int pos = HashUtil.mix(strategy.hashCode(key)) & mask;
while(!strategy.equals(keys[pos], EMPTY_KEY_VALUE)) {
if(strategy.equals(keys[pos], key)) {
moveToFirstIndex(pos);
return true;
}
pos = ++pos & mask;
}
}
return false;
}
@Override
public boolean moveToLast(KEY_TYPE key) {
if(strategy.equals(LAST_ENTRY_KEY(), key)) return false;
if(strategy.equals(key, EMPTY_KEY_VALUE)) {
if(containsNull) {
moveToLastIndex(nullIndex);
return true;
}
}
else {
int pos = HashUtil.mix(strategy.hashCode(key)) & mask;
while(!strategy.equals(keys[pos], EMPTY_KEY_VALUE)) {
if(strategy.equals(keys[pos], key)) {
moveToLastIndex(pos);
return true;
}
pos = ++pos & mask;
}
}
return false;
}
@Override
public VALUE_TYPE getAndMoveToFirst(KEY_TYPE key) {
int index = findIndex(key);
if(index < 0) return getDefaultReturnValue();
moveToFirstIndex(index);
return values[index];
}
@Override
public VALUE_TYPE getAndMoveToLast(KEY_TYPE key) {
int index = findIndex(key);
if(index < 0) return getDefaultReturnValue();
moveToLastIndex(index);
return values[index];
}
@Override
public COMPARATOR KEY_GENERIC_TYPE comparator() {
return null;
}
@Override
public SORTED_MAP KEY_VALUE_GENERIC_TYPE subMap(KEY_TYPE fromKey, KEY_TYPE toKey) { throw new UnsupportedOperationException(); }
@Override
public SORTED_MAP KEY_VALUE_GENERIC_TYPE headMap(KEY_TYPE toKey) { throw new UnsupportedOperationException(); }
@Override
public SORTED_MAP KEY_VALUE_GENERIC_TYPE tailMap(KEY_TYPE fromKey) { throw new UnsupportedOperationException(); }
@Override
public KEY_TYPE FIRST_ENTRY_KEY() {
if(size == 0) throw new NoSuchElementException();
return keys[firstIndex];
}
@Override
public KEY_TYPE POLL_FIRST_ENTRY_KEY() {
if(size == 0) throw new NoSuchElementException();
int pos = firstIndex;
firstIndex = (int)links[pos];
if(0 <= firstIndex) links[firstIndex] |= 0xFFFFFFFF00000000L;
KEY_TYPE result = keys[pos];
size--;
if(strategy.equals(result, EMPTY_KEY_VALUE)) {
containsNull = false;
keys[nullIndex] = EMPTY_KEY_VALUE;
values[nullIndex] = EMPTY_VALUE;
}
else shiftKeys(pos);
if(nullIndex > minCapacity && size < maxFill / 4 && nullIndex > HashUtil.DEFAULT_MIN_CAPACITY) rehash(nullIndex / 2);
return result;
}
@Override
public KEY_TYPE LAST_ENTRY_KEY() {
if(size == 0) throw new NoSuchElementException();
return keys[lastIndex];
}
@Override
public KEY_TYPE POLL_LAST_ENTRY_KEY() {
if(size == 0) throw new NoSuchElementException();
int pos = lastIndex;
lastIndex = (int)(links[pos] >>> 32);
if(0 <= lastIndex) links[lastIndex] |= 0xFFFFFFFFL;
KEY_TYPE result = keys[pos];
size--;
if(strategy.equals(result, EMPTY_KEY_VALUE)) {
containsNull = false;
keys[nullIndex] = EMPTY_KEY_VALUE;
values[nullIndex] = EMPTY_VALUE;
}
else shiftKeys(pos);
if(nullIndex > minCapacity && size < maxFill / 4 && nullIndex > HashUtil.DEFAULT_MIN_CAPACITY) rehash(nullIndex / 2);
return result;
}
@Override
public VALUE_TYPE FIRST_ENTRY_VALUE() {
if(size == 0) throw new NoSuchElementException();
return values[firstIndex];
}
@Override
public VALUE_TYPE LAST_ENTRY_VALUE() {
if(size == 0) throw new NoSuchElementException();
return values[lastIndex];
}
@Override
public ObjectSet<MAP.Entry KEY_VALUE_GENERIC_TYPE> ENTRY_SET() {
if(entrySet == null) entrySet = new MapEntrySet();
return entrySet;
}
@Override
public SET KEY_GENERIC_TYPE keySet() {
if(keySet == null) keySet = new KeySet();
return keySet;
}
@Override
public VALUE_COLLECTION VALUE_GENERIC_TYPE values() {
if(values == null) valuesC = new Values();
return valuesC;
}
@Override
public void forEach(BI_CONSUMER KEY_VALUE_GENERIC_TYPE action) {
int index = firstIndex;
while(index != -1){
action.accept(keys[index], values[index]);
index = (int)links[index];
}
}
@Override
public void clear() {
super.clear();
firstIndex = lastIndex = -1;
}
protected void moveToFirstIndex(int startPos) {
if(size == 1 || firstIndex == startPos) return;
if(lastIndex == startPos) {
lastIndex = (int)(links[startPos] >>> 32);
links[lastIndex] |= 0xFFFFFFFFL;
}
else {
long link = links[startPos];
int prev = (int)(link >>> 32);
int next = (int)link;
links[prev] ^= ((links[prev] ^ (link & 0xFFFFFFFFL)) & 0xFFFFFFFFL);
links[next] ^= ((links[next] ^ (link & 0xFFFFFFFF00000000L)) & 0xFFFFFFFF00000000L);
}
links[firstIndex] ^= ((links[firstIndex] ^ ((startPos & 0xFFFFFFFFL) << 32)) & 0xFFFFFFFF00000000L);
links[startPos] = 0xFFFFFFFF00000000L | (firstIndex & 0xFFFFFFFFL);
firstIndex = startPos;
}
protected void moveToLastIndex(int startPos) {
if(size == 1 || lastIndex == startPos) return;
if(firstIndex == startPos) {
firstIndex = (int)links[startPos];
links[lastIndex] |= 0xFFFFFFFF00000000L;
}
else {
long link = links[startPos];
int prev = (int)(link >>> 32);
int next = (int)link;
links[prev] ^= ((links[prev] ^ (link & 0xFFFFFFFFL)) & 0xFFFFFFFFL);
links[next] ^= ((links[next] ^ (link & 0xFFFFFFFF00000000L)) & 0xFFFFFFFF00000000L);
}
links[lastIndex] ^= ((links[lastIndex] ^ (startPos & 0xFFFFFFFFL)) & 0xFFFFFFFFL);
links[startPos] = ((lastIndex & 0xFFFFFFFFL) << 32) | 0xFFFFFFFFL;
lastIndex = startPos;
}
@Override
protected void onNodeAdded(int pos) {
if(size == 0) {
firstIndex = lastIndex = pos;
links[pos] = -1L;
}
else {
links[lastIndex] ^= ((links[lastIndex] ^ (pos & 0xFFFFFFFFL)) & 0xFFFFFFFFL);
links[pos] = ((lastIndex & 0xFFFFFFFFL) << 32) | 0xFFFFFFFFL;
lastIndex = pos;
}
}
@Override
protected void onNodeRemoved(int pos) {
if(size == 0) firstIndex = lastIndex = -1;
else if(firstIndex == pos) {
firstIndex = (int)links[pos];
if(0 <= firstIndex) links[firstIndex] |= 0xFFFFFFFF00000000L;
}
else if(lastIndex == pos) {
lastIndex = (int)(links[pos] >>> 32);
if(0 <= lastIndex) links[pos] |= 0xFFFFFFFFL;
}
else {
long link = links[pos];
int prev = (int)(link >>> 32);
int next = (int)link;
links[prev] ^= ((links[prev] ^ (link & 0xFFFFFFFFL)) & 0xFFFFFFFFL);
links[next] ^= ((links[next] ^ (link & 0xFFFFFFFF00000000L)) & 0xFFFFFFFF00000000L);
}
}
@Override
protected void onNodeMoved(int from, int to) {
if(size == 1) {
firstIndex = lastIndex = to;
links[to] = -1L;
}
else if(firstIndex == from) {
firstIndex = to;
links[(int)links[from]] ^= ((links[(int)links[from]] ^ ((to & 0xFFFFFFFFL) << 32)) & 0xFFFFFFFF00000000L);
links[to] = links[from];
}
else if(lastIndex == from) {
lastIndex = to;
links[(int)(links[from] >>> 32)] ^= ((links[(int)(links[from] >>> 32)] ^ (to & 0xFFFFFFFFL)) & 0xFFFFFFFFL);
links[to] = links[from];
}
else {
long link = links[from];
int prev = (int)(link >>> 32);
int next = (int)link;
links[prev] ^= ((links[prev] ^ (to & 0xFFFFFFFFL)) & 0xFFFFFFFFL);
links[next] ^= ((links[next] ^ ((to & 0xFFFFFFFFL) << 32)) & 0xFFFFFFFF00000000L);
links[to] = link;
}
}
@Override
protected void rehash(int newSize) {
int newMask = newSize - 1;
KEY_TYPE[] newKeys = NEW_KEY_ARRAY(newSize + 1);
VALUE_TYPE[] newValues = NEW_VALUE_ARRAY(newSize + 1);
long[] newLinks = new long[newSize + 1];
int newPrev = -1;
for(int j = size, i = firstIndex, pos = 0, prev = -1;j != 0;) {
if(strategy.equals(keys[i], EMPTY_KEY_VALUE)) pos = newSize;
else {
pos = HashUtil.mix(strategy.hashCode(keys[i])) & newMask;
while(!strategy.equals(newKeys[pos], EMPTY_KEY_VALUE)) pos = ++pos & newMask;
}
newKeys[pos] = keys[i];
newValues[pos] = values[i];
if(prev != -1) {
newLinks[newPrev] ^= ((newLinks[newPrev] ^ (pos & 0xFFFFFFFFL)) & 0xFFFFFFFFL);
newLinks[pos] ^= ((newLinks[pos] ^ ((newPrev & 0xFFFFFFFFL) << 32)) & 0xFFFFFFFF00000000L);
newPrev = pos;
}
else {
newPrev = firstIndex = pos;
newLinks[pos] = -1L;
}
i = (int)links[prev = i];
}
links = newLinks;
lastIndex = newPrev;
if(newPrev != -1) newLinks[newPrev] |= 0xFFFFFFFFL;
nullIndex = newSize;
mask = newMask;
maxFill = Math.min((int)Math.ceil(nullIndex * loadFactor), nullIndex - 1);
keys = newKeys;
}
private class MapEntrySet extends AbstractObjectSet<MAP.Entry KEY_VALUE_GENERIC_TYPE> implements SORTED_MAP.FastSortedSet KEY_VALUE_GENERIC_TYPE {
@Override
public boolean addAndMoveToFirst(MAP.Entry KEY_VALUE_GENERIC_TYPE o) { throw new UnsupportedOperationException(); }
@Override
public boolean addAndMoveToLast(MAP.Entry KEY_VALUE_GENERIC_TYPE o) { throw new UnsupportedOperationException(); }
@Override
public boolean moveToFirst(MAP.Entry KEY_VALUE_GENERIC_TYPE o) {
return LINKED_CUSTOM_HASH_MAP.this.moveToFirst(o.ENTRY_KEY());
}
@Override
public boolean moveToLast(MAP.Entry KEY_VALUE_GENERIC_TYPE o) {
return LINKED_CUSTOM_HASH_MAP.this.moveToLast(o.ENTRY_KEY());
}
@Override
public MAP.Entry KEY_VALUE_GENERIC_TYPE first() {
return new BasicEntryKV_BRACES(FIRST_ENTRY_KEY(), FIRST_ENTRY_VALUE());
}
@Override
public MAP.Entry KEY_VALUE_GENERIC_TYPE last() {
return new BasicEntryKV_BRACES(LAST_ENTRY_KEY(), LAST_ENTRY_VALUE());
}
@Override
public MAP.Entry KEY_VALUE_GENERIC_TYPE pollFirst() {
BasicEntry KEY_VALUE_GENERIC_TYPE entry = new BasicEntryKV_BRACES(FIRST_ENTRY_KEY(), FIRST_ENTRY_VALUE());
POLL_FIRST_ENTRY_KEY();
return entry;
}
@Override
public MAP.Entry KEY_VALUE_GENERIC_TYPE pollLast() {
BasicEntry KEY_VALUE_GENERIC_TYPE entry = new BasicEntryKV_BRACES(LAST_ENTRY_KEY(), LAST_ENTRY_VALUE());
POLL_LAST_ENTRY_KEY();
return entry;
}
@Override
public ObjectBidirectionalIterator<MAP.Entry KEY_VALUE_GENERIC_TYPE> iterator() {
return new EntryIterator();
}
@Override
public ObjectBidirectionalIterator<MAP.Entry KEY_VALUE_GENERIC_TYPE> iterator(MAP.Entry KEY_VALUE_GENERIC_TYPE fromElement) {
return new EntryIterator(fromElement.ENTRY_KEY());
}
@Override
public ObjectBidirectionalIterator<MAP.Entry KEY_VALUE_GENERIC_TYPE> fastIterator() {
return new FastEntryIterator();
}
@Override
public ObjectBidirectionalIterator<MAP.Entry KEY_VALUE_GENERIC_TYPE> fastIterator(KEY_TYPE fromElement) {
return new FastEntryIterator(fromElement);
}
@Override
public void forEach(Consumer<? super MAP.Entry KEY_VALUE_GENERIC_TYPE> action) {
int index = firstIndex;
while(index != -1){
action.accept(new BasicEntryKV_BRACES(keys[index], values[index]));
index = (int)links[index];
}
}
@Override
public void fastForEach(Consumer<? super MAP.Entry KEY_VALUE_GENERIC_TYPE> action) {
BasicEntry KEY_VALUE_GENERIC_TYPE entry = new BasicEntryKV_BRACES();
int index = firstIndex;
while(index != -1){
entry.set(keys[index], values[index]);
action.accept(entry);
index = (int)links[index];
}
}
@Override
@Deprecated
public boolean contains(Object o) {
if(o instanceof Map.Entry) {
if(o instanceof MAP.Entry) return LINKED_CUSTOM_HASH_MAP.this.containsKey(((MAP.Entry KEY_VALUE_GENERIC_TYPE)o).ENTRY_KEY());
return LINKED_CUSTOM_HASH_MAP.this.containsKey(((Map.Entry<?, ?>)o).getKey());
}
return false;
}
@Override
@Deprecated
public boolean remove(Object o) {
if(o instanceof Map.Entry) {
if(o instanceof MAP.Entry) {
MAP.Entry KEY_VALUE_GENERIC_TYPE entry = (MAP.Entry KEY_VALUE_GENERIC_TYPE)o;
return LINKED_CUSTOM_HASH_MAP.this.remove(entry.ENTRY_KEY(), entry.ENTRY_VALUE());
}
Map.Entry<?, ?> entry = (Map.Entry<?, ?>)o;
return LINKED_CUSTOM_HASH_MAP.this.remove(entry.getKey(), entry.getValue());
}
return false;
}
@Override
public int size() {
return LINKED_CUSTOM_HASH_MAP.this.size();
}
@Override
public void clear() {
LINKED_CUSTOM_HASH_MAP.this.clear();
}
@Override
public Comparator<MAP.Entry KEY_VALUE_GENERIC_TYPE> comparator() {
return null;
}
@Override
public ObjectSortedSet<MAP.Entry KEY_VALUE_GENERIC_TYPE> subSet(MAP.Entry KEY_VALUE_GENERIC_TYPE fromElement, MAP.Entry KEY_VALUE_GENERIC_TYPE toElement) { throw new UnsupportedOperationException(); }
@Override
public ObjectSortedSet<MAP.Entry KEY_VALUE_GENERIC_TYPE> headSet(MAP.Entry KEY_VALUE_GENERIC_TYPE toElement) { throw new UnsupportedOperationException(); }
@Override
public ObjectSortedSet<MAP.Entry KEY_VALUE_GENERIC_TYPE> tailSet(MAP.Entry KEY_VALUE_GENERIC_TYPE fromElement) { throw new UnsupportedOperationException(); }
}
private final class KeySet extends ABSTRACT_SET KEY_GENERIC_TYPE implements SORTED_SET KEY_GENERIC_TYPE {
#if TYPE_OBJECT
@Override
@Deprecated
public boolean contains(Object e) {
return containsKey(e);
}
@Override
public boolean remove(Object o) {
int oldSize = size;
remove(o);
return size != oldSize;
}
#else
@Override
public boolean contains(KEY_TYPE e) {
return containsKey(e);
}
@Override
public boolean remove(KEY_TYPE o) {
int oldSize = size;
remove(o);
return size != oldSize;
}
#endif
@Override
public boolean add(KEY_TYPE o) {
throw new UnsupportedOperationException();
}
@Override
public boolean addAndMoveToFirst(KEY_TYPE o) { throw new UnsupportedOperationException(); }
@Override
public boolean addAndMoveToLast(KEY_TYPE o) { throw new UnsupportedOperationException(); }
@Override
public boolean moveToFirst(KEY_TYPE o) {
return LINKED_CUSTOM_HASH_MAP.this.moveToFirst(o);
}
@Override
public boolean moveToLast(KEY_TYPE o) {
return LINKED_CUSTOM_HASH_MAP.this.moveToLast(o);
}
@Override
public LIST_ITERATOR KEY_GENERIC_TYPE iterator() {
return new KeyIterator();
}
@Override
public BI_ITERATOR KEY_GENERIC_TYPE iterator(KEY_TYPE fromElement) {
return new KeyIterator(fromElement);
}
@Override
public int size() {
return LINKED_CUSTOM_HASH_MAP.this.size();
}
@Override
public void clear() {
LINKED_CUSTOM_HASH_MAP.this.clear();
}
@Override
public KEY_TYPE FIRST_KEY() {
return FIRST_ENTRY_KEY();
}
@Override
public KEY_TYPE POLL_FIRST_KEY() {
return POLL_FIRST_ENTRY_KEY();
}
@Override
public KEY_TYPE LAST_KEY() {
return LAST_ENTRY_KEY();
}
@Override
public KEY_TYPE POLL_LAST_KEY() {
return POLL_LAST_ENTRY_KEY();
}
#if TYPE_OBJECT
@Override
public void forEach(Consumer KEY_SUPER_GENERIC_TYPE action) {
int index = firstIndex;
while(index != -1){
action.accept(keys[index]);
index = (int)links[index];
}
}
#else
@Override
public void forEach(CONSUMER KEY_SUPER_GENERIC_TYPE action) {
int index = firstIndex;
while(index != -1){
action.accept(keys[index]);
index = (int)links[index];
}
}
#endif
@Override
public COMPARATOR KEY_GENERIC_TYPE comparator() { return null; }
@Override
public SORTED_SET KEY_GENERIC_TYPE subSet(KEY_TYPE fromElement, KEY_TYPE toElement) { throw new UnsupportedOperationException(); }
@Override
public SORTED_SET KEY_GENERIC_TYPE headSet(KEY_TYPE toElement) { throw new UnsupportedOperationException(); }
@Override
public SORTED_SET KEY_GENERIC_TYPE tailSet(KEY_TYPE fromElement) { throw new UnsupportedOperationException(); }
}
private class Values extends VALUE_ABSTRACT_COLLECTION VALUE_GENERIC_TYPE {
#if VALUE_OBJECT
@Override
@Deprecated
public boolean contains(Object e) {
return containsValue(e);
}
#else
@Override
public boolean contains(VALUE_TYPE e) {
return containsValue(e);
}
#endif
@Override
public boolean add(VALUE_TYPE o) {
throw new UnsupportedOperationException();
}
@Override
public VALUE_ITERATOR VALUE_GENERIC_TYPE iterator() {
return new ValueIterator();
}
@Override
public int size() {
return LINKED_CUSTOM_HASH_MAP.this.size();
}
@Override
public void clear() {
LINKED_CUSTOM_HASH_MAP.this.clear();
}
#if VALUE_OBJECT
@Override
public void forEach(Consumer VALUE_SUPER_GENERIC_TYPE action) {
int index = firstIndex;
while(index != -1){
action.accept(values[index]);
index = (int)links[index];
}
}
#else
@Override
public void forEach(VALUE_CONSUMER VALUE_SUPER_GENERIC_TYPE action) {
int index = firstIndex;
while(index != -1){
action.accept(values[index]);
index = (int)links[index];
}
}
#endif
}
private class FastEntryIterator extends MapIterator implements ObjectListIterator<MAP.Entry KEY_VALUE_GENERIC_TYPE> {
MapEntry entry = new MapEntry(nextEntry());
public FastEntryIterator() {}
public FastEntryIterator(KEY_TYPE from) {
super(from);
}
@Override
public MAP.Entry KEY_VALUE_GENERIC_TYPE next() {
entry.index = nextEntry();
return entry;
}
@Override
public MAP.Entry KEY_VALUE_GENERIC_TYPE previous() {
entry.index = previousEntry();
return entry;
}
@Override
public void set(MAP.Entry KEY_VALUE_GENERIC_TYPE entry) { throw new UnsupportedOperationException(); }
@Override
public void add(MAP.Entry KEY_VALUE_GENERIC_TYPE entry) { throw new UnsupportedOperationException(); }
}
private class EntryIterator extends MapIterator implements ObjectListIterator<MAP.Entry KEY_VALUE_GENERIC_TYPE> {
MapEntry entry;
public EntryIterator() {}
public EntryIterator(KEY_TYPE from) {
super(from);
}
@Override
public MAP.Entry KEY_VALUE_GENERIC_TYPE next() {
return entry = new MapEntry(nextEntry());
}
@Override
public MAP.Entry KEY_VALUE_GENERIC_TYPE previous() {
return entry = new MapEntry(previousEntry());
}
@Override
public void remove() {
super.remove();
entry.index = -1;
}
@Override
public void set(MAP.Entry KEY_VALUE_GENERIC_TYPE entry) { throw new UnsupportedOperationException(); }
@Override
public void add(MAP.Entry KEY_VALUE_GENERIC_TYPE entry) { throw new UnsupportedOperationException(); }
}
private class KeyIterator extends MapIterator implements LIST_ITERATOR KEY_GENERIC_TYPE {
public KeyIterator() {}
public KeyIterator(KEY_TYPE from) {
super(from);
}
@Override
public KEY_TYPE PREVIOUS() {
return keys[previousEntry()];
}
@Override
public KEY_TYPE NEXT() {
return keys[nextEntry()];
}
@Override
public void set(KEY_TYPE e) { throw new UnsupportedOperationException(); }
@Override
public void add(KEY_TYPE e) { throw new UnsupportedOperationException(); }
}
private class ValueIterator extends MapIterator implements VALUE_LIST_ITERATOR VALUE_GENERIC_TYPE {
public ValueIterator() {}
@Override
public VALUE_TYPE VALUE_PREVIOUS() {
return values[previousEntry()];
}
@Override
public VALUE_TYPE VALUE_NEXT() {
return values[nextEntry()];
}
@Override
public void set(VALUE_TYPE e) { throw new UnsupportedOperationException(); }
@Override
public void add(VALUE_TYPE e) { throw new UnsupportedOperationException(); }
}
private class MapIterator {
int previous = -1;
int next = -1;
int current = -1;
int index = 0;
MapIterator() {
next = firstIndex;
}
MapIterator(KEY_TYPE from) {
if(strategy.equals(from, EMPTY_KEY_VALUE)) {
if(containsNull) {
next = (int) links[nullIndex];
previous = nullIndex;
}
else throw new NoSuchElementException("The null element is not in the set");
}
else if(keys[lastIndex] == from) {
previous = lastIndex;
index = size;
}
else {
int pos = HashUtil.mix(strategy.hashCode(from)) & mask;
while(!strategy.equals(keys[pos], EMPTY_KEY_VALUE)) {
if(strategy.equals(keys[pos], from)) {
next = (int)links[pos];
previous = pos;
break;
}
pos = ++pos & mask;
}
if(previous == -1 && next == -1)
throw new NoSuchElementException("The element was not found");
}
}
public boolean hasNext() {
return next != -1;
}
public boolean hasPrevious() {
return previous != -1;
}
public int nextIndex() {
ensureIndexKnown();
return index;
}
public int previousIndex() {
ensureIndexKnown();
return index - 1;
}
public void remove() {
if(current == -1) throw new IllegalStateException();
ensureIndexKnown();
if(current == previous) {
index--;
previous = (int)(links[current] >>> 32);
}
else next = (int)links[current];
size--;
if(previous == -1) firstIndex = next;
else links[previous] ^= ((links[previous] ^ (next & 0xFFFFFFFFL)) & 0xFFFFFFFFL);
if (next == -1) lastIndex = previous;
else links[next] ^= ((links[next] ^ ((previous & 0xFFFFFFFFL) << 32)) & 0xFFFFFFFF00000000L);
if(current == nullIndex) {
current = -1;
containsNull = false;
keys[nullIndex] = EMPTY_KEY_VALUE;
values[nullIndex] = EMPTY_VALUE;
}
else {
int slot, last, startPos = current;
current = -1;
KEY_TYPE current;
while(true) {
startPos = ((last = startPos) + 1) & mask;
while(true){
if(strategy.equals((current = keys[startPos]), EMPTY_KEY_VALUE)) {
keys[last] = EMPTY_KEY_VALUE;
values[last] = EMPTY_VALUE;
return;
}
slot = HashUtil.mix(strategy.hashCode(current)) & mask;
if(last <= startPos ? (last >= slot || slot > startPos) : (last >= slot && slot > startPos)) break;
startPos = ++startPos & mask;
}
keys[last] = current;
values[last] = values[startPos];
if(next == startPos) next = last;
if(previous == startPos) previous = last;
onNodeMoved(startPos, last);
}
}
}
public int previousEntry() {
if(!hasPrevious()) throw new NoSuchElementException();
current = previous;
previous = (int)(links[current] >> 32);
next = current;
if(index >= 0) index--;
return current;
}
public int nextEntry() {
if(!hasNext()) throw new NoSuchElementException();
current = next;
next = (int)(links[current]);
previous = current;
if(index >= 0) index++;
return current;
}
private void ensureIndexKnown() {
if(index == -1) {
if(previous == -1) {
index = 0;
}
else if(next == -1) {
index = size;
}
else {
index = 1;
for(int pos = firstIndex;pos != previous;pos = (int)links[pos], index++);
}
}
}
}
}
@@ -0,0 +1,782 @@
package speiger.src.collections.PACKAGE.maps.impl.customHash;
import java.util.Arrays;
import java.util.Map;
import java.util.NoSuchElementException;
import java.util.Objects;
import java.util.function.Consumer;
#if !TYPE_OBJECT
import speiger.src.collections.PACKAGE.collections.ITERATOR;
import speiger.src.collections.PACKAGE.functions.CONSUMER;
#endif
import speiger.src.collections.PACKAGE.functions.consumer.BI_CONSUMER;
import speiger.src.collections.PACKAGE.lists.ARRAY_LIST;
import speiger.src.collections.PACKAGE.lists.LIST;
import speiger.src.collections.PACKAGE.maps.abstracts.ABSTRACT_MAP;
import speiger.src.collections.PACKAGE.maps.interfaces.MAP;
#if !TYPE_OBJECT
import speiger.src.collections.PACKAGE.sets.ABSTRACT_SET;
import speiger.src.collections.PACKAGE.sets.SET;
#endif
import speiger.src.collections.PACKAGE.utils.STRATEGY;
import speiger.src.collections.VALUE_PACKAGE.collections.VALUE_ABSTRACT_COLLECTION;
import speiger.src.collections.VALUE_PACKAGE.collections.VALUE_COLLECTION;
#if !SAME_TYPE && !VALUE_OBJECT
import speiger.src.collections.VALUE_PACKAGE.collections.VALUE_ITERATOR;
import speiger.src.collections.VALUE_PACKAGE.functions.VALUE_CONSUMER;
#endif
import speiger.src.collections.objects.collections.ObjectIterator;
import speiger.src.collections.objects.sets.AbstractObjectSet;
import speiger.src.collections.objects.sets.ObjectSet;
import speiger.src.collections.utils.HashUtil;
public class CUSTOM_HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_GENERIC_TYPE
{
protected transient KEY_TYPE[] keys;
protected transient VALUE_TYPE[] values;
protected transient boolean containsNull;
protected transient int minCapacity;
protected transient int nullIndex;
protected transient int maxFill;
protected transient int mask;
protected transient FastEntrySet KEY_VALUE_GENERIC_TYPE entrySet;
protected transient SET KEY_GENERIC_TYPE keySet;
protected transient VALUE_COLLECTION VALUE_GENERIC_TYPE valuesC;
protected int size;
protected final float loadFactor;
protected final STRATEGY KEY_SUPER_GENERIC_TYPE strategy;
public CUSTOM_HASH_MAP(STRATEGY KEY_SUPER_GENERIC_TYPE strategy) {
this(HashUtil.DEFAULT_MIN_CAPACITY, HashUtil.DEFAULT_LOAD_FACTOR, strategy);
}
public CUSTOM_HASH_MAP(int minCapacity, STRATEGY KEY_SUPER_GENERIC_TYPE strategy) {
this(minCapacity, HashUtil.DEFAULT_LOAD_FACTOR, strategy);
}
public CUSTOM_HASH_MAP(int minCapacity, float loadFactor, STRATEGY KEY_SUPER_GENERIC_TYPE strategy) {
if(minCapacity < 0) throw new IllegalStateException("Minimum Capacity is negative. This is not allowed");
if(loadFactor <= 0 || loadFactor >= 1F) throw new IllegalStateException("Load Factor is not between 0 and 1");
this.loadFactor = loadFactor;
this.minCapacity = nullIndex = HashUtil.arraySize(minCapacity, loadFactor);
this.strategy = strategy;
mask = nullIndex - 1;
maxFill = Math.min((int)Math.ceil(nullIndex * loadFactor), nullIndex - 1);
keys = NEW_KEY_ARRAY(nullIndex + 1);
values = NEW_VALUE_ARRAY(nullIndex + 1);
}
#if !TYPE_OBJECT || !VALUE_OBJECT
public CUSTOM_HASH_MAP(CLASS_TYPE[] keys, CLASS_VALUE_TYPE[] values, STRATEGY KEY_SUPER_GENERIC_TYPE strategy) {
this(keys, values, HashUtil.DEFAULT_LOAD_FACTOR, strategy);
}
public CUSTOM_HASH_MAP(CLASS_TYPE[] keys, CLASS_VALUE_TYPE[] values, float loadFactor, STRATEGY KEY_SUPER_GENERIC_TYPE strategy) {
this(keys.length, loadFactor, strategy);
if(keys.length != values.length) throw new IllegalStateException("Input Arrays are not equal size");
for(int i = 0,m=keys.length;i<m;i++) put(OBJ_TO_KEY(keys[i]), OBJ_TO_VALUE(values[i]));
}
#endif
public CUSTOM_HASH_MAP(KEY_TYPE[] keys, VALUE_TYPE[] values, STRATEGY KEY_SUPER_GENERIC_TYPE strategy) {
this(keys, values, HashUtil.DEFAULT_LOAD_FACTOR, strategy);
}
public CUSTOM_HASH_MAP(KEY_TYPE[] keys, VALUE_TYPE[] values, float loadFactor, STRATEGY KEY_SUPER_GENERIC_TYPE strategy) {
this(keys.length, loadFactor, strategy);
if(keys.length != values.length) throw new IllegalStateException("Input Arrays are not equal size");
for(int i = 0,m=keys.length;i<m;i++) put(keys[i], values[i]);
}
public CUSTOM_HASH_MAP(Map<? extends CLASS_TYPE, ? extends CLASS_VALUE_TYPE> map, STRATEGY KEY_SUPER_GENERIC_TYPE strategy) {
this(map, HashUtil.DEFAULT_LOAD_FACTOR, strategy);
}
public CUSTOM_HASH_MAP(Map<? extends CLASS_TYPE, ? extends CLASS_VALUE_TYPE> map, float loadFactor, STRATEGY KEY_SUPER_GENERIC_TYPE strategy) {
this(map.size(), loadFactor, strategy);
putAll(map);
}
public CUSTOM_HASH_MAP(MAP KEY_VALUE_GENERIC_TYPE map, STRATEGY KEY_SUPER_GENERIC_TYPE strategy) {
this(map, HashUtil.DEFAULT_LOAD_FACTOR, strategy);
}
public CUSTOM_HASH_MAP(MAP KEY_VALUE_GENERIC_TYPE map, float loadFactor, STRATEGY KEY_SUPER_GENERIC_TYPE strategy) {
this(map.size(), loadFactor, strategy);
putAll(map);
}
@Override
public VALUE_TYPE put(KEY_TYPE key, VALUE_TYPE value) {
int slot = findIndex(key);
if(slot < 0) {
insert(-slot-1, key, value);
return getDefaultReturnValue();
}
VALUE_TYPE oldValue = values[slot];
values[slot] = value;
return oldValue;
}
@Override
public VALUE_TYPE putIfAbsent(KEY_TYPE key, VALUE_TYPE value) {
int slot = findIndex(key);
if(slot < 0) {
insert(-slot-1, key, value);
return getDefaultReturnValue();
}
return values[slot];
}
#if VALUE_PRIMITIVES
@Override
public VALUE_TYPE addTo(KEY_TYPE key, VALUE_TYPE value) {
int slot = findIndex(key);
if(slot < 0) {
insert(-slot-1, key, value);
return getDefaultReturnValue();
}
VALUE_TYPE oldValue = values[slot];
values[slot] += value;
return oldValue;
}
#endif
#if !TYPE_OBJECT
@Override
public boolean containsKey(KEY_TYPE key) {
return findIndex(key) >= 0;
}
#endif
@Override
@Deprecated
public boolean containsKey(Object key) {
return findIndex(key) >= 0;
}
#if !VALUE_OBJECT
@Override
public boolean containsValue(VALUE_TYPE value) {
if(VALUE_EQUALS(value, values[nullIndex])) return true;
for(int i = nullIndex-1;i >= 0;i--)
if(!strategy.equals(keys[i], EMPTY_KEY_VALUE) && VALUE_EQUALS(values[i], value)) return true;
return false;
}
#endif
@Override
@Deprecated
public boolean containsValue(Object value) {
if((value == null && VALUE_EQUALS(values[nullIndex], getDefaultReturnValue())) || EQUALS_VALUE_TYPE(values[nullIndex], value)) return true;
for(int i = nullIndex-1;i >= 0;i--)
if(!strategy.equals(keys[i], EMPTY_KEY_VALUE) && ((value == null && values[i] == getDefaultReturnValue()) || EQUALS_VALUE_TYPE(values[i], value))) return true;
return false;
}
@Override
public VALUE_TYPE REMOVE_KEY(KEY_TYPE key) {
int slot = findIndex(key);
if(slot < 0) return getDefaultReturnValue();
return removeIndex(slot);
}
@Override
@Deprecated
public CLASS_VALUE_TYPE remove(Object key) {
int slot = findIndex(key);
if(slot < 0) return VALUE_TO_OBJ(getDefaultReturnValue());
return removeIndex(slot);
}
#if !TYPE_OBJECT || !VALUE_OBJECT
@Override
public boolean remove(KEY_TYPE key, VALUE_TYPE value) {
if(strategy.equals(key, EMPTY_KEY_VALUE)) {
if(containsNull && VALUE_EQUALS(value, values[nullIndex])) {
removeNullIndex();
return true;
}
return false;
}
int pos = HashUtil.mix(strategy.hashCode(key)) & mask;
KEY_TYPE current = keys[pos];
if(strategy.equals(current, EMPTY_KEY_VALUE)) return false;
if(strategy.equals(current, key) && VALUE_EQUALS(value, values[pos])) {
removeIndex(pos);
return true;
}
while(true) {
if(strategy.equals((current = keys[pos = (++pos & mask)]), EMPTY_KEY_VALUE)) return false;
else if(strategy.equals(current, key) && VALUE_EQUALS(value, values[pos])) {
removeIndex(pos);
return true;
}
}
}
#endif
@Override
public boolean remove(Object key, Object value) {
Objects.requireNonNull(value);
if(key == null) {
if(containsNull && EQUALS_VALUE_TYPE(values[nullIndex], value)) {
removeNullIndex();
return true;
}
return false;
}
KEY_TYPE keyType = CLASS_TO_KEY(key);
int pos = HashUtil.mix(strategy.hashCode(keyType)) & mask;
KEY_TYPE current = keys[pos];
if(strategy.equals(current, EMPTY_KEY_VALUE)) return false;
if(strategy.equals(current, keyType) && EQUALS_VALUE_TYPE(values[pos], value)) {
removeIndex(pos);
return true;
}
while(true) {
if(strategy.equals((current = keys[pos = (++pos & mask)]), EMPTY_KEY_VALUE)) return false;
else if(strategy.equals(current, keyType) && EQUALS_VALUE_TYPE(values[pos], value)){
removeIndex(pos);
return true;
}
}
}
@Override
public VALUE_TYPE GET_VALUE(KEY_TYPE key) {
int slot = findIndex(key);
return slot < 0 ? getDefaultReturnValue() : values[slot];
}
@Override
public CLASS_VALUE_TYPE get(Object key) {
int slot = findIndex(key);
return VALUE_TO_OBJ(slot < 0 ? getDefaultReturnValue() : values[slot]);
}
#if TYPE_OBJECT && VALUE_OBJECT
@Override
public VALUE_TYPE getOrDefault(Object key, VALUE_TYPE defaultValue) {
int slot = findIndex(key);
return slot < 0 ? defaultValue : values[slot];
}
#else
@Override
public VALUE_TYPE getOrDefault(KEY_TYPE key, VALUE_TYPE defaultValue) {
int slot = findIndex(key);
return slot < 0 ? defaultValue : values[slot];
}
#endif
@Override
public ObjectSet<MAP.Entry KEY_VALUE_GENERIC_TYPE> ENTRY_SET() {
if(entrySet == null) entrySet = new MapEntrySet();
return entrySet;
}
@Override
public SET KEY_GENERIC_TYPE keySet() {
if(keySet == null) keySet = new KeySet();
return keySet;
}
@Override
public VALUE_COLLECTION VALUE_GENERIC_TYPE values() {
if(valuesC == null) valuesC = new Values();
return valuesC;
}
@Override
public void forEach(BI_CONSUMER KEY_VALUE_GENERIC_TYPE action) {
if(size() <= 0) return;
if(containsNull) action.accept(keys[nullIndex], values[nullIndex]);
for(int i = nullIndex-1;i>=0;i--) {
if(!strategy.equals(keys[i], EMPTY_KEY_VALUE)) action.accept(keys[i], values[i]);
}
}
@Override
public void clear() {
if(size == 0) return;
size = 0;
containsNull = false;
Arrays.fill(keys, EMPTY_KEY_VALUE);
Arrays.fill(values, EMPTY_VALUE);
}
#if !TYPE_OBJECT
protected int findIndex(KEY_TYPE key) {
if(KEY_EQUALS_NULL(key)) return containsNull ? nullIndex : -(nullIndex + 1);
int pos = HashUtil.mix(strategy.hashCode(key)) & mask;
KEY_TYPE current = keys[pos];
if(!strategy.equals(current, EMPTY_KEY_VALUE)) {
if(strategy.equals(current, key)) return pos;
while(!strategy.equals((current = keys[pos = (++pos & mask)]), EMPTY_KEY_VALUE))
if(strategy.equals(current, key)) return pos;
}
return -(pos + 1);
}
#endif
protected int findIndex(Object key) {
if(key == null) return containsNull ? nullIndex : -(nullIndex + 1);
KEY_TYPE keyType = CLASS_TO_KEY(key);
int pos = HashUtil.mix(strategy.hashCode(keyType)) & mask;
KEY_TYPE current = keys[pos];
if(!strategy.equals(current, EMPTY_KEY_VALUE)) {
if(strategy.equals(current, keyType)) return pos;
while(!strategy.equals((current = keys[pos = (++pos & mask)]), EMPTY_KEY_VALUE))
if(strategy.equals(current, keyType)) return pos;
}
return -(pos + 1);
}
protected VALUE_TYPE removeIndex(int pos) {
VALUE_TYPE value = values[pos];
size--;
onNodeRemoved(pos);
shiftKeys(pos);
if(nullIndex > minCapacity && size < maxFill / 4 && nullIndex > HashUtil.DEFAULT_MIN_CAPACITY) rehash(nullIndex / 2);
return value;
}
protected VALUE_TYPE removeNullIndex() {
VALUE_TYPE value = values[nullIndex];
containsNull = false;
keys[nullIndex] = EMPTY_KEY_VALUE;
values[nullIndex] = EMPTY_VALUE;
size--;
onNodeRemoved(nullIndex);
if(nullIndex > minCapacity && size < maxFill / 4 && nullIndex > HashUtil.DEFAULT_MIN_CAPACITY) rehash(nullIndex / 2);
return value;
}
protected void insert(int slot, KEY_TYPE key, VALUE_TYPE value) {
if(slot == nullIndex) containsNull = true;
keys[slot] = key;
values[slot] = value;
onNodeAdded(slot);
if(size++ >= maxFill) rehash(HashUtil.arraySize(size+1, loadFactor));
}
protected void rehash(int newSize) {
int newMask = newSize - 1;
KEY_TYPE[] newKeys = NEW_KEY_ARRAY(newSize + 1);
VALUE_TYPE[] newValues = NEW_VALUE_ARRAY(newSize + 1);
for(int i = nullIndex, pos = 0, j = (size - (containsNull ? 1 : 0));j-- != 0;) {
while(strategy.equals(keys[--i], EMPTY_KEY_VALUE));
if(!strategy.equals(newKeys[pos = HashUtil.mix(strategy.hashCode(keys[i])) & newMask], EMPTY_KEY_VALUE))
while(!strategy.equals(newKeys[pos = (++pos & newMask)], EMPTY_KEY_VALUE));
newKeys[pos] = keys[i];
newValues[pos] = values[i];
}
newValues[newSize] = values[nullIndex];
nullIndex = newSize;
mask = newMask;
maxFill = Math.min((int)Math.ceil(nullIndex * loadFactor), nullIndex - 1);
keys = newKeys;
values = newValues;
}
protected void onNodeAdded(int pos) {
}
protected void onNodeRemoved(int pos) {
}
protected void onNodeMoved(int from, int to) {
}
protected void shiftKeys(int startPos) {
int slot, last;
KEY_TYPE current;
while(true) {
startPos = ((last = startPos) + 1) & mask;
while(true){
if(strategy.equals((current = keys[startPos]), EMPTY_KEY_VALUE)) {
keys[last] = EMPTY_KEY_VALUE;
values[last] = EMPTY_VALUE;
return;
}
slot = HashUtil.mix(strategy.hashCode(current)) & mask;
if(last <= startPos ? (last >= slot || slot > startPos) : (last >= slot && slot > startPos)) break;
startPos = ++startPos & mask;
}
keys[last] = current;
values[last] = values[startPos];
onNodeMoved(startPos, last);
}
}
protected class MapEntry implements MAP.Entry KEY_VALUE_GENERIC_TYPE, Map.Entry<CLASS_TYPE, CLASS_VALUE_TYPE> {
public int index = -1;
public MapEntry() {}
public MapEntry(int index) {
this.index = index;
}
@Override
public KEY_TYPE ENTRY_KEY() {
return keys[index];
}
@Override
public VALUE_TYPE ENTRY_VALUE() {
return values[index];
}
@Override
public VALUE_TYPE setValue(VALUE_TYPE value) {
VALUE_TYPE oldValue = values[index];
values[index] = value;
return oldValue;
}
@Override
public boolean equals(Object obj) {
if(obj instanceof Map.Entry) {
if(obj instanceof MAP.Entry) {
MAP.Entry KEY_VALUE_GENERIC_TYPE entry = (MAP.Entry KEY_VALUE_GENERIC_TYPE)obj;
return KEY_EQUALS(keys[index], entry.ENTRY_KEY()) && VALUE_EQUALS(values[index], entry.ENTRY_VALUE());
}
Map.Entry<?, ?> entry = (Map.Entry<?, ?>)obj;
Object key = entry.getKey();
Object value = entry.getValue();
#if TYPE_OBJECT && VALUE_OBJECT
return KEY_EQUALS(keys[index], key) && VALUE_EQUALS(values[index], value);
#else if TYPE_OBJECT
return value instanceof CLASS_VALUE_TYPE && KEY_EQUALS(keys[index], key) && VALUE_EQUALS(values[index], CLASS_TO_VALUE(value));
#else if VALUE_OBJECT
return key instanceof CLASS_TYPE && KEY_EQUALS(keys[index], CLASS_TO_KEY(key)) && VALUE_EQUALS(values[index], value);
#else
return key instanceof CLASS_TYPE && value instanceof CLASS_VALUE_TYPE && KEY_EQUALS(keys[index], CLASS_TO_KEY(key)) && VALUE_EQUALS(values[index], CLASS_TO_VALUE(value));
#endif
}
return false;
}
@Override
public int hashCode() {
return strategy.hashCode(keys[index]) ^ VALUE_TO_HASH(values[index]);
}
@Override
public String toString() {
return KEY_TO_STRING(keys[index]) + "->" + VALUE_TO_STRING(values[index]);
}
}
private final class MapEntrySet extends AbstractObjectSet<MAP.Entry KEY_VALUE_GENERIC_TYPE> implements MAP.FastEntrySet KEY_VALUE_GENERIC_TYPE {
@Override
public ObjectIterator<MAP.Entry KEY_VALUE_GENERIC_TYPE> fastIterator() {
return new FastEntryIterator();
}
@Override
public ObjectIterator<MAP.Entry KEY_VALUE_GENERIC_TYPE> iterator() {
return new EntryIterator();
}
@Override
public void forEach(Consumer<? super MAP.Entry KEY_VALUE_GENERIC_TYPE> action) {
if(containsNull) action.accept(new BasicEntryKV_BRACES(keys[nullIndex], values[nullIndex]));
for(int i = nullIndex-1;i>=0;i--)
if(!strategy.equals(keys[i], EMPTY_KEY_VALUE)) action.accept(new BasicEntryKV_BRACES(keys[i], values[i]));
}
@Override
public void fastForEach(Consumer<? super MAP.Entry KEY_VALUE_GENERIC_TYPE> action) {
BasicEntry KEY_VALUE_GENERIC_TYPE entry = new BasicEntryKV_BRACES();
if(containsNull) {
entry.set(keys[nullIndex], values[nullIndex]);
action.accept(entry);
}
for(int i = nullIndex-1;i>=0;i--) {
if(strategy.equals(keys[i], EMPTY_KEY_VALUE)) {
entry.set(keys[i], values[i]);
action.accept(entry);
}
}
}
@Override
public int size() {
return CUSTOM_HASH_MAP.this.size();
}
@Override
public void clear() {
CUSTOM_HASH_MAP.this.clear();
}
@Override
public boolean contains(Object o) {
if(o instanceof Map.Entry) {
if(o instanceof MAP.Entry) return CUSTOM_HASH_MAP.this.containsKey(((MAP.Entry KEY_VALUE_GENERIC_TYPE)o).ENTRY_KEY());
return CUSTOM_HASH_MAP.this.containsKey(((Map.Entry<?, ?>)o).getKey());
}
return false;
}
@Override
public boolean remove(Object o) {
if(o instanceof Map.Entry) {
if(o instanceof MAP.Entry) {
MAP.Entry KEY_VALUE_GENERIC_TYPE entry = (MAP.Entry KEY_VALUE_GENERIC_TYPE)o;
return CUSTOM_HASH_MAP.this.remove(entry.ENTRY_KEY(), entry.ENTRY_VALUE());
}
Map.Entry<?, ?> entry = (Map.Entry<?, ?>)o;
return CUSTOM_HASH_MAP.this.remove(entry.getKey(), entry.getValue());
}
return false;
}
}
private final class KeySet extends ABSTRACT_SET KEY_GENERIC_TYPE {
#if TYPE_OBJECT
@Override
public boolean contains(Object e) {
return containsKey(e);
}
@Override
public boolean remove(Object o) {
int oldSize = size;
remove(o);
return size != oldSize;
}
#else
@Override
public boolean contains(KEY_TYPE e) {
return containsKey(e);
}
@Override
public boolean remove(KEY_TYPE o) {
int oldSize = size;
remove(o);
return size != oldSize;
}
#endif
@Override
public boolean add(KEY_TYPE o) {
throw new UnsupportedOperationException();
}
@Override
public ITERATOR KEY_GENERIC_TYPE iterator() {
return new KeyIterator();
}
@Override
public int size() {
return CUSTOM_HASH_MAP.this.size();
}
@Override
public void clear() {
CUSTOM_HASH_MAP.this.clear();
}
#if TYPE_OBJECT
@Override
public void forEach(Consumer KEY_SUPER_GENERIC_TYPE action) {
if(containsNull) action.accept(keys[nullIndex]);
for(int i = nullIndex-1;i>=0;i--)
if(strategy.equals(keys[i], EMPTY_KEY_VALUE)) action.accept(keys[i]);
}
#else
@Override
public void forEach(CONSUMER KEY_SUPER_GENERIC_TYPE action) {
if(containsNull) action.accept(keys[nullIndex]);
for(int i = nullIndex-1;i>=0;i--)
if(strategy.equals(keys[i], EMPTY_KEY_VALUE)) action.accept(keys[i]);
}
#endif
}
private class Values extends VALUE_ABSTRACT_COLLECTION VALUE_GENERIC_TYPE {
#if VALUE_OBJECT
@Override
public boolean contains(Object e) {
return containsValue(e);
}
#else
@Override
public boolean contains(VALUE_TYPE e) {
return containsValue(e);
}
#endif
@Override
public boolean add(VALUE_TYPE o) {
throw new UnsupportedOperationException();
}
@Override
public VALUE_ITERATOR VALUE_GENERIC_TYPE iterator() {
return new ValueIterator();
}
@Override
public int size() {
return CUSTOM_HASH_MAP.this.size();
}
@Override
public void clear() {
CUSTOM_HASH_MAP.this.clear();
}
#if VALUE_OBJECT
@Override
public void forEach(Consumer VALUE_SUPER_GENERIC_TYPE action) {
if(containsNull) action.accept(values[nullIndex]);
for(int i = nullIndex-1;i>=0;i--)
if(strategy.equals(keys[i], EMPTY_KEY_VALUE)) action.accept(values[i]);
}
#else
@Override
public void forEach(VALUE_CONSUMER VALUE_SUPER_GENERIC_TYPE action) {
if(containsNull) action.accept(values[nullIndex]);
for(int i = nullIndex-1;i>=0;i--)
if(strategy.equals(keys[i], EMPTY_KEY_VALUE)) action.accept(values[i]);
}
#endif
}
private class FastEntryIterator extends MapIterator implements ObjectIterator<MAP.Entry KEY_VALUE_GENERIC_TYPE> {
MapEntry entry = new MapEntry();
@Override
public MAP.Entry KEY_VALUE_GENERIC_TYPE next() {
entry.index = nextEntry();
return entry;
}
}
private class EntryIterator extends MapIterator implements ObjectIterator<MAP.Entry KEY_VALUE_GENERIC_TYPE> {
MapEntry entry;
@Override
public MAP.Entry KEY_VALUE_GENERIC_TYPE next() {
return entry = new MapEntry(nextEntry());
}
@Override
public void remove() {
super.remove();
entry.index = -1;
}
}
private class KeyIterator extends MapIterator implements ITERATOR KEY_GENERIC_TYPE {
@Override
public KEY_TYPE NEXT() {
return keys[nextEntry()];
}
}
private class ValueIterator extends MapIterator implements VALUE_ITERATOR VALUE_GENERIC_TYPE {
@Override
public VALUE_TYPE VALUE_NEXT() {
return values[nextEntry()];
}
}
private class MapIterator {
int pos = nullIndex;
int lastReturned = -1;
int nextIndex = Integer.MIN_VALUE;
boolean returnNull = containsNull;
LIST KEY_GENERIC_TYPE wrapped = null;
public boolean hasNext() {
if(nextIndex == Integer.MIN_VALUE) {
if(returnNull) {
returnNull = false;
nextIndex = nullIndex;
}
else
{
while(true) {
if(--pos < 0) {
if(wrapped == null || wrapped.size() <= -pos - 1) break;
nextIndex = -pos - 1;
break;
}
if(!strategy.equals(keys[pos], EMPTY_KEY_VALUE)){
nextIndex = pos;
break;
}
}
}
}
return nextIndex != Integer.MIN_VALUE;
}
public int nextEntry() {
if(!hasNext()) throw new NoSuchElementException();
if(nextIndex < 0){
lastReturned = Integer.MAX_VALUE;
int value = findIndex(wrapped.GET_KEY(nextIndex));
if(value < 0) throw new IllegalStateException("Entry ["+nextIndex+"] was removed during Iteration");
nextIndex = Integer.MIN_VALUE;
return value;
}
int value = (lastReturned = nextIndex);
nextIndex = Integer.MIN_VALUE;
return value;
}
public void remove() {
if(lastReturned == -1) throw new IllegalStateException();
if(lastReturned == nullIndex) {
containsNull = false;
keys[nullIndex] = EMPTY_KEY_VALUE;
values[nullIndex] = EMPTY_VALUE;
}
else if(pos >= 0) shiftKeys(pos);
else {
CUSTOM_HASH_MAP.this.remove(wrapped.GET_KEY(-pos - 1));
return;
}
size--;
lastReturned = -1;
}
private void shiftKeys(int startPos) {
int slot, last;
KEY_TYPE current;
while(true) {
startPos = ((last = startPos) + 1) & mask;
while(true){
if(strategy.equals((current = keys[startPos]), EMPTY_KEY_VALUE)) {
keys[last] = EMPTY_KEY_VALUE;
values[last] = EMPTY_VALUE;
return;
}
slot = HashUtil.mix(strategy.hashCode(current)) & mask;
if(last <= startPos ? (last >= slot || slot > startPos) : (last >= slot && slot > startPos)) break;
startPos = ++startPos & mask;
}
if(startPos < last) {
if(wrapped == null) wrapped = new ARRAY_LISTBRACES(2);
wrapped.add(keys[startPos]);
}
keys[last] = current;
values[last] = values[startPos];
}
}
}
}
@@ -0,0 +1,777 @@
package speiger.src.collections.PACKAGE.maps.impl.hash;
import java.util.Arrays;
import java.util.Map;
import java.util.NoSuchElementException;
import java.util.Objects;
import java.util.function.Consumer;
#if !TYPE_OBJECT
import speiger.src.collections.PACKAGE.collections.ITERATOR;
import speiger.src.collections.PACKAGE.functions.CONSUMER;
#endif
import speiger.src.collections.PACKAGE.functions.consumer.BI_CONSUMER;
import speiger.src.collections.PACKAGE.lists.ARRAY_LIST;
import speiger.src.collections.PACKAGE.lists.LIST;
import speiger.src.collections.PACKAGE.maps.abstracts.ABSTRACT_MAP;
import speiger.src.collections.PACKAGE.maps.interfaces.MAP;
#if !TYPE_OBJECT
import speiger.src.collections.PACKAGE.sets.ABSTRACT_SET;
import speiger.src.collections.PACKAGE.sets.SET;
#endif
import speiger.src.collections.VALUE_PACKAGE.collections.VALUE_ABSTRACT_COLLECTION;
import speiger.src.collections.VALUE_PACKAGE.collections.VALUE_COLLECTION;
#if !SAME_TYPE && !VALUE_OBJECT
import speiger.src.collections.VALUE_PACKAGE.collections.VALUE_ITERATOR;
import speiger.src.collections.VALUE_PACKAGE.functions.VALUE_CONSUMER;
#endif
import speiger.src.collections.objects.collections.ObjectIterator;
import speiger.src.collections.objects.sets.AbstractObjectSet;
import speiger.src.collections.objects.sets.ObjectSet;
import speiger.src.collections.utils.HashUtil;
public class HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_GENERIC_TYPE
{
protected transient KEY_TYPE[] keys;
protected transient VALUE_TYPE[] values;
protected transient boolean containsNull;
protected transient int minCapacity;
protected transient int nullIndex;
protected transient int maxFill;
protected transient int mask;
protected transient FastEntrySet KEY_VALUE_GENERIC_TYPE entrySet;
protected transient SET KEY_GENERIC_TYPE keySet;
protected transient VALUE_COLLECTION VALUE_GENERIC_TYPE valuesC;
protected int size;
protected final float loadFactor;
public HASH_MAP() {
this(HashUtil.DEFAULT_MIN_CAPACITY, HashUtil.DEFAULT_LOAD_FACTOR);
}
public HASH_MAP(int minCapacity) {
this(minCapacity, HashUtil.DEFAULT_LOAD_FACTOR);
}
public HASH_MAP(int minCapacity, float loadFactor) {
if(minCapacity < 0) throw new IllegalStateException("Minimum Capacity is negative. This is not allowed");
if(loadFactor <= 0 || loadFactor >= 1F) throw new IllegalStateException("Load Factor is not between 0 and 1");
this.loadFactor = loadFactor;
this.minCapacity = nullIndex = HashUtil.arraySize(minCapacity, loadFactor);
mask = nullIndex - 1;
maxFill = Math.min((int)Math.ceil(nullIndex * loadFactor), nullIndex - 1);
keys = NEW_KEY_ARRAY(nullIndex + 1);
values = NEW_VALUE_ARRAY(nullIndex + 1);
}
#if !TYPE_OBJECT || !VALUE_OBJECT
public HASH_MAP(CLASS_TYPE[] keys, CLASS_VALUE_TYPE[] values) {
this(keys, values, HashUtil.DEFAULT_LOAD_FACTOR);
}
public HASH_MAP(CLASS_TYPE[] keys, CLASS_VALUE_TYPE[] values, float loadFactor) {
this(keys.length, loadFactor);
if(keys.length != values.length) throw new IllegalStateException("Input Arrays are not equal size");
for(int i = 0,m=keys.length;i<m;i++) put(OBJ_TO_KEY(keys[i]), OBJ_TO_VALUE(values[i]));
}
#endif
public HASH_MAP(KEY_TYPE[] keys, VALUE_TYPE[] values) {
this(keys, values, HashUtil.DEFAULT_LOAD_FACTOR);
}
public HASH_MAP(KEY_TYPE[] keys, VALUE_TYPE[] values, float loadFactor) {
this(keys.length, loadFactor);
if(keys.length != values.length) throw new IllegalStateException("Input Arrays are not equal size");
for(int i = 0,m=keys.length;i<m;i++) put(keys[i], values[i]);
}
public HASH_MAP(Map<? extends CLASS_TYPE, ? extends CLASS_VALUE_TYPE> map) {
this(map, HashUtil.DEFAULT_LOAD_FACTOR);
}
public HASH_MAP(Map<? extends CLASS_TYPE, ? extends CLASS_VALUE_TYPE> map, float loadFactor) {
this(map.size(), loadFactor);
putAll(map);
}
public HASH_MAP(MAP KEY_VALUE_GENERIC_TYPE map) {
this(map, HashUtil.DEFAULT_LOAD_FACTOR);
}
public HASH_MAP(MAP KEY_VALUE_GENERIC_TYPE map, float loadFactor) {
this(map.size(), loadFactor);
putAll(map);
}
@Override
public VALUE_TYPE put(KEY_TYPE key, VALUE_TYPE value) {
int slot = findIndex(key);
if(slot < 0) {
insert(-slot-1, key, value);
return getDefaultReturnValue();
}
VALUE_TYPE oldValue = values[slot];
values[slot] = value;
return oldValue;
}
@Override
public VALUE_TYPE putIfAbsent(KEY_TYPE key, VALUE_TYPE value) {
int slot = findIndex(key);
if(slot < 0) {
insert(-slot-1, key, value);
return getDefaultReturnValue();
}
return values[slot];
}
#if VALUE_PRIMITIVES
@Override
public VALUE_TYPE addTo(KEY_TYPE key, VALUE_TYPE value) {
int slot = findIndex(key);
if(slot < 0) {
insert(-slot-1, key, value);
return getDefaultReturnValue();
}
VALUE_TYPE oldValue = values[slot];
values[slot] += value;
return oldValue;
}
#endif
#if !TYPE_OBJECT
@Override
public boolean containsKey(KEY_TYPE key) {
return findIndex(key) >= 0;
}
#endif
@Override
@Deprecated
public boolean containsKey(Object key) {
return findIndex(key) >= 0;
}
#if !VALUE_OBJECT
@Override
public boolean containsValue(VALUE_TYPE value) {
if(VALUE_EQUALS(value, values[nullIndex])) return true;
for(int i = nullIndex-1;i >= 0;i--)
if(KEY_EQUALS_NOT_NULL(keys[i]) && VALUE_EQUALS(values[i], value)) return true;
return false;
}
#endif
@Override
@Deprecated
public boolean containsValue(Object value) {
if((value == null && VALUE_EQUALS(values[nullIndex], getDefaultReturnValue())) || EQUALS_VALUE_TYPE(values[nullIndex], value)) return true;
for(int i = nullIndex-1;i >= 0;i--)
if(KEY_EQUALS_NOT_NULL(keys[i]) && ((value == null && values[i] == getDefaultReturnValue()) || EQUALS_VALUE_TYPE(values[i], value))) return true;
return false;
}
@Override
public VALUE_TYPE REMOVE_KEY(KEY_TYPE key) {
int slot = findIndex(key);
if(slot < 0) return getDefaultReturnValue();
return removeIndex(slot);
}
@Override
@Deprecated
public CLASS_VALUE_TYPE remove(Object key) {
int slot = findIndex(key);
if(slot < 0) return VALUE_TO_OBJ(getDefaultReturnValue());
return removeIndex(slot);
}
#if !TYPE_OBJECT || !VALUE_OBJECT
@Override
public boolean remove(KEY_TYPE key, VALUE_TYPE value) {
if(KEY_EQUALS_NULL(key)) {
if(containsNull && VALUE_EQUALS(value, values[nullIndex])) {
removeNullIndex();
return true;
}
return false;
}
int pos = HashUtil.mix(KEY_TO_HASH(key)) & mask;
KEY_TYPE current = keys[pos];
if(KEY_EQUALS_NULL(current)) return false;
if(KEY_EQUALS(current, key) && VALUE_EQUALS(value, values[pos])) {
removeIndex(pos);
return true;
}
while(true) {
if(KEY_EQUALS_NULL((current = keys[pos = (++pos & mask)]))) return false;
else if(KEY_EQUALS(current, key) && VALUE_EQUALS(value, values[pos])) {
removeIndex(pos);
return true;
}
}
}
#endif
@Override
public boolean remove(Object key, Object value) {
Objects.requireNonNull(value);
if(key == null) {
if(containsNull && EQUALS_VALUE_TYPE(values[nullIndex], value)) {
removeNullIndex();
return true;
}
return false;
}
int pos = HashUtil.mix(key.hashCode()) & mask;
KEY_TYPE current = keys[pos];
if(KEY_EQUALS_NULL(current)) return false;
if(EQUALS_KEY_TYPE(current, key) && EQUALS_VALUE_TYPE(values[pos], value)) {
removeIndex(pos);
return true;
}
while(true) {
if(KEY_EQUALS_NULL((current = keys[pos = (++pos & mask)]))) return false;
else if(EQUALS_KEY_TYPE(current, key) && EQUALS_VALUE_TYPE(values[pos], value)){
removeIndex(pos);
return true;
}
}
}
@Override
public VALUE_TYPE GET_VALUE(KEY_TYPE key) {
int slot = findIndex(key);
return slot < 0 ? getDefaultReturnValue() : values[slot];
}
@Override
public CLASS_VALUE_TYPE get(Object key) {
int slot = findIndex(key);
return VALUE_TO_OBJ(slot < 0 ? getDefaultReturnValue() : values[slot]);
}
#if TYPE_OBJECT && VALUE_OBJECT
@Override
public VALUE_TYPE getOrDefault(Object key, VALUE_TYPE defaultValue) {
int slot = findIndex(key);
return slot < 0 ? defaultValue : values[slot];
}
#else
@Override
public VALUE_TYPE getOrDefault(KEY_TYPE key, VALUE_TYPE defaultValue) {
int slot = findIndex(key);
return slot < 0 ? defaultValue : values[slot];
}
#endif
@Override
public ObjectSet<MAP.Entry KEY_VALUE_GENERIC_TYPE> ENTRY_SET() {
if(entrySet == null) entrySet = new MapEntrySet();
return entrySet;
}
@Override
public SET KEY_GENERIC_TYPE keySet() {
if(keySet == null) keySet = new KeySet();
return keySet;
}
@Override
public VALUE_COLLECTION VALUE_GENERIC_TYPE values() {
if(valuesC == null) valuesC = new Values();
return valuesC;
}
@Override
public void forEach(BI_CONSUMER KEY_VALUE_GENERIC_TYPE action) {
if(size() <= 0) return;
if(containsNull) action.accept(keys[nullIndex], values[nullIndex]);
for(int i = nullIndex-1;i>=0;i--) {
if(KEY_EQUALS_NOT_NULL(keys[i])) action.accept(keys[i], values[i]);
}
}
@Override
public void clear() {
if(size == 0) return;
size = 0;
containsNull = false;
Arrays.fill(keys, EMPTY_KEY_VALUE);
Arrays.fill(values, EMPTY_VALUE);
}
#if !TYPE_OBJECT
protected int findIndex(KEY_TYPE key) {
if(KEY_EQUALS_NULL(key)) return containsNull ? nullIndex : -(nullIndex + 1);
int pos = HashUtil.mix(KEY_TO_HASH(key)) & mask;
KEY_TYPE current = keys[pos];
if(KEY_EQUALS_NOT_NULL(current)) {
if(KEY_EQUALS(current, key)) return pos;
while(KEY_EQUALS_NOT_NULL((current = keys[pos = (++pos & mask)])))
if(KEY_EQUALS(current, key)) return pos;
}
return -(pos + 1);
}
#endif
protected int findIndex(Object key) {
if(key == null) return containsNull ? nullIndex : -(nullIndex + 1);
int pos = HashUtil.mix(key.hashCode()) & mask;
KEY_TYPE current = keys[pos];
if(KEY_EQUALS_NOT_NULL(current)) {
if(EQUALS_KEY_TYPE(current, key)) return pos;
while(KEY_EQUALS_NOT_NULL((current = keys[pos = (++pos & mask)])))
if(EQUALS_KEY_TYPE(current, key)) return pos;
}
return -(pos + 1);
}
protected VALUE_TYPE removeIndex(int pos) {
VALUE_TYPE value = values[pos];
size--;
onNodeRemoved(pos);
shiftKeys(pos);
if(nullIndex > minCapacity && size < maxFill / 4 && nullIndex > HashUtil.DEFAULT_MIN_CAPACITY) rehash(nullIndex / 2);
return value;
}
protected VALUE_TYPE removeNullIndex() {
VALUE_TYPE value = values[nullIndex];
containsNull = false;
keys[nullIndex] = EMPTY_KEY_VALUE;
values[nullIndex] = EMPTY_VALUE;
size--;
onNodeRemoved(nullIndex);
if(nullIndex > minCapacity && size < maxFill / 4 && nullIndex > HashUtil.DEFAULT_MIN_CAPACITY) rehash(nullIndex / 2);
return value;
}
protected void insert(int slot, KEY_TYPE key, VALUE_TYPE value) {
if(slot == nullIndex) containsNull = true;
keys[slot] = key;
values[slot] = value;
onNodeAdded(slot);
if(size++ >= maxFill) rehash(HashUtil.arraySize(size+1, loadFactor));
}
protected void rehash(int newSize) {
int newMask = newSize - 1;
KEY_TYPE[] newKeys = NEW_KEY_ARRAY(newSize + 1);
VALUE_TYPE[] newValues = NEW_VALUE_ARRAY(newSize + 1);
for(int i = nullIndex, pos = 0, j = (size - (containsNull ? 1 : 0));j-- != 0;) {
while(KEY_EQUALS_NULL(keys[--i]));
if(KEY_EQUALS_NOT_NULL(newKeys[pos = HashUtil.mix(KEY_TO_HASH(keys[i])) & newMask]))
while(KEY_EQUALS_NOT_NULL(newKeys[pos = (++pos & newMask)]));
newKeys[pos] = keys[i];
newValues[pos] = values[i];
}
newValues[newSize] = values[nullIndex];
nullIndex = newSize;
mask = newMask;
maxFill = Math.min((int)Math.ceil(nullIndex * loadFactor), nullIndex - 1);
keys = newKeys;
values = newValues;
}
protected void onNodeAdded(int pos) {
}
protected void onNodeRemoved(int pos) {
}
protected void onNodeMoved(int from, int to) {
}
protected void shiftKeys(int startPos) {
int slot, last;
KEY_TYPE current;
while(true) {
startPos = ((last = startPos) + 1) & mask;
while(true){
if(KEY_EQUALS_NULL((current = keys[startPos]))) {
keys[last] = EMPTY_KEY_VALUE;
values[last] = EMPTY_VALUE;
return;
}
slot = HashUtil.mix(KEY_TO_HASH(current)) & mask;
if(last <= startPos ? (last >= slot || slot > startPos) : (last >= slot && slot > startPos)) break;
startPos = ++startPos & mask;
}
keys[last] = current;
values[last] = values[startPos];
onNodeMoved(startPos, last);
}
}
protected class MapEntry implements MAP.Entry KEY_VALUE_GENERIC_TYPE, Map.Entry<CLASS_TYPE, CLASS_VALUE_TYPE> {
public int index = -1;
public MapEntry() {}
public MapEntry(int index) {
this.index = index;
}
@Override
public KEY_TYPE ENTRY_KEY() {
return keys[index];
}
@Override
public VALUE_TYPE ENTRY_VALUE() {
return values[index];
}
@Override
public VALUE_TYPE setValue(VALUE_TYPE value) {
VALUE_TYPE oldValue = values[index];
values[index] = value;
return oldValue;
}
@Override
public boolean equals(Object obj) {
if(obj instanceof Map.Entry) {
if(obj instanceof MAP.Entry) {
MAP.Entry KEY_VALUE_GENERIC_TYPE entry = (MAP.Entry KEY_VALUE_GENERIC_TYPE)obj;
return KEY_EQUALS(keys[index], entry.ENTRY_KEY()) && VALUE_EQUALS(values[index], entry.ENTRY_VALUE());
}
Map.Entry<?, ?> entry = (Map.Entry<?, ?>)obj;
Object key = entry.getKey();
Object value = entry.getValue();
#if TYPE_OBJECT && VALUE_OBJECT
return KEY_EQUALS(keys[index], key) && VALUE_EQUALS(values[index], value);
#else if TYPE_OBJECT
return value instanceof CLASS_VALUE_TYPE && KEY_EQUALS(keys[index], key) && VALUE_EQUALS(values[index], CLASS_TO_VALUE(value));
#else if VALUE_OBJECT
return key instanceof CLASS_TYPE && KEY_EQUALS(keys[index], CLASS_TO_KEY(key)) && VALUE_EQUALS(values[index], value);
#else
return key instanceof CLASS_TYPE && value instanceof CLASS_VALUE_TYPE && KEY_EQUALS(keys[index], CLASS_TO_KEY(key)) && VALUE_EQUALS(values[index], CLASS_TO_VALUE(value));
#endif
}
return false;
}
@Override
public int hashCode() {
return KEY_TO_HASH(keys[index]) ^ VALUE_TO_HASH(values[index]);
}
@Override
public String toString() {
return KEY_TO_STRING(keys[index]) + "->" + VALUE_TO_STRING(values[index]);
}
}
private final class MapEntrySet extends AbstractObjectSet<MAP.Entry KEY_VALUE_GENERIC_TYPE> implements MAP.FastEntrySet KEY_VALUE_GENERIC_TYPE {
@Override
public ObjectIterator<MAP.Entry KEY_VALUE_GENERIC_TYPE> fastIterator() {
return new FastEntryIterator();
}
@Override
public ObjectIterator<MAP.Entry KEY_VALUE_GENERIC_TYPE> iterator() {
return new EntryIterator();
}
@Override
public void forEach(Consumer<? super MAP.Entry KEY_VALUE_GENERIC_TYPE> action) {
if(containsNull) action.accept(new BasicEntryKV_BRACES(keys[nullIndex], values[nullIndex]));
for(int i = nullIndex-1;i>=0;i--)
if(KEY_EQUALS_NOT_NULL(keys[i])) action.accept(new BasicEntryKV_BRACES(keys[i], values[i]));
}
@Override
public void fastForEach(Consumer<? super MAP.Entry KEY_VALUE_GENERIC_TYPE> action) {
BasicEntry KEY_VALUE_GENERIC_TYPE entry = new BasicEntryKV_BRACES();
if(containsNull) {
entry.set(keys[nullIndex], values[nullIndex]);
action.accept(entry);
}
for(int i = nullIndex-1;i>=0;i--) {
if(KEY_EQUALS_NOT_NULL(keys[i])) {
entry.set(keys[i], values[i]);
action.accept(entry);
}
}
}
@Override
public int size() {
return HASH_MAP.this.size();
}
@Override
public void clear() {
HASH_MAP.this.clear();
}
@Override
public boolean contains(Object o) {
if(o instanceof Map.Entry) {
if(o instanceof MAP.Entry) return HASH_MAP.this.containsKey(((MAP.Entry KEY_VALUE_GENERIC_TYPE)o).ENTRY_KEY());
return HASH_MAP.this.containsKey(((Map.Entry<?, ?>)o).getKey());
}
return false;
}
@Override
public boolean remove(Object o) {
if(o instanceof Map.Entry) {
if(o instanceof MAP.Entry) {
MAP.Entry KEY_VALUE_GENERIC_TYPE entry = (MAP.Entry KEY_VALUE_GENERIC_TYPE)o;
return HASH_MAP.this.remove(entry.ENTRY_KEY(), entry.ENTRY_VALUE());
}
Map.Entry<?, ?> entry = (Map.Entry<?, ?>)o;
return HASH_MAP.this.remove(entry.getKey(), entry.getValue());
}
return false;
}
}
private final class KeySet extends ABSTRACT_SET KEY_GENERIC_TYPE {
#if TYPE_OBJECT
@Override
public boolean contains(Object e) {
return containsKey(e);
}
@Override
public boolean remove(Object o) {
int oldSize = size;
remove(o);
return size != oldSize;
}
#else
@Override
public boolean contains(KEY_TYPE e) {
return containsKey(e);
}
@Override
public boolean remove(KEY_TYPE o) {
int oldSize = size;
remove(o);
return size != oldSize;
}
#endif
@Override
public boolean add(KEY_TYPE o) {
throw new UnsupportedOperationException();
}
@Override
public ITERATOR KEY_GENERIC_TYPE iterator() {
return new KeyIterator();
}
@Override
public int size() {
return HASH_MAP.this.size();
}
@Override
public void clear() {
HASH_MAP.this.clear();
}
#if TYPE_OBJECT
@Override
public void forEach(Consumer KEY_SUPER_GENERIC_TYPE action) {
if(containsNull) action.accept(keys[nullIndex]);
for(int i = nullIndex-1;i>=0;i--)
if(KEY_EQUALS_NOT_NULL(keys[i])) action.accept(keys[i]);
}
#else
@Override
public void forEach(CONSUMER KEY_SUPER_GENERIC_TYPE action) {
if(containsNull) action.accept(keys[nullIndex]);
for(int i = nullIndex-1;i>=0;i--)
if(KEY_EQUALS_NOT_NULL(keys[i])) action.accept(keys[i]);
}
#endif
}
private class Values extends VALUE_ABSTRACT_COLLECTION VALUE_GENERIC_TYPE {
#if VALUE_OBJECT
@Override
public boolean contains(Object e) {
return containsValue(e);
}
#else
@Override
public boolean contains(VALUE_TYPE e) {
return containsValue(e);
}
#endif
@Override
public boolean add(VALUE_TYPE o) {
throw new UnsupportedOperationException();
}
@Override
public VALUE_ITERATOR VALUE_GENERIC_TYPE iterator() {
return new ValueIterator();
}
@Override
public int size() {
return HASH_MAP.this.size();
}
@Override
public void clear() {
HASH_MAP.this.clear();
}
#if VALUE_OBJECT
@Override
public void forEach(Consumer VALUE_SUPER_GENERIC_TYPE action) {
if(containsNull) action.accept(values[nullIndex]);
for(int i = nullIndex-1;i>=0;i--)
if(KEY_EQUALS_NOT_NULL(keys[i])) action.accept(values[i]);
}
#else
@Override
public void forEach(VALUE_CONSUMER VALUE_SUPER_GENERIC_TYPE action) {
if(containsNull) action.accept(values[nullIndex]);
for(int i = nullIndex-1;i>=0;i--)
if(KEY_EQUALS_NOT_NULL(keys[i])) action.accept(values[i]);
}
#endif
}
private class FastEntryIterator extends MapIterator implements ObjectIterator<MAP.Entry KEY_VALUE_GENERIC_TYPE> {
MapEntry entry = new MapEntry();
@Override
public MAP.Entry KEY_VALUE_GENERIC_TYPE next() {
entry.index = nextEntry();
return entry;
}
}
private class EntryIterator extends MapIterator implements ObjectIterator<MAP.Entry KEY_VALUE_GENERIC_TYPE> {
MapEntry entry;
@Override
public MAP.Entry KEY_VALUE_GENERIC_TYPE next() {
return entry = new MapEntry(nextEntry());
}
@Override
public void remove() {
super.remove();
entry.index = -1;
}
}
private class KeyIterator extends MapIterator implements ITERATOR KEY_GENERIC_TYPE {
@Override
public KEY_TYPE NEXT() {
return keys[nextEntry()];
}
}
private class ValueIterator extends MapIterator implements VALUE_ITERATOR VALUE_GENERIC_TYPE {
@Override
public VALUE_TYPE VALUE_NEXT() {
return values[nextEntry()];
}
}
private class MapIterator {
int pos = nullIndex;
int lastReturned = -1;
int nextIndex = Integer.MIN_VALUE;
boolean returnNull = containsNull;
LIST KEY_GENERIC_TYPE wrapped = null;
public boolean hasNext() {
if(nextIndex == Integer.MIN_VALUE) {
if(returnNull) {
returnNull = false;
nextIndex = nullIndex;
}
else
{
while(true) {
if(--pos < 0) {
if(wrapped == null || wrapped.size() <= -pos - 1) break;
nextIndex = -pos - 1;
break;
}
if(KEY_EQUALS_NOT_NULL(keys[pos])){
nextIndex = pos;
break;
}
}
}
}
return nextIndex != Integer.MIN_VALUE;
}
public int nextEntry() {
if(!hasNext()) throw new NoSuchElementException();
if(nextIndex < 0){
lastReturned = Integer.MAX_VALUE;
int value = findIndex(wrapped.GET_KEY(nextIndex));
if(value < 0) throw new IllegalStateException("Entry ["+nextIndex+"] was removed during Iteration");
nextIndex = Integer.MIN_VALUE;
return value;
}
int value = (lastReturned = nextIndex);
nextIndex = Integer.MIN_VALUE;
return value;
}
public void remove() {
if(lastReturned == -1) throw new IllegalStateException();
if(lastReturned == nullIndex) {
containsNull = false;
keys[nullIndex] = EMPTY_KEY_VALUE;
values[nullIndex] = EMPTY_VALUE;
}
else if(pos >= 0) shiftKeys(pos);
else {
HASH_MAP.this.remove(wrapped.GET_KEY(-pos - 1));
return;
}
size--;
lastReturned = -1;
}
private void shiftKeys(int startPos) {
int slot, last;
KEY_TYPE current;
while(true) {
startPos = ((last = startPos) + 1) & mask;
while(true){
if(KEY_EQUALS_NULL((current = keys[startPos]))) {
keys[last] = EMPTY_KEY_VALUE;
values[last] = EMPTY_VALUE;
return;
}
slot = HashUtil.mix(KEY_TO_HASH(current)) & mask;
if(last <= startPos ? (last >= slot || slot > startPos) : (last >= slot && slot > startPos)) break;
startPos = ++startPos & mask;
}
if(startPos < last) {
if(wrapped == null) wrapped = new ARRAY_LISTBRACES(2);
wrapped.add(keys[startPos]);
}
keys[last] = current;
values[last] = values[startPos];
}
}
}
}
@@ -0,0 +1,335 @@
package speiger.src.collections.PACKAGE.maps.impl.misc;
import java.util.Map;
import java.util.NoSuchElementException;
#if VALUE_OBJECT
import java.util.Objects;
#endif
import speiger.src.collections.VALUE_PACKAGE.collections.VALUE_ABSTRACT_COLLECTION;
import speiger.src.collections.VALUE_PACKAGE.collections.VALUE_COLLECTION;
import speiger.src.collections.VALUE_PACKAGE.collections.VALUE_ITERATOR;
#if !VALUE_OBJECT
import speiger.src.collections.objects.collections.ObjectIterator;
#endif
import speiger.src.collections.objects.maps.abstracts.ABSTRACT_MAP;
import speiger.src.collections.objects.maps.interfaces.MAP;
import speiger.src.collections.objects.sets.AbstractObjectSet;
import speiger.src.collections.objects.sets.ObjectSet;
//import sun.misc.SharedSecrets;
public class ENUM_MAP KEY_ENUM_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_GENERIC_TYPE
{
protected final Class<T> keyType;
protected transient final T[] keys;
protected transient final VALUE_TYPE[] values;
protected transient final long[] present;
protected int size = 0;
protected transient ObjectSet<MAP.Entry KEY_VALUE_GENERIC_TYPE> entrySet;
protected transient ObjectSet<T> keySet;
protected transient VALUE_COLLECTION VALUE_GENERIC_TYPE valuesC;
public ENUM_MAP(Class<T> keyType) {
this.keyType = keyType;
keys = getKeyUniverse(keyType);
values = NEW_VALUE_ARRAY(keys.length);
present = new long[((keys.length - 1) >> 6) + 1];
}
@Override
public VALUE_TYPE put(T key, VALUE_TYPE value) {
int index = key.ordinal();
if(isSet(index)) {
VALUE_TYPE result = values[index];
values[index] = value;
return result;
}
set(index);
values[index] = value;
return getDefaultReturnValue();
}
@Override
public VALUE_TYPE putIfAbsent(T key, VALUE_TYPE value) {
int index = key.ordinal();
if(isSet(index)) return values[index];
set(index);
values[index] = value;
return getDefaultReturnValue();
}
#if VALUE_PRIMITIVES
@Override
public VALUE_TYPE addTo(T key, VALUE_TYPE value) {
int index = key.ordinal();
if(isSet(index)) {
VALUE_TYPE result = values[index];
values[index] += value;
return result;
}
set(index);
values[index] = value;
return getDefaultReturnValue();
}
#endif
@Override
public boolean containsKey(Object key) {
return isSet(((T)key).ordinal());
}
#if VALUE_OBJECT
@Override
public boolean containsValue(Object value) {
for(int i = 0;i<values.length;i++)
if(VALUE_EQUALS(value, values[i])) return true;
return false;
}
#else
@Override
public boolean containsValue(VALUE_TYPE value) {
for(int i = 0;i<values.length;i++)
if(VALUE_EQUALS(value, values[i])) return true;
return false;
}
#endif
@Override
public VALUE_TYPE rem(T key) {
int index = key.ordinal();
if(!isSet(index)) return getDefaultReturnValue();
clear(index);
VALUE_TYPE result = values[index];
values[index] = EMPTY_VALUE;
return result;
}
#if VALUE_OBJECT
@Override
public boolean remove(Object key, Object value) {
int index = ((T)key).ordinal();
if(!isSet(index) || VALUE_EQUALS_NOT(value, values[index])) return false;
clear(index);
values[index] = EMPTY_VALUE;
return true;
}
#else
@Override
public boolean remove(T key, VALUE_TYPE value) {
int index = key.ordinal();
if(!isSet(index) || VALUE_EQUALS_NOT(value, values[index])) return false;
clear(index);
values[index] = EMPTY_VALUE;
return true;
}
#endif
@Override
public VALUE_TYPE GET_VALUE(T key) {
int index = key.ordinal();
return isSet(index) ? values[index] : getDefaultReturnValue();
}
#if VALUE_OBJECT
@Override
public VALUE_TYPE getOrDefault(Object key, VALUE_TYPE defaultValue) {
int index = ((T)key).ordinal();
return isSet(index) ? values[index] : defaultValue;
}
#else
@Override
public VALUE_TYPE getOrDefault(T key, VALUE_TYPE defaultValue) {
int index = key.ordinal();
return isSet(index) ? values[index] : defaultValue;
}
#endif
@Override
public ObjectSet<MAP.Entry KEY_VALUE_GENERIC_TYPE> ENTRY_SET() {
if(entrySet == null) entrySet = new EntrySet();
return entrySet;
}
@Override
public ObjectSet<T> keySet() {
if(keySet == null) keySet = new KeySet();
return keySet;
}
@Override
public VALUE_COLLECTION VALUE_GENERIC_TYPE values() {
if(valuesC == null) valuesC = new Values();
return valuesC;
}
protected void onNodeAdded(int index) {
}
protected void onNodeRemoved(int index) {
}
protected void set(int index) {
present[index >> 6] |= (1L << index);
onNodeAdded(index);
}
protected void clear(int index) {
present[index >> 6] &= ~(1L << index);
onNodeRemoved(index);
}
protected boolean isSet(int index) { return (present[index >> 6] & (1L << index)) != 0; }
private static <K extends Enum<K>> K[] getKeyUniverse(Class<K> keyType) {
return keyType.getEnumConstants();
// return SharedSecrets.getJavaLangAccess().getEnumConstantsShared(keyType);
}
class EntrySet extends AbstractObjectSet<MAP.Entry KEY_VALUE_GENERIC_TYPE> {
@Override
public boolean contains(Object o) {
if(o instanceof Map.Entry) return containsKey(((Map.Entry<?, ?>)o).getKey());
return false;
}
@Override
public boolean remove(Object o) {
if(o instanceof Map.Entry) {
if(o instanceof MAP.Entry) {
MAP.Entry KEY_VALUE_GENERIC_TYPE entry = (MAP.Entry KEY_VALUE_GENERIC_TYPE)o;
return ENUM_MAP.this.remove(entry.getKey(), entry.ENTRY_VALUE());
}
Map.Entry<?, ?> entry = (java.util.Map.Entry<?, ?>)o;
return ENUM_MAP.this.remove(entry.getKey(), entry.getValue());
}
return false;
}
@Override
public ObjectIterator<MAP.Entry KEY_VALUE_GENERIC_TYPE> iterator() {
return new EntryIterator();
}
@Override
public int size() {
return ENUM_MAP.this.size();
}
@Override
public void clear() {
ENUM_MAP.this.clear();
}
}
class KeySet extends AbstractObjectSet<T> {
@Override
public boolean contains(Object o) {
return containsKey(o);
}
@Override
public boolean remove(Object o) {
int size = size();
ENUM_MAP.this.remove(o);
return size != size();
}
@Override
public ObjectIterator<T> iterator() {
return new KeyIterator();
}
@Override
public int size() {
return ENUM_MAP.this.size();
}
@Override
public void clear() {
ENUM_MAP.this.clear();
}
}
class Values extends VALUE_ABSTRACT_COLLECTION VALUE_GENERIC_TYPE {
@Override
public boolean add(VALUE_TYPE o) { throw new UnsupportedOperationException(); }
#if TYPE_OBJECT
@Override
public boolean contains(Object e) { return containsValue(e); }
#else
@Override
public boolean contains(VALUE_TYPE e) { return containsValue(e); }
#endif
@Override
public VALUE_ITERATOR VALUE_GENERIC_TYPE iterator() {
return new ValueIterator();
}
@Override
public int size() {
return ENUM_MAP.this.size();
}
@Override
public void clear() {
ENUM_MAP.this.clear();
}
}
class EntryIterator extends MapIterator implements ObjectIterator<MAP.Entry KEY_VALUE_GENERIC_TYPE> {
@Override
public MAP.Entry KEY_VALUE_GENERIC_TYPE next() {
int index = nextEntry();
return new BasicEntry<>(keys[index], values[index]);
}
}
class KeyIterator extends MapIterator implements ObjectIterator<T> {
@Override
public T next() {
return keys[nextEntry()];
}
}
class ValueIterator extends MapIterator implements VALUE_ITERATOR VALUE_GENERIC_TYPE {
@Override
public VALUE_TYPE VALUE_NEXT() {
return values[nextEntry()];
}
}
class MapIterator {
int index;
int lastReturnValue = -1;
int nextIndex = -1;
public boolean hasNext() {
if(nextIndex == -1 && index < values.length) {
while(index < values.length && !isSet(index++));
nextIndex = index-1;
if(!isSet(nextIndex)) nextIndex = -1;
}
return nextIndex != -1;
}
public int nextEntry() {
if(!hasNext()) throw new NoSuchElementException();
lastReturnValue = nextIndex;
return nextIndex;
}
public void remove() {
if(lastReturnValue == -1) throw new IllegalStateException();
clear(lastReturnValue);
values[lastReturnValue] = EMPTY_VALUE;
}
}
}
@@ -0,0 +1,198 @@
package speiger.src.collections.PACKAGE.maps.interfaces;
import java.util.Map;
#if VALUE_OBJECT && !TYPE_OBJECT
import java.util.Objects;
#endif
import java.util.function.BiConsumer;
import java.util.function.BiFunction;
import java.util.function.Consumer;
import java.util.function.Function;
import speiger.src.collections.VALUE_PACKAGE.collections.VALUE_COLLECTION;
import speiger.src.collections.PACKAGE.functions.consumer.BI_CONSUMER;
import speiger.src.collections.PACKAGE.functions.function.FUNCTION;
import speiger.src.collections.PACKAGE.functions.function.UNARY_OPERATOR;
import speiger.src.collections.PACKAGE.sets.SET;
#if !SAME_TYPE
import speiger.src.collections.VALUE_PACKAGE.functions.function.VALUE_UNARY_OPERATOR;
#endif
import speiger.src.collections.objects.collections.ObjectIterator;
#if !TYPE_OBJECT
import speiger.src.collections.objects.sets.ObjectSet;
#endif
public interface MAP KEY_VALUE_GENERIC_TYPE extends Map<CLASS_TYPE, CLASS_VALUE_TYPE>, FUNCTION KEY_VALUE_GENERIC_TYPE
{
public VALUE_TYPE getDefaultReturnValue();
public MAP KEY_VALUE_GENERIC_TYPE setDefaultReturnValue(VALUE_TYPE v);
public VALUE_TYPE put(KEY_TYPE key, VALUE_TYPE value);
public VALUE_TYPE putIfAbsent(KEY_TYPE key, VALUE_TYPE value);
#if VALUE_PRIMITIVES
public VALUE_TYPE addTo(KEY_TYPE key, VALUE_TYPE value);
#endif
public void putAll(MAP KEY_VALUE_GENERIC_TYPE m);
#if !TYPE_OBJECT
public boolean containsKey(KEY_TYPE key);
@Override
public default boolean containsKey(Object key) {
return key instanceof CLASS_TYPE && containsKey(CLASS_TO_KEY(key));
}
#endif
#if !VALUE_OBJECT
public boolean containsValue(VALUE_TYPE value);
@Override
public default boolean containsValue(Object value) {
return value instanceof CLASS_VALUE_TYPE && containsValue(CLASS_TO_VALUE(value));
}
#endif
public VALUE_TYPE REMOVE_KEY(KEY_TYPE key);
@Override
public default CLASS_VALUE_TYPE remove(Object key) {
#if TYPE_OBJECT
return VALUE_TO_OBJ(REMOVE_KEY((CLASS_TYPE)key));
#else
return key instanceof CLASS_TYPE ? VALUE_TO_OBJ(REMOVE_KEY(CLASS_TO_KEY(key))) : VALUE_TO_OBJ(getDefaultReturnValue());
#endif
}
#if !TYPE_OBJECT || !VALUE_OBJECT
public boolean remove(KEY_TYPE key, VALUE_TYPE value);
@Override
public default boolean remove(Object key, Object value) {
#if TYPE_OBJECT
return value instanceof CLASS_VALUE_TYPE && remove((KEY_TYPE)key, CLASS_TO_VALUE(value));
#else if VALUE_OBJECT
return key instanceof CLASS_TYPE && remove(CLASS_TO_KEY(key), (VALUE_TYPE)value);
#else
return key instanceof CLASS_TYPE && value instanceof CLASS_VALUE_TYPE && remove(CLASS_TO_KEY(key), CLASS_TO_VALUE(value));
#endif
}
#endif
public boolean replace(KEY_TYPE key, VALUE_TYPE oldValue, VALUE_TYPE newValue);
public VALUE_TYPE replace(KEY_TYPE key, VALUE_TYPE value);
public void REPLACE_VALUES(UNARY_OPERATOR KEY_VALUE_GENERIC_TYPE mappingFunction);
public VALUE_TYPE COMPUTE(KEY_TYPE key, UNARY_OPERATOR KEY_VALUE_GENERIC_TYPE mappingFunction);
public VALUE_TYPE COMPUTE_IF_ABSENT(KEY_TYPE key, FUNCTION KEY_VALUE_GENERIC_TYPE mappingFunction);
public VALUE_TYPE COMPUTE_IF_PRESENT(KEY_TYPE key, UNARY_OPERATOR KEY_VALUE_GENERIC_TYPE mappingFunction);
public VALUE_TYPE MERGE(KEY_TYPE key, VALUE_TYPE value, VALUE_UNARY_OPERATOR VALUE_VALUE_GENERIC_TYPE mappingFunction);
#if !TYPE_OBJECT || !VALUE_OBJECT
@Override
public default boolean replace(CLASS_TYPE key, CLASS_VALUE_TYPE oldValue, CLASS_VALUE_TYPE newValue) {
return replace(OBJ_TO_KEY(key), OBJ_TO_VALUE(oldValue), OBJ_TO_VALUE(newValue));
}
@Override
public default CLASS_VALUE_TYPE replace(CLASS_TYPE key, CLASS_VALUE_TYPE value) {
return VALUE_TO_OBJ(replace(OBJ_TO_KEY(key), OBJ_TO_VALUE(value)));
}
@Override
public VALUE_TYPE GET_VALUE(KEY_TYPE key);
public VALUE_TYPE getOrDefault(KEY_TYPE key, VALUE_TYPE defaultValue);
@Override
public default CLASS_VALUE_TYPE get(Object key) {
#if TYPE_OBJECT
return VALUE_TO_OBJ(GET_VALUE((CLASS_TYPE)key));
#else
return VALUE_TO_OBJ(key instanceof CLASS_TYPE ? GET_VALUE(CLASS_TO_KEY(key)) : getDefaultReturnValue());
#endif
}
@Override
public default CLASS_VALUE_TYPE getOrDefault(Object key, CLASS_VALUE_TYPE defaultValue) {
#if TYPE_OBJECT
CLASS_VALUE_TYPE value = VALUE_TO_OBJ(GET_VALUE((CLASS_TYPE)key));
#else
CLASS_VALUE_TYPE value = VALUE_TO_OBJ(key instanceof CLASS_TYPE ? GET_VALUE(CLASS_TO_KEY(key)) : getDefaultReturnValue());
#endif
return VALUE_EQUALS_NOT(value, getDefaultReturnValue()) || containsKey(key) ? value : defaultValue;
}
#endif
@Override
public default void replaceAll(BiFunction<? super CLASS_TYPE, ? super CLASS_VALUE_TYPE, ? extends CLASS_VALUE_TYPE> mappingFunction) {
REPLACE_VALUES(mappingFunction instanceof UNARY_OPERATOR ? (UNARY_OPERATOR KEY_VALUE_GENERIC_TYPE)mappingFunction : (K, V) -> OBJ_TO_VALUE(mappingFunction.apply(KEY_TO_OBJ(K), VALUE_TO_OBJ(V))));
}
@Override
public default CLASS_VALUE_TYPE compute(CLASS_TYPE key, BiFunction<? super CLASS_TYPE, ? super CLASS_VALUE_TYPE, ? extends CLASS_VALUE_TYPE> mappingFunction) {
return VALUE_TO_OBJ(COMPUTE(OBJ_TO_KEY(key), mappingFunction instanceof UNARY_OPERATOR ? (UNARY_OPERATOR KEY_VALUE_GENERIC_TYPE)mappingFunction : (K, V) -> OBJ_TO_VALUE(mappingFunction.apply(KEY_TO_OBJ(K), VALUE_TO_OBJ(V)))));
}
@Override
public default CLASS_VALUE_TYPE computeIfAbsent(CLASS_TYPE key, Function<? super CLASS_TYPE, ? extends CLASS_VALUE_TYPE> mappingFunction) {
return VALUE_TO_OBJ(COMPUTE_IF_ABSENT(OBJ_TO_KEY(key), mappingFunction instanceof FUNCTION ? (FUNCTION KEY_VALUE_GENERIC_TYPE)mappingFunction : K -> OBJ_TO_VALUE(mappingFunction.apply(KEY_TO_OBJ(K)))));
}
@Override
public default CLASS_VALUE_TYPE computeIfPresent(CLASS_TYPE key, BiFunction<? super CLASS_TYPE, ? super CLASS_VALUE_TYPE, ? extends CLASS_VALUE_TYPE> mappingFunction) {
return VALUE_TO_OBJ(COMPUTE_IF_PRESENT(OBJ_TO_KEY(key), mappingFunction instanceof UNARY_OPERATOR ? (UNARY_OPERATOR KEY_VALUE_GENERIC_TYPE)mappingFunction : (K, V) -> OBJ_TO_VALUE(mappingFunction.apply(KEY_TO_OBJ(K), VALUE_TO_OBJ(V)))));
}
@Override
public default CLASS_VALUE_TYPE merge(CLASS_TYPE key, CLASS_VALUE_TYPE value, BiFunction<? super CLASS_VALUE_TYPE, ? super CLASS_VALUE_TYPE, ? extends CLASS_VALUE_TYPE> mappingFunction) {
return VALUE_TO_OBJ(MERGE(OBJ_TO_KEY(key), OBJ_TO_VALUE(value), mappingFunction instanceof VALUE_UNARY_OPERATOR ? (VALUE_UNARY_OPERATOR VALUE_VALUE_GENERIC_TYPE)mappingFunction : (K, V) -> OBJ_TO_VALUE(mappingFunction.apply(VALUE_TO_OBJ(K), VALUE_TO_OBJ(V)))));
}
public void forEach(BI_CONSUMER KEY_VALUE_GENERIC_TYPE action);
@Override
public default void forEach(BiConsumer<? super CLASS_TYPE, ? super CLASS_VALUE_TYPE> action) {
forEach(action instanceof BI_CONSUMER ? (BI_CONSUMER KEY_VALUE_GENERIC_TYPE)action : (K, V) -> action.accept(KEY_TO_OBJ(K), VALUE_TO_OBJ(V)));
}
@Override
public SET KEY_GENERIC_TYPE keySet();
@Override
public VALUE_COLLECTION VALUE_GENERIC_TYPE values();
@Override
public ObjectSet<Map.Entry<CLASS_TYPE, CLASS_VALUE_TYPE>> entrySet();
public ObjectSet<Entry KEY_VALUE_GENERIC_TYPE> ENTRY_SET();
#if !TYPE_OBJECT || !VALUE_OBJECT
@Override
public default CLASS_VALUE_TYPE put(CLASS_TYPE key, CLASS_VALUE_TYPE value) {
return VALUE_TO_OBJ(put(OBJ_TO_KEY(key), OBJ_TO_VALUE(value)));
}
@Override
public default CLASS_VALUE_TYPE putIfAbsent(CLASS_TYPE key, CLASS_VALUE_TYPE value) {
return VALUE_TO_OBJ(put(OBJ_TO_KEY(key), OBJ_TO_VALUE(value)));
}
#endif
public interface FastEntrySet KEY_VALUE_GENERIC_TYPE extends ObjectSet<MAP.Entry KEY_VALUE_GENERIC_TYPE>
{
public ObjectIterator<MAP.Entry KEY_VALUE_GENERIC_TYPE> fastIterator();
public default void fastForEach(Consumer<? super MAP.Entry KEY_VALUE_GENERIC_TYPE> action) {
forEach(action);
}
}
public interface Entry KEY_VALUE_GENERIC_TYPE extends Map.Entry<CLASS_TYPE, CLASS_VALUE_TYPE>
{
#if !TYPE_OBJECT
public KEY_TYPE ENTRY_KEY();
public default CLASS_TYPE getKey() { return KEY_TO_OBJ(ENTRY_KEY()); }
#endif
#if !VALUE_OBJECT
public VALUE_TYPE ENTRY_VALUE();
public VALUE_TYPE setValue(VALUE_TYPE value);
public default CLASS_VALUE_TYPE getValue() { return VALUE_TO_OBJ(ENTRY_VALUE()); }
public default CLASS_VALUE_TYPE setValue(CLASS_VALUE_TYPE value) { return VALUE_TO_OBJ(setValue(OBJ_TO_VALUE(value))); }
#endif
}
}
@@ -0,0 +1,95 @@
package speiger.src.collections.PACKAGE.maps.interfaces;
import java.util.NavigableMap;
import speiger.src.collections.PACKAGE.sets.NAVIGABLE_SET;
public interface NAVIGABLE_MAP KEY_VALUE_GENERIC_TYPE extends SORTED_MAP KEY_VALUE_GENERIC_TYPE, NavigableMap<CLASS_TYPE, CLASS_VALUE_TYPE>
{
@Override
public NAVIGABLE_MAP KEY_VALUE_GENERIC_TYPE descendingMap();
@Override
public NAVIGABLE_SET KEY_GENERIC_TYPE navigableKeySet();
@Override
public NAVIGABLE_SET KEY_GENERIC_TYPE descendingKeySet();
@Override
public MAP.Entry KEY_VALUE_GENERIC_TYPE firstEntry();
@Override
public MAP.Entry KEY_VALUE_GENERIC_TYPE lastEntry();
@Override
public MAP.Entry KEY_VALUE_GENERIC_TYPE pollFirstEntry();
@Override
public MAP.Entry KEY_VALUE_GENERIC_TYPE pollLastEntry();
#if !TYPE_OBJECT
public NAVIGABLE_MAP KEY_VALUE_GENERIC_TYPE subMap(KEY_TYPE fromKey, boolean fromInclusive, KEY_TYPE toKey, boolean toInclusive);
public NAVIGABLE_MAP KEY_VALUE_GENERIC_TYPE headMap(KEY_TYPE toKey, boolean inclusive);
public NAVIGABLE_MAP KEY_VALUE_GENERIC_TYPE tailMap(KEY_TYPE fromKey, boolean inclusive);
@Override
public default NAVIGABLE_MAP KEY_VALUE_GENERIC_TYPE subMap(KEY_TYPE fromKey, KEY_TYPE toKey) { return subMap(fromKey, true, toKey, false); }
@Override
public default NAVIGABLE_MAP KEY_VALUE_GENERIC_TYPE headMap(KEY_TYPE toKey) { return headMap(toKey, false); }
@Override
public default NAVIGABLE_MAP KEY_VALUE_GENERIC_TYPE tailMap(KEY_TYPE fromKey) { return tailMap(fromKey, true); }
public void setDefaultMaxValue(KEY_TYPE e);
public KEY_TYPE getDefaultMaxValue();
public void setDefaultMinValue(KEY_TYPE e);
public KEY_TYPE getDefaultMinValue();
public KEY_TYPE lowerKey(KEY_TYPE key);
public KEY_TYPE higherKey(KEY_TYPE key);
public KEY_TYPE floorKey(KEY_TYPE key);
public KEY_TYPE ceilingKey(KEY_TYPE key);
public MAP.Entry KEY_VALUE_GENERIC_TYPE lowerEntry(KEY_TYPE key);
public MAP.Entry KEY_VALUE_GENERIC_TYPE higherEntry(KEY_TYPE key);
public MAP.Entry KEY_VALUE_GENERIC_TYPE floorEntry(KEY_TYPE key);
public MAP.Entry KEY_VALUE_GENERIC_TYPE ceilingEntry(KEY_TYPE key);
@Override
public default CLASS_TYPE lowerKey(CLASS_TYPE key) { return KEY_TO_OBJ(lowerKey(OBJ_TO_KEY(key)));}
@Override
public default CLASS_TYPE floorKey(CLASS_TYPE key) { return KEY_TO_OBJ(floorKey(OBJ_TO_KEY(key)));}
@Override
public default CLASS_TYPE ceilingKey(CLASS_TYPE key) { return KEY_TO_OBJ(ceilingKey(OBJ_TO_KEY(key)));}
@Override
public default CLASS_TYPE higherKey(CLASS_TYPE key) { return KEY_TO_OBJ(higherKey(OBJ_TO_KEY(key)));}
@Override
default MAP.Entry KEY_VALUE_GENERIC_TYPE lowerEntry(CLASS_TYPE key) { return lowerEntry(OBJ_TO_KEY(key)); }
@Override
default MAP.Entry KEY_VALUE_GENERIC_TYPE floorEntry(CLASS_TYPE key) { return floorEntry(OBJ_TO_KEY(key)); }
@Override
default MAP.Entry KEY_VALUE_GENERIC_TYPE ceilingEntry(CLASS_TYPE key) { return ceilingEntry(OBJ_TO_KEY(key)); }
@Override
default MAP.Entry KEY_VALUE_GENERIC_TYPE higherEntry(CLASS_TYPE key) { return higherEntry(OBJ_TO_KEY(key)); }
@Override
default NAVIGABLE_MAP KEY_VALUE_GENERIC_TYPE subMap(CLASS_TYPE fromKey, boolean fromInclusive, CLASS_TYPE toKey, boolean toInclusive) { return subMap(OBJ_TO_KEY(fromKey), fromInclusive, OBJ_TO_KEY(toKey), toInclusive); }
@Override
default NAVIGABLE_MAP KEY_VALUE_GENERIC_TYPE headMap(CLASS_TYPE toKey, boolean inclusive) { return headMap(OBJ_TO_KEY(toKey), inclusive); }
@Override
default NAVIGABLE_MAP KEY_VALUE_GENERIC_TYPE tailMap(CLASS_TYPE fromKey, boolean inclusive) { return tailMap(OBJ_TO_KEY(fromKey), inclusive); }
@Override
default NAVIGABLE_MAP KEY_VALUE_GENERIC_TYPE subMap(CLASS_TYPE fromKey, CLASS_TYPE toKey) { return subMap(OBJ_TO_KEY(fromKey), true, OBJ_TO_KEY(toKey), false); }
@Override
default NAVIGABLE_MAP KEY_VALUE_GENERIC_TYPE headMap(CLASS_TYPE toKey) { return headMap(OBJ_TO_KEY(toKey), false); }
@Override
default NAVIGABLE_MAP KEY_VALUE_GENERIC_TYPE tailMap(CLASS_TYPE fromKey) { return tailMap(OBJ_TO_KEY(fromKey), true); }
#else
@Override
public NAVIGABLE_MAP KEY_VALUE_GENERIC_TYPE subMap(CLASS_TYPE fromKey, boolean fromInclusive, CLASS_TYPE toKey, boolean toInclusive);
@Override
public NAVIGABLE_MAP KEY_VALUE_GENERIC_TYPE headMap(CLASS_TYPE toKey, boolean inclusive);
@Override
public NAVIGABLE_MAP KEY_VALUE_GENERIC_TYPE tailMap(CLASS_TYPE fromKey, boolean inclusive);
@Override
public default NAVIGABLE_MAP KEY_VALUE_GENERIC_TYPE subMap(CLASS_TYPE fromKey, CLASS_TYPE toKey) { return subMap(fromKey, true, toKey, false); }
@Override
public default NAVIGABLE_MAP KEY_VALUE_GENERIC_TYPE headMap(CLASS_TYPE toKey) { return headMap(toKey, false); }
@Override
public default NAVIGABLE_MAP KEY_VALUE_GENERIC_TYPE tailMap(CLASS_TYPE fromKey) { return tailMap(fromKey, true); }
#endif
}
@@ -0,0 +1,73 @@
package speiger.src.collections.PACKAGE.maps.interfaces;
#if TYPE_OBJECT
import java.util.Comparator;
#endif
import java.util.SortedMap;
import speiger.src.collections.VALUE_PACKAGE.collections.VALUE_COLLECTION;
#if !TYPE_OBJECT
import speiger.src.collections.PACKAGE.functions.COMPARATOR;
#endif
import speiger.src.collections.PACKAGE.sets.SET;
import speiger.src.collections.objects.sets.ObjectSortedSet;
import speiger.src.collections.objects.collections.ObjectBidirectionalIterator;
public interface SORTED_MAP KEY_VALUE_GENERIC_TYPE extends SortedMap<CLASS_TYPE, CLASS_VALUE_TYPE>, MAP KEY_VALUE_GENERIC_TYPE
{
public VALUE_TYPE putAndMoveToFirst(KEY_TYPE key, VALUE_TYPE value);
public VALUE_TYPE putAndMoveToLast(KEY_TYPE key, VALUE_TYPE value);
public boolean moveToFirst(KEY_TYPE key);
public boolean moveToLast(KEY_TYPE key);
public VALUE_TYPE getAndMoveToFirst(KEY_TYPE key);
public VALUE_TYPE getAndMoveToLast(KEY_TYPE key);
@Override
public COMPARATOR KEY_GENERIC_TYPE comparator();
@Override
public SET KEY_GENERIC_TYPE keySet();
@Override
public VALUE_COLLECTION VALUE_GENERIC_TYPE values();
#if !TYPE_OBJECT
public SORTED_MAP KEY_VALUE_GENERIC_TYPE subMap(KEY_TYPE fromKey, KEY_TYPE toKey);
public SORTED_MAP KEY_VALUE_GENERIC_TYPE headMap(KEY_TYPE toKey);
public SORTED_MAP KEY_VALUE_GENERIC_TYPE tailMap(KEY_TYPE fromKey);
public KEY_TYPE FIRST_ENTRY_KEY();
public KEY_TYPE POLL_FIRST_ENTRY_KEY();
public KEY_TYPE LAST_ENTRY_KEY();
public KEY_TYPE POLL_LAST_ENTRY_KEY();
public VALUE_TYPE FIRST_ENTRY_VALUE();
public VALUE_TYPE LAST_ENTRY_VALUE();
public default CLASS_TYPE firstKey() { return KEY_TO_OBJ(FIRST_ENTRY_KEY()); }
public default CLASS_TYPE lastKey() { return KEY_TO_OBJ(LAST_ENTRY_KEY()); }
@Override
@Deprecated
public default SORTED_MAP KEY_VALUE_GENERIC_TYPE subMap(CLASS_TYPE fromKey, CLASS_TYPE toKey) { return subMap(OBJ_TO_KEY(fromKey), OBJ_TO_KEY(toKey)); }
@Override
@Deprecated
public default SORTED_MAP KEY_VALUE_GENERIC_TYPE headMap(CLASS_TYPE toKey) { return headMap(OBJ_TO_KEY(toKey)); }
@Override
@Deprecated
public default SORTED_MAP KEY_VALUE_GENERIC_TYPE tailMap(CLASS_TYPE fromKey) { return tailMap(OBJ_TO_KEY(fromKey)); }
#else
public KEY_TYPE POLL_FIRST_ENTRY_KEY();
public KEY_TYPE POLL_LAST_ENTRY_KEY();
public VALUE_TYPE FIRST_ENTRY_VALUE();
public VALUE_TYPE LAST_ENTRY_VALUE();
#endif
interface FastSortedSet KEY_VALUE_GENERIC_TYPE extends MAP.FastEntrySet KEY_VALUE_GENERIC_TYPE, ObjectSortedSet<MAP.Entry KEY_VALUE_GENERIC_TYPE> {
@Override
public ObjectBidirectionalIterator<MAP.Entry KEY_VALUE_GENERIC_TYPE> fastIterator();
public ObjectBidirectionalIterator<MAP.Entry KEY_VALUE_GENERIC_TYPE> fastIterator(KEY_TYPE fromElement);
}
}
@@ -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<m;i++) {
int index = (first + i) % array.length;
if(e == array[index])
return removeIndex(index);
}
return false;
}
@Override
public boolean REMOVE_LAST(KEY_TYPE e) {
if(first == last) return false;
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 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<m;i++)
input[i] = KEY_TO_OBJ(array[first + i]);
}
else {
int offset = 0;
for(int i = 0,m=array.length-first;i<m;i++,offset++)
input[i] = KEY_TO_OBJ(array[first + i]);
for(int i = 0;i<last;i++)
input[offset+i] = KEY_TO_OBJ(array[i]);
}
return input;
}
#endif
protected void reduce() {
final int size = size();
if (array.length > 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;
}
}
}
@@ -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_KEY_BRACES ARRAY_PRIORITY_QUEUE KEY_GENERIC_TYPE wrap(KEY_TYPE[] array) {
return wrap(array, array.length);
}
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;
}
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);
}
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, 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 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<size;i++)
if(KEY_EQUALS(e, array[i])) return removeIndex(i);
return false;
}
@Override
public boolean REMOVE_LAST(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 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<size;i++) input[i] = KEY_TO_OBJ(array[i]);
return input;
}
#endif
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;
}
public class Iter implements ITERATOR KEY_GENERIC_TYPE {
@Override
public boolean hasNext() {
return !isEmpty();
}
@Override
public KEY_TYPE NEXT() {
return DEQUEUE();
}
}
}
@@ -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_KEY_BRACES HEAP_PRIORITY_QUEUE KEY_GENERIC_TYPE wrap(KEY_TYPE[] array) {
return wrap(array, array.length);
}
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;
}
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);
}
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, 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<size;i++)
if(KEY_EQUALS(e, array[i])) return removeIndex(i);
return false;
}
@Override
public boolean REMOVE_LAST(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) {
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<size;i++) input[i] = KEY_TO_OBJ(array[i]);
return input;
}
#endif
public class Iter implements ITERATOR KEY_GENERIC_TYPE {
@Override
public boolean hasNext() {
return !isEmpty();
}
@Override
public KEY_TYPE NEXT() {
return DEQUEUE();
}
}
}
@@ -0,0 +1,14 @@
package speiger.src.collections.PACKAGE.queues;
public interface PRIORITY_DEQUEUE KEY_GENERIC_TYPE extends PRIORITY_QUEUE KEY_GENERIC_TYPE
{
public void ENQUEUE_FIRST(KEY_TYPE e);
public KEY_TYPE DEQUEUE_LAST();
public default KEY_TYPE LAST_KEY() { return PEEK(size()-1); }
#if !TYPE_OBJECT
public default void enqueueFirst(CLASS_TYPE e) { ENQUEUE_FIRST(OBJ_TO_KEY(e)); }
public default CLASS_TYPE dequeueLast() { return KEY_TO_OBJ(DEQUEUE_LAST()); }
public default CLASS_TYPE last() { return peek(size()-1); }
#endif
}
@@ -0,0 +1,56 @@
package speiger.src.collections.PACKAGE.queues;
#if TYPE_OBJECT
import java.util.Comparator;
#else
import speiger.src.collections.PACKAGE.collections.ITERABLE;
import speiger.src.collections.PACKAGE.functions.COMPARATOR;
import speiger.src.collections.objects.queues.ObjectPriorityQueue;
#endif
#if TYPE_OBJECT
public interface PRIORITY_QUEUE KEY_GENERIC_TYPE extends Iterable<KEY_TYPE>
#else
public interface PRIORITY_QUEUE KEY_GENERIC_TYPE extends ObjectPriorityQueue<CLASS_TYPE>, 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 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 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
}
@@ -0,0 +1,52 @@
package speiger.src.collections.PACKAGE.sets;
import java.util.Iterator;
import java.util.Objects;
import java.util.Set;
import speiger.src.collections.PACKAGE.collections.ABSTRACT_COLLECTION;
import speiger.src.collections.PACKAGE.collections.ITERATOR;
public abstract class ABSTRACT_SET KEY_GENERIC_TYPE extends ABSTRACT_COLLECTION KEY_GENERIC_TYPE implements SET KEY_GENERIC_TYPE
{
@Override
public abstract ITERATOR KEY_GENERIC_TYPE iterator();
@Override
public int hashCode() {
int hashCode = 1;
ITERATOR KEY_GENERIC_TYPE i = iterator();
while(i.hasNext())
hashCode = 31 * hashCode + KEY_TO_HASH(i.NEXT());
return hashCode;
}
@Override
public boolean equals(Object o) {
if (o == this)
return true;
if (!(o instanceof Set))
return false;
Set<?> l = (Set<?>)o;
if(l.size() != size()) return false;
#if !TYPE_OBJECT
if(l instanceof SET)
{
ITERATOR e1 = iterator();
ITERATOR e2 = ((SET)l).iterator();
while (e1.hasNext() && e2.hasNext()) {
if(!(KEY_EQUALS(e1.NEXT(), e2.NEXT())))
return false;
}
return !(e1.hasNext() || e2.hasNext());
}
#endif
Iterator<CLASS_TYPE> e1 = iterator();
Iterator<?> e2 = l.iterator();
while (e1.hasNext() && e2.hasNext()) {
if(!Objects.equals(e1.next(), e2.next()))
return false;
}
return !(e1.hasNext() || e2.hasNext());
}
}
@@ -0,0 +1,699 @@
package speiger.src.collections.PACKAGE.sets;
import java.util.Arrays;
import java.util.Collection;
#if TYPE_OBJECT
import java.util.Comparator;
import java.util.function.Consumer;
#endif
import java.util.NoSuchElementException;
import java.util.Objects;
import java.util.Set;
#if PRIMITIVES
import java.util.function.JAVA_PREDICATE;
#endif
import speiger.src.collections.PACKAGE.collections.BI_ITERATOR;
import speiger.src.collections.PACKAGE.collections.COLLECTION;
#if !TYPE_OBJECT
import speiger.src.collections.PACKAGE.functions.COMPARATOR;
import speiger.src.collections.PACKAGE.functions.CONSUMER;
#endif
import speiger.src.collections.PACKAGE.lists.LIST_ITERATOR;
import speiger.src.collections.PACKAGE.utils.ARRAYS;
public class ARRAY_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_TYPE implements SORTED_SET KEY_GENERIC_TYPE
{
protected transient KEY_TYPE[] data;
protected int size = 0;
public ARRAY_SET() {
data = EMPTY_KEY_ARRAY;
}
public ARRAY_SET(int capacity) {
data = NEW_KEY_ARRAY(capacity);
}
public ARRAY_SET(KEY_TYPE[] array) {
this(array, array.length);
}
public ARRAY_SET(KEY_TYPE[] array, int length) {
data = Arrays.copyOf(array, length);
size = length;
}
@Deprecated
public ARRAY_SET(Collection<? extends CLASS_TYPE> c) {
this(c.size());
addAll(c);
}
public ARRAY_SET(COLLECTION KEY_GENERIC_TYPE c) {
this(c.size());
addAll(c);
}
@Deprecated
public ARRAY_SET(Set<? extends CLASS_TYPE> s) {
this(s.size());
for(CLASS_TYPE e : s)
data[size++] = OBJ_TO_KEY(e);
}
public ARRAY_SET(SET KEY_GENERIC_TYPE s) {
this(s.size());
for(KEY_TYPE e : s)
data[size++] = e;
}
@Override
public boolean add(KEY_TYPE o) {
int index = findIndex(o);
if(index == -1) {
if(data.length == size) data = Arrays.copyOf(data, size == 0 ? 2 : size * 2);
data[size++] = o;
return true;
}
return false;
}
@Override
public boolean addAndMoveToFirst(KEY_TYPE o) {
int index = findIndex(o);
if(index == -1) {
if(data.length == size) data = Arrays.copyOf(data, size == 0 ? 2 : size * 2);
System.arraycopy(data, 0, data, 1, size++);
data[0] = o;
return true;
}
else if(index != 0) {
o = data[index];
System.arraycopy(data, 0, data, 1, index);
data[0] = o;
}
return false;
}
@Override
public boolean addAndMoveToLast(KEY_TYPE o) {
int index = findIndex(o);
if(index == -1) {
if(data.length == size) data = Arrays.copyOf(data, size == 0 ? 2 : size * 2);
data[size++] = o;
return true;
}
else if(index != size - 1) {
o = data[index];
System.arraycopy(data, index+1, data, index, size - index);
data[size-1] = o;
}
return false;
}
@Override
public boolean moveToFirst(KEY_TYPE o) {
int index = findIndex(o);
if(index > 0) {
o = data[index];
System.arraycopy(data, 0, data, 1, index);
data[0] = o;
return true;
}
return false;
}
@Override
public boolean moveToLast(KEY_TYPE o) {
int index = findIndex(o);
if(index != -1 && index != size - 1) {
o = data[index];
System.arraycopy(data, index+1, data, index, size - index - 1);
data[size-1] = o;
return true;
}
return false;
}
#if !TYPE_OBJECT
@Override
public boolean contains(KEY_TYPE e) {
return findIndex(e) != -1;
}
#else
@Override
public boolean contains(Object e) {
return findIndex(e) != -1;
}
#endif
@Override
public KEY_TYPE FIRST_KEY() {
if(size == 0) throw new NoSuchElementException();
return data[0];
}
@Override
public KEY_TYPE LAST_KEY() {
if(size == 0) throw new NoSuchElementException();
return data[size - 1];
}
#if !TYPE_OBJECT
@Override
public boolean remove(KEY_TYPE o) {
int index = findIndex(o);
if(index != -1) {
size--;
if(index != size) System.arraycopy(data, index+1, data, index, size - index);
#if TYPE_OBJECT
data[size] = EMPTY_KEY_VALUE;
#endif
return true;
}
return false;
}
#else
@Override
public boolean remove(Object o) {
int index = findIndex(o);
if(index != -1) {
size--;
if(index != size) System.arraycopy(data, index+1, data, index, size - index);
#if TYPE_OBJECT
data[size] = EMPTY_KEY_VALUE;
#endif
return true;
}
return false;
}
#endif
@Override
public KEY_TYPE POLL_FIRST_KEY() {
if(size == 0) throw new NoSuchElementException();
KEY_TYPE result = data[0];
System.arraycopy(data, 1, data, 0, --size);
#if TYPE_OBJECT
data[size] = EMPTY_KEY_VALUE;
#endif
return result;
}
@Override
public KEY_TYPE POLL_LAST_KEY() {
if(size == 0) throw new NoSuchElementException();
size--;
#if TYPE_OBJECT
KEY_TYPE result = data[size];
data[size] = EMPTY_KEY_VALUE;
return result;
#else
return data[size];
#endif
}
#if PRIMITIVES
@Override
public boolean remIf(JAVA_PREDICATE KEY_GENERIC_TYPE filter) {
Objects.requireNonNull(filter);
boolean modified = false;
int j = 0;
for(int i = 0;i<size;i++) {
if(!filter.test(data[i])) data[j++] = data[i];
else modified = true;
}
size = j;
return modified;
}
#endif
#if TYPE_OBJECT
@Override
public void forEach(Consumer KEY_SUPER_GENERIC_TYPE action) {
Objects.requireNonNull(action);
for(int i = 0;i<size;action.accept(data[i++]));
}
#else
@Override
public void forEach(CONSUMER KEY_GENERIC_TYPE action) {
Objects.requireNonNull(action);
for(int i = 0;i<size;action.accept(data[i++]));
}
#endif
#if !TYPE_OBJECT
protected int findIndex(KEY_TYPE o) {
for(int i = size-1;i>=0;i--)
if(KEY_EQUALS(data[i], o)) return i;
return -1;
}
#endif
protected int findIndex(Object o) {
for(int i = size-1;i>=0;i--)
if(EQUALS_KEY_TYPE(data[i], o)) return i;
return -1;
}
@Override
public BI_ITERATOR KEY_GENERIC_TYPE iterator() {
return new SetIterator(0);
}
@Override
public BI_ITERATOR KEY_GENERIC_TYPE iterator(KEY_TYPE fromElement) {
int index = findIndex(fromElement);
if(index != -1) return new SetIterator(index);
throw new NoSuchElementException();
}
@Override
public SORTED_SET KEY_GENERIC_TYPE subSet(KEY_TYPE fromElement, KEY_TYPE toElement) {
int fromIndex = findIndex(fromElement);
int toIndex = findIndex(toElement);
if(fromIndex == -1 || toIndex == -1) throw new NoSuchElementException();
return new SubSet(fromIndex, toIndex - fromIndex + 1);
}
@Override
public SORTED_SET KEY_GENERIC_TYPE headSet(KEY_TYPE toElement) {
int toIndex = findIndex(toElement);
if(toIndex == -1) throw new NoSuchElementException();
return new SubSet(0, toIndex+1);
}
@Override
public SORTED_SET KEY_GENERIC_TYPE tailSet(KEY_TYPE fromElement) {
int fromIndex = findIndex(fromElement);
if(fromIndex == -1) throw new NoSuchElementException();
return new SubSet(fromIndex, size - fromIndex);
}
@Override
public COMPARATOR KEY_GENERIC_TYPE comparator() {
return null;
}
@Override
public void clear() {
size = 0;
}
@Override
public int size() {
return size;
}
private class SubSet extends ABSTRACT_SET KEY_GENERIC_TYPE implements SORTED_SET KEY_GENERIC_TYPE {
int offset;
int length;
SubSet(int offset, int length) {
this.offset = offset;
this.length = length;
}
int end() { return offset+length; }
@Override
public boolean add(KEY_TYPE o) {
int index = findIndex(o);
if(index == -1) {
if(data.length == size) data = Arrays.copyOf(data, size == 0 ? 2 : size * 2);
if(end() != size) System.arraycopy(data, end(), data, end()+1, size-(offset+length));
data[end()] = o;
size++;
length++;
return true;
}
return false;
}
@Override
public boolean addAndMoveToFirst(KEY_TYPE o) {
int index = findIndex(o);
if(index == -1) {
if(data.length == size) data = Arrays.copyOf(data, size == 0 ? 2 : size * 2);
System.arraycopy(data, offset, data, offset+1, size-offset);
data[offset] = o;
size++;
length++;
return true;
}
else if(index != 0) {
o = data[index];
System.arraycopy(data, offset, data, offset+1, index-offset);
data[offset] = o;
}
return false;
}
@Override
public boolean addAndMoveToLast(KEY_TYPE o) {
int index = findIndex(o);
if(index == -1) {
if(data.length == size) data = Arrays.copyOf(data, size == 0 ? 2 : size * 2);
System.arraycopy(data, end()+1, data, end(), size-end());
data[end()] = o;
size++;
length++;
return true;
}
else if(index != 0) {
o = data[index];
System.arraycopy(data, offset+1, data, offset, index-offset);
data[offset+length] = o;
}
return false;
}
@Override
public boolean moveToFirst(KEY_TYPE o) {
int index = findIndex(o);
if(index > offset) {
o = data[index];
System.arraycopy(data, offset, data, offset+1, index-offset);
data[offset] = o;
return true;
}
return false;
}
@Override
public boolean moveToLast(KEY_TYPE o) {
int index = findIndex(o);
if(index != -1 && index < end()-1) {
o = data[index];
System.arraycopy(data, index+1, data, index, end()-index-1);
data[end()-1] = o;
return true;
}
return false;
}
#if !TYPE_OBJECT
@Override
public boolean contains(KEY_TYPE e) {
return findIndex(e) != -1;
}
#endif
@Override
public boolean contains(Object e) {
return findIndex(e) != -1;
}
@Override
public KEY_TYPE FIRST_KEY() {
if(length == 0) throw new NoSuchElementException();
return data[offset];
}
@Override
public KEY_TYPE LAST_KEY() {
if(length == 0) throw new NoSuchElementException();
return data[end()-1];
}
#if !TYPE_OBJECT
@Override
public boolean remove(KEY_TYPE o) {
int index = findIndex(o);
if(index != -1) {
size--;
length--;
if(index != size) System.arraycopy(data, index+1, data, index, size - index);
return true;
}
return false;
}
#endif
@Override
public boolean remove(Object o) {
int index = findIndex(o);
if(index != -1) {
size--;
length--;
if(index != size) System.arraycopy(data, index+1, data, index, size - index);
#if TYPE_OBJECT
data[size] = EMPTY_KEY_VALUE;
#endif
return true;
}
return false;
}
@Override
public KEY_TYPE POLL_FIRST_KEY() {
if(length == 0) throw new NoSuchElementException();
size--;
length--;
KEY_TYPE result = data[offset];
System.arraycopy(data, offset+1, data, offset, size-offset);
#if TYPE_OBJECT
data[size] = EMPTY_KEY_VALUE;
#endif
return result;
}
@Override
public KEY_TYPE POLL_LAST_KEY() {
if(length == 0) throw new NoSuchElementException();
KEY_TYPE result = data[offset+length];
size--;
length--;
System.arraycopy(data, end()+1, data, end(), size-end());
#if TYPE_OBJECT
data[size] = EMPTY_KEY_VALUE;
#endif
return result;
}
@Override
public COMPARATOR KEY_GENERIC_TYPE comparator() {
return null;
}
@Override
public BI_ITERATOR KEY_GENERIC_TYPE iterator() {
return new SetIterator(offset);
}
@Override
public BI_ITERATOR KEY_GENERIC_TYPE iterator(KEY_TYPE fromElement) {
int index = findIndex(fromElement);
if(index != -1) return new SetIterator(index);
throw new NoSuchElementException();
}
@Override
public SORTED_SET KEY_GENERIC_TYPE subSet(KEY_TYPE fromElement, KEY_TYPE toElement) {
int fromIndex = findIndex(fromElement);
int toIndex = findIndex(toElement);
if(fromIndex == -1 || toIndex == -1) throw new NoSuchElementException();
return new SubSet(fromIndex, toIndex - fromIndex);
}
@Override
public SORTED_SET KEY_GENERIC_TYPE headSet(KEY_TYPE toElement) {
int toIndex = findIndex(toElement);
if(toIndex == -1) throw new NoSuchElementException();
return new SubSet(0, toIndex);
}
@Override
public SORTED_SET KEY_GENERIC_TYPE tailSet(KEY_TYPE fromElement) {
int fromIndex = findIndex(fromElement);
if(fromIndex == -1) throw new NoSuchElementException();
return new SubSet(fromIndex, size - fromIndex);
}
@Override
public int size() {
return length;
}
#if !TYPE_OBJECT
protected int findIndex(KEY_TYPE o) {
for(int i = length-1;i>=0;i--)
if(KEY_EQUALS(data[offset+i], o)) return i + offset;
return -1;
}
#endif
protected int findIndex(Object o) {
for(int i = length-1;i>=0;i--)
if(EQUALS_KEY_TYPE(data[offset+i], o)) return i + offset;
return -1;
}
private class SetIterator implements LIST_ITERATOR KEY_GENERIC_TYPE {
int index;
int lastReturned = -1;
public SetIterator(int index) {
this.index = index;
}
@Override
public boolean hasNext() {
return index < size();
}
@Override
public KEY_TYPE NEXT() {
lastReturned = index;
return data[index++];
}
@Override
public boolean hasPrevious() {
return index > 0;
}
@Override
public KEY_TYPE PREVIOUS() {
lastReturned = index;
return data[index--];
}
@Override
public int nextIndex() {
return index;
}
@Override
public int previousIndex() {
return index-1;
}
@Override
public void remove() {
if(lastReturned == -1)
throw new IllegalStateException();
SubSet.this.remove(data[lastReturned]);
if(lastReturned < index)
index--;
lastReturned = -1;
}
#if TYPE_OBJECT
@Override
public void set(Object e) { throw new UnsupportedOperationException(); }
@Override
public void add(Object e) { throw new UnsupportedOperationException(); }
#else
@Override
public void set(KEY_TYPE e) { throw new UnsupportedOperationException(); }
@Override
public void add(KEY_TYPE e) { throw new UnsupportedOperationException(); }
#endif
@Override
public int skip(int amount) {
if(amount < 0) throw new IllegalStateException("Negative Numbers are not allowed");
int steps = Math.min(amount, (size() - 1) - index);
index += steps;
return steps;
}
@Override
public int back(int amount) {
if(amount < 0) throw new IllegalStateException("Negative Numbers are not allowed");
int steps = Math.min(amount, index);
index -= steps;
return steps;
}
}
}
private class SetIterator implements LIST_ITERATOR KEY_GENERIC_TYPE {
int index;
int lastReturned = -1;
public SetIterator(int index) {
this.index = index;
}
@Override
public boolean hasNext() {
return index < size();
}
@Override
public KEY_TYPE NEXT() {
lastReturned = index;
return data[index++];
}
@Override
public boolean hasPrevious() {
return index > 0;
}
@Override
public KEY_TYPE PREVIOUS() {
lastReturned = index;
return data[index--];
}
@Override
public int nextIndex() {
return index;
}
@Override
public int previousIndex() {
return index-1;
}
@Override
public void remove() {
if(lastReturned == -1)
throw new IllegalStateException();
ARRAY_SET.this.remove(data[lastReturned]);
if(lastReturned < index)
index--;
lastReturned = -1;
}
#if TYPE_OBJECT
@Override
public void set(Object e) { throw new UnsupportedOperationException(); }
@Override
public void add(Object e) { throw new UnsupportedOperationException(); }
#else
@Override
public void set(KEY_TYPE e) { throw new UnsupportedOperationException(); }
@Override
public void add(KEY_TYPE e) { throw new UnsupportedOperationException(); }
#endif
@Override
public int skip(int amount) {
if(amount < 0) throw new IllegalStateException("Negative Numbers are not allowed");
int steps = Math.min(amount, (size() - 1) - index);
index += steps;
return steps;
}
@Override
public int back(int amount) {
if(amount < 0) throw new IllegalStateException("Negative Numbers are not allowed");
int steps = Math.min(amount, index);
index -= steps;
return steps;
}
}
}
@@ -0,0 +1,556 @@
package speiger.src.collections.PACKAGE.sets;
#if TYPE_OBJECT
import java.util.Comparator;
#endif
import java.util.Collection;
import java.util.Iterator;
import java.util.NoSuchElementException;
import speiger.src.collections.PACKAGE.collections.COLLECTION;
#if !TYPE_OBJECT
import speiger.src.collections.PACKAGE.collections.ITERATOR;
#endif
import speiger.src.collections.PACKAGE.collections.BI_ITERATOR;
#if !TYPE_OBJECT
import speiger.src.collections.PACKAGE.functions.COMPARATOR;
#endif
import speiger.src.collections.PACKAGE.lists.LIST_ITERATOR;
#if !TYPE_OBJECT
import speiger.src.collections.PACKAGE.utils.ITERATORS;
#endif
import speiger.src.collections.PACKAGE.utils.STRATEGY;
import speiger.src.collections.utils.HashUtil;
import speiger.src.collections.utils.SanityChecks;
public class LINKED_CUSTOM_HASH_SET KEY_GENERIC_TYPE extends CUSTOM_HASH_SET KEY_GENERIC_TYPE implements SORTED_SET KEY_GENERIC_TYPE
{
protected long[] links;
protected int firstIndex = -1;
protected int lastIndex = -1;
public LINKED_CUSTOM_HASH_SET(STRATEGY KEY_SUPER_GENERIC_TYPE strategy) {
this(HashUtil.DEFAULT_MIN_CAPACITY, HashUtil.DEFAULT_LOAD_FACTOR, strategy);
}
public LINKED_CUSTOM_HASH_SET(int minCapacity, STRATEGY KEY_SUPER_GENERIC_TYPE strategy) {
this(minCapacity, HashUtil.DEFAULT_LOAD_FACTOR, strategy);
}
public LINKED_CUSTOM_HASH_SET(int minCapacity, float loadFactor, STRATEGY KEY_SUPER_GENERIC_TYPE strategy) {
super(minCapacity, loadFactor, strategy);
links = new long[nullIndex + 1];
}
public LINKED_CUSTOM_HASH_SET(KEY_TYPE[] array, STRATEGY KEY_SUPER_GENERIC_TYPE strategy) {
this(array, 0, array.length, HashUtil.DEFAULT_LOAD_FACTOR, strategy);
}
public LINKED_CUSTOM_HASH_SET(KEY_TYPE[] array, float loadFactor, STRATEGY KEY_SUPER_GENERIC_TYPE strategy) {
this(array, 0, array.length, loadFactor, strategy);
}
public LINKED_CUSTOM_HASH_SET(KEY_TYPE[] array, int offset, int length, STRATEGY KEY_SUPER_GENERIC_TYPE strategy) {
this(array, offset, length, HashUtil.DEFAULT_LOAD_FACTOR, strategy);
}
public LINKED_CUSTOM_HASH_SET(KEY_TYPE[] array, int offset, int length, float loadFactor, STRATEGY KEY_SUPER_GENERIC_TYPE strategy) {
this(length < 0 ? 0 : length, strategy);
SanityChecks.checkArrayCapacity(array.length, offset, length);
for(int i = 0;i<length;i++) add(array[offset+i]);
}
@Deprecated
public LINKED_CUSTOM_HASH_SET(Collection<? extends CLASS_TYPE> collection, STRATEGY KEY_SUPER_GENERIC_TYPE strategy) {
this(collection, HashUtil.DEFAULT_LOAD_FACTOR, strategy);
}
@Deprecated
public LINKED_CUSTOM_HASH_SET(Collection<? extends CLASS_TYPE> collection, float loadFactor, STRATEGY KEY_SUPER_GENERIC_TYPE strategy) {
this(collection.size(), loadFactor, strategy);
addAll(collection);
}
public LINKED_CUSTOM_HASH_SET(COLLECTION KEY_GENERIC_TYPE collection, STRATEGY KEY_SUPER_GENERIC_TYPE strategy) {
this(collection, HashUtil.DEFAULT_LOAD_FACTOR, strategy);
}
public LINKED_CUSTOM_HASH_SET(COLLECTION KEY_GENERIC_TYPE collection, float loadFactor, STRATEGY KEY_SUPER_GENERIC_TYPE strategy) {
this(collection.size(), strategy);
addAll(collection);
}
public LINKED_CUSTOM_HASH_SET(Iterator<CLASS_TYPE> iterator, STRATEGY KEY_SUPER_GENERIC_TYPE strategy) {
this(iterator, HashUtil.DEFAULT_LOAD_FACTOR, strategy);
}
public LINKED_CUSTOM_HASH_SET(Iterator<CLASS_TYPE> iterator, float loadFactor, STRATEGY KEY_SUPER_GENERIC_TYPE strategy) {
#if !TYPE_OBJECT
this(ITERATORS.wrap(iterator), loadFactor, strategy);
#else
this(HashUtil.DEFAULT_MIN_CAPACITY, loadFactor, strategy);
while(iterator.hasNext()) add(iterator.next());
#endif
}
#if !TYPE_OBJECT
public LINKED_CUSTOM_HASH_SET(ITERATOR KEY_GENERIC_TYPE iterator, STRATEGY KEY_SUPER_GENERIC_TYPE strategy) {
this(iterator, HashUtil.DEFAULT_LOAD_FACTOR, strategy);
}
public LINKED_CUSTOM_HASH_SET(ITERATOR KEY_GENERIC_TYPE iterator, float loadFactor, STRATEGY KEY_SUPER_GENERIC_TYPE strategy) {
this(HashUtil.DEFAULT_MIN_CAPACITY, loadFactor, strategy);
while(iterator.hasNext()) add(iterator.NEXT());
}
#endif
@Override
public boolean addAndMoveToFirst(KEY_TYPE o) {
if(strategy.equals(o, EMPTY_KEY_VALUE)) {
if(containsNull) {
moveToFirstIndex(nullIndex);
return false;
}
containsNull = true;
onNodeAdded(nullIndex);
}
else {
int pos = HashUtil.mix(strategy.hashCode(o)) & mask;
while(!strategy.equals(keys[pos], EMPTY_KEY_VALUE)) {
if(strategy.equals(keys[pos], o)) {
moveToFirstIndex(pos);
return false;
}
pos = ++pos & mask;
}
keys[pos] = o;
onNodeAdded(pos);
}
if(size++ >= maxFill) rehash(HashUtil.arraySize(size+1, loadFactor));
return true;
}
@Override
public boolean addAndMoveToLast(KEY_TYPE o) {
if(strategy.equals(o, EMPTY_KEY_VALUE)) {
if(containsNull) {
moveToLastIndex(nullIndex);
return false;
}
containsNull = true;
onNodeAdded(nullIndex);
}
else {
int pos = HashUtil.mix(strategy.hashCode(o)) & mask;
while(!strategy.equals(keys[pos], EMPTY_KEY_VALUE)) {
if(strategy.equals(keys[pos], o)) {
moveToLastIndex(pos);
return false;
}
pos = ++pos & mask;
}
keys[pos] = o;
onNodeAdded(pos);
}
if(size++ >= maxFill) rehash(HashUtil.arraySize(size+1, loadFactor));
return true;
}
@Override
public boolean moveToFirst(KEY_TYPE o) {
if(strategy.equals(FIRST_KEY(), o)) return false;
if(strategy.equals(o, EMPTY_KEY_VALUE)) {
if(containsNull) {
moveToFirstIndex(nullIndex);
return true;
}
}
else {
int pos = HashUtil.mix(strategy.hashCode(o)) & mask;
while(!strategy.equals(keys[pos], EMPTY_KEY_VALUE)) {
if(strategy.equals(keys[pos], o)) {
moveToFirstIndex(pos);
return true;
}
pos = ++pos & mask;
}
}
return false;
}
@Override
public boolean moveToLast(KEY_TYPE o) {
if(strategy.equals(LAST_KEY(), o)) return false;
if(strategy.equals(o, EMPTY_KEY_VALUE)) {
if(containsNull) {
moveToLastIndex(nullIndex);
return true;
}
}
else {
int pos = HashUtil.mix(strategy.hashCode(o)) & mask;
while(!strategy.equals(keys[pos], EMPTY_KEY_VALUE)) {
if(strategy.equals(keys[pos], o)) {
moveToLastIndex(pos);
return true;
}
pos = ++pos & mask;
}
}
return false;
}
protected void moveToFirstIndex(int startPos) {
if(size == 1 || firstIndex == startPos) return;
if(lastIndex == startPos) {
lastIndex = (int)(links[startPos] >>> 32);
links[lastIndex] |= 0xFFFFFFFFL;
}
else {
long link = links[startPos];
int prev = (int)(link >>> 32);
int next = (int)link;
links[prev] ^= ((links[prev] ^ (link & 0xFFFFFFFFL)) & 0xFFFFFFFFL);
links[next] ^= ((links[next] ^ (link & 0xFFFFFFFF00000000L)) & 0xFFFFFFFF00000000L);
}
links[firstIndex] ^= ((links[firstIndex] ^ ((startPos & 0xFFFFFFFFL) << 32)) & 0xFFFFFFFF00000000L);
links[startPos] = 0xFFFFFFFF00000000L | (firstIndex & 0xFFFFFFFFL);
firstIndex = startPos;
}
protected void moveToLastIndex(int startPos) {
if(size == 1 || lastIndex == startPos) return;
if(firstIndex == startPos) {
firstIndex = (int)links[startPos];
links[lastIndex] |= 0xFFFFFFFF00000000L;
}
else {
long link = links[startPos];
int prev = (int)(link >>> 32);
int next = (int)link;
links[prev] ^= ((links[prev] ^ (link & 0xFFFFFFFFL)) & 0xFFFFFFFFL);
links[next] ^= ((links[next] ^ (link & 0xFFFFFFFF00000000L)) & 0xFFFFFFFF00000000L);
}
links[lastIndex] ^= ((links[lastIndex] ^ (startPos & 0xFFFFFFFFL)) & 0xFFFFFFFFL);
links[startPos] = ((lastIndex & 0xFFFFFFFFL) << 32) | 0xFFFFFFFFL;
lastIndex = startPos;
}
@Override
public KEY_TYPE FIRST_KEY() {
if(size == 0) throw new NoSuchElementException();
return keys[firstIndex];
}
@Override
public KEY_TYPE POLL_FIRST_KEY() {
if(size == 0) throw new NoSuchElementException();
int pos = firstIndex;
firstIndex = (int)links[pos];
if(0 <= firstIndex) links[firstIndex] |= 0xFFFFFFFF00000000L;
KEY_TYPE result = keys[pos];
size--;
if(strategy.equals(result, EMPTY_KEY_VALUE)) {
containsNull = false;
keys[nullIndex] = EMPTY_KEY_VALUE;
}
else shiftKeys(pos);
if(nullIndex > minCapacity && size < maxFill / 4 && nullIndex > HashUtil.DEFAULT_MIN_CAPACITY) rehash(nullIndex / 2);
return result;
}
@Override
public KEY_TYPE LAST_KEY() {
if(size == 0) throw new NoSuchElementException();
return keys[lastIndex];
}
@Override
public KEY_TYPE POLL_LAST_KEY() {
if(size == 0) throw new NoSuchElementException();
int pos = lastIndex;
lastIndex = (int)(links[pos] >>> 32);
if(0 <= lastIndex) links[lastIndex] |= 0xFFFFFFFFL;
KEY_TYPE result = keys[pos];
size--;
if(strategy.equals(result, EMPTY_KEY_VALUE)) {
containsNull = false;
keys[nullIndex] = EMPTY_KEY_VALUE;
}
else shiftKeys(pos);
if(nullIndex > minCapacity && size < maxFill / 4 && nullIndex > HashUtil.DEFAULT_MIN_CAPACITY) rehash(nullIndex / 2);
return result;
}
@Override
protected void onNodeAdded(int pos) {
if(size == 0) {
firstIndex = lastIndex = pos;
links[pos] = -1L;
}
else {
links[lastIndex] ^= ((links[lastIndex] ^ (pos & 0xFFFFFFFFL)) & 0xFFFFFFFFL);
links[pos] = ((lastIndex & 0xFFFFFFFFL) << 32) | 0xFFFFFFFFL;
lastIndex = pos;
}
}
@Override
protected void onNodeRemoved(int pos) {
if(size == 0) firstIndex = lastIndex = -1;
else if(firstIndex == pos) {
firstIndex = (int)links[pos];
if(0 <= firstIndex) links[firstIndex] |= 0xFFFFFFFF00000000L;
}
else if(lastIndex == pos) {
lastIndex = (int)(links[pos] >>> 32);
if(0 <= lastIndex) links[pos] |= 0xFFFFFFFFL;
}
else {
long link = links[pos];
int prev = (int)(link >>> 32);
int next = (int)link;
links[prev] ^= ((links[prev] ^ (link & 0xFFFFFFFFL)) & 0xFFFFFFFFL);
links[next] ^= ((links[next] ^ (link & 0xFFFFFFFF00000000L)) & 0xFFFFFFFF00000000L);
}
}
@Override
protected void onNodeMoved(int from, int to) {
if(size == 1) {
firstIndex = lastIndex = to;
links[to] = -1L;
}
else if(firstIndex == from) {
firstIndex = to;
links[(int)links[from]] ^= ((links[(int)links[from]] ^ ((to & 0xFFFFFFFFL) << 32)) & 0xFFFFFFFF00000000L);
links[to] = links[from];
}
else if(lastIndex == from) {
lastIndex = to;
links[(int)(links[from] >>> 32)] ^= ((links[(int)(links[from] >>> 32)] ^ (to & 0xFFFFFFFFL)) & 0xFFFFFFFFL);
links[to] = links[from];
}
else {
long link = links[from];
int prev = (int)(link >>> 32);
int next = (int)link;
links[prev] ^= ((links[prev] ^ (to & 0xFFFFFFFFL)) & 0xFFFFFFFFL);
links[next] ^= ((links[next] ^ ((to & 0xFFFFFFFFL) << 32)) & 0xFFFFFFFF00000000L);
links[to] = link;
}
}
@Override
protected void rehash(int newSize) {
int newMask = newSize - 1;
KEY_TYPE[] newKeys = NEW_KEY_ARRAY(newSize + 1);
long[] newLinks = new long[newSize + 1];
int newPrev = -1;
for(int j = size, i = firstIndex, pos = 0, prev = -1;j != 0;) {
if(strategy.equals(keys[i], EMPTY_KEY_VALUE)) pos = newSize;
else {
pos = HashUtil.mix(strategy.hashCode(keys[i])) & newMask;
while(!strategy.equals(newKeys[pos], EMPTY_KEY_VALUE)) pos = ++pos & newMask;
}
newKeys[pos] = keys[i];
if(prev != -1) {
newLinks[newPrev] ^= ((newLinks[newPrev] ^ (pos & 0xFFFFFFFFL)) & 0xFFFFFFFFL);
newLinks[pos] ^= ((newLinks[pos] ^ ((newPrev & 0xFFFFFFFFL) << 32)) & 0xFFFFFFFF00000000L);
newPrev = pos;
}
else {
newPrev = firstIndex = pos;
newLinks[pos] = -1L;
}
i = (int)links[prev = i];
}
links = newLinks;
lastIndex = newPrev;
if(newPrev != -1) newLinks[newPrev] |= 0xFFFFFFFFL;
nullIndex = newSize;
mask = newMask;
maxFill = Math.min((int)Math.ceil(nullIndex * loadFactor), nullIndex - 1);
keys = newKeys;
}
@Override
public void clear() {
super.clear();
firstIndex = lastIndex = -1;
}
@Override
public LIST_ITERATOR KEY_GENERIC_TYPE iterator() {
return new SetIterator();
}
@Override
public BI_ITERATOR KEY_GENERIC_TYPE iterator(KEY_TYPE fromElement) {
return new SetIterator(fromElement);
}
@Override
public COMPARATOR KEY_GENERIC_TYPE comparator() { return null; }
@Override
public SORTED_SET KEY_GENERIC_TYPE subSet(KEY_TYPE fromElement, KEY_TYPE toElement) { throw new UnsupportedOperationException(); }
@Override
public SORTED_SET KEY_GENERIC_TYPE headSet(KEY_TYPE toElement) { throw new UnsupportedOperationException(); }
@Override
public SORTED_SET KEY_GENERIC_TYPE tailSet(KEY_TYPE fromElement) { throw new UnsupportedOperationException(); }
private class SetIterator implements LIST_ITERATOR KEY_GENERIC_TYPE {
int previous = -1;
int next = -1;
int current = -1;
int index = 0;
SetIterator() {
next = firstIndex;
}
SetIterator(KEY_TYPE from) {
if(strategy.equals(from, EMPTY_KEY_VALUE)) {
if(containsNull) {
next = (int) links[nullIndex];
previous = nullIndex;
}
else throw new NoSuchElementException("The null element is not in the set");
}
else if(strategy.equals(keys[lastIndex], from)) {
previous = lastIndex;
index = size;
}
else {
int pos = HashUtil.mix(strategy.hashCode(from)) & mask;
while(!strategy.equals(keys[pos], EMPTY_KEY_VALUE)) {
if(strategy.equals(keys[pos], from)) {
next = (int)links[pos];
previous = pos;
break;
}
pos = ++pos & mask;
}
if(previous == -1 && next == -1)
throw new NoSuchElementException("The element was not found");
}
}
@Override
public boolean hasNext() {
return next != -1;
}
@Override
public boolean hasPrevious() {
return previous != -1;
}
@Override
public int nextIndex() {
ensureIndexKnown();
return index;
}
@Override
public int previousIndex() {
ensureIndexKnown();
return index - 1;
}
@Override
public void remove() {
if(current == -1) throw new IllegalStateException();
ensureIndexKnown();
if(current == previous) {
index--;
previous = (int)(links[current] >>> 32);
}
else next = (int)links[current];
size--;
if(previous == -1) firstIndex = next;
else links[previous] ^= ((links[previous] ^ (next & 0xFFFFFFFFL)) & 0xFFFFFFFFL);
if (next == -1) lastIndex = previous;
else links[next] ^= ((links[next] ^ ((previous & 0xFFFFFFFFL) << 32)) & 0xFFFFFFFF00000000L);
if(current == nullIndex) {
current = -1;
containsNull = false;
keys[nullIndex] = EMPTY_KEY_VALUE;
}
else {
int slot, last, startPos = current;
current = -1;
KEY_TYPE current;
while(true) {
startPos = ((last = startPos) + 1) & mask;
while(true){
if(strategy.equals((current = keys[startPos]), EMPTY_KEY_VALUE)) {
keys[last] = EMPTY_KEY_VALUE;
return;
}
slot = HashUtil.mix(strategy.hashCode(current)) & mask;
if(last <= startPos ? (last >= slot || slot > startPos) : (last >= slot && slot > startPos)) break;
startPos = ++startPos & mask;
}
keys[last] = current;
if(next == startPos) next = last;
if(previous == startPos) previous = last;
onNodeMoved(startPos, last);
}
}
}
@Override
public KEY_TYPE PREVIOUS() {
if(!hasPrevious()) throw new NoSuchElementException();
current = previous;
previous = (int)(links[current] >> 32);
next = current;
if(index >= 0) index--;
return keys[current];
}
@Override
public KEY_TYPE NEXT() {
if(!hasNext()) throw new NoSuchElementException();
current = next;
next = (int)(links[current]);
previous = current;
if(index >= 0) index++;
return keys[current];
}
private void ensureIndexKnown() {
if(index == -1) {
if(previous == -1) {
index = 0;
}
else if(next == -1) {
index = size;
}
else {
index = 1;
for(int pos = firstIndex;pos != previous;pos = (int)links[pos], index++);
}
}
}
#if TYPE_OBJECT
@Override
public void set(Object e) { throw new UnsupportedOperationException(); }
@Override
public void add(Object e) { throw new UnsupportedOperationException(); }
#else
@Override
public void set(KEY_TYPE e) { throw new UnsupportedOperationException(); }
@Override
public void add(KEY_TYPE e) { throw new UnsupportedOperationException(); }
#endif
}
}
@@ -0,0 +1,558 @@
package speiger.src.collections.PACKAGE.sets;
#if TYPE_OBJECT
import java.util.Comparator;
#endif
import java.util.Collection;
import java.util.Iterator;
import java.util.NoSuchElementException;
#if TYPE_OBJECT
import java.util.Objects;
#endif
import speiger.src.collections.PACKAGE.collections.COLLECTION;
#if !TYPE_OBJECT
import speiger.src.collections.PACKAGE.collections.ITERATOR;
#endif
import speiger.src.collections.PACKAGE.collections.BI_ITERATOR;
#if !TYPE_OBJECT
import speiger.src.collections.PACKAGE.functions.COMPARATOR;
#endif
import speiger.src.collections.PACKAGE.lists.LIST_ITERATOR;
#if !TYPE_OBJECT
import speiger.src.collections.PACKAGE.utils.ITERATORS;
#endif
import speiger.src.collections.utils.HashUtil;
import speiger.src.collections.utils.SanityChecks;
public class LINKED_HASH_SET KEY_GENERIC_TYPE extends HASH_SET KEY_GENERIC_TYPE implements SORTED_SET KEY_GENERIC_TYPE
{
protected long[] links;
protected int firstIndex = -1;
protected int lastIndex = -1;
public LINKED_HASH_SET() {
this(HashUtil.DEFAULT_MIN_CAPACITY, HashUtil.DEFAULT_LOAD_FACTOR);
}
public LINKED_HASH_SET(int minCapacity) {
this(minCapacity, HashUtil.DEFAULT_LOAD_FACTOR);
}
public LINKED_HASH_SET(int minCapacity, float loadFactor) {
super(minCapacity, loadFactor);
links = new long[nullIndex + 1];
}
public LINKED_HASH_SET(KEY_TYPE[] array) {
this(array, 0, array.length, HashUtil.DEFAULT_LOAD_FACTOR);
}
public LINKED_HASH_SET(KEY_TYPE[] array, float loadFactor) {
this(array, 0, array.length, loadFactor);
}
public LINKED_HASH_SET(KEY_TYPE[] array, int offset, int length) {
this(array, offset, length, HashUtil.DEFAULT_LOAD_FACTOR);
}
public LINKED_HASH_SET(KEY_TYPE[] array, int offset, int length, float loadFactor) {
this(length < 0 ? 0 : length);
SanityChecks.checkArrayCapacity(array.length, offset, length);
for(int i = 0;i<length;i++) add(array[offset+i]);
}
@Deprecated
public LINKED_HASH_SET(Collection<? extends CLASS_TYPE> collection) {
this(collection, HashUtil.DEFAULT_LOAD_FACTOR);
}
@Deprecated
public LINKED_HASH_SET(Collection<? extends CLASS_TYPE> collection, float loadFactor) {
this(collection.size(), loadFactor);
addAll(collection);
}
public LINKED_HASH_SET(COLLECTION KEY_GENERIC_TYPE collection) {
this(collection, HashUtil.DEFAULT_LOAD_FACTOR);
}
public LINKED_HASH_SET(COLLECTION KEY_GENERIC_TYPE collection, float loadFactor) {
this(collection.size());
addAll(collection);
}
public LINKED_HASH_SET(Iterator<CLASS_TYPE> iterator) {
this(iterator, HashUtil.DEFAULT_LOAD_FACTOR);
}
public LINKED_HASH_SET(Iterator<CLASS_TYPE> iterator, float loadFactor) {
#if !TYPE_OBJECT
this(ITERATORS.wrap(iterator), loadFactor);
#else
this(HashUtil.DEFAULT_MIN_CAPACITY, loadFactor);
while(iterator.hasNext()) add(iterator.next());
#endif
}
#if !TYPE_OBJECT
public LINKED_HASH_SET(ITERATOR KEY_GENERIC_TYPE iterator) {
this(iterator, HashUtil.DEFAULT_LOAD_FACTOR);
}
public LINKED_HASH_SET(ITERATOR KEY_GENERIC_TYPE iterator, float loadFactor) {
this(HashUtil.DEFAULT_MIN_CAPACITY, loadFactor);
while(iterator.hasNext()) add(iterator.NEXT());
}
#endif
@Override
public boolean addAndMoveToFirst(KEY_TYPE o) {
if(KEY_EQUALS_NULL(o)) {
if(containsNull) {
moveToFirstIndex(nullIndex);
return false;
}
containsNull = true;
onNodeAdded(nullIndex);
}
else {
int pos = HashUtil.mix(KEY_TO_HASH(o)) & mask;
while(KEY_EQUALS_NOT_NULL(keys[pos])) {
if(KEY_EQUALS(keys[pos], o)) {
moveToFirstIndex(pos);
return false;
}
pos = ++pos & mask;
}
keys[pos] = o;
onNodeAdded(pos);
}
if(size++ >= maxFill) rehash(HashUtil.arraySize(size+1, loadFactor));
return true;
}
@Override
public boolean addAndMoveToLast(KEY_TYPE o) {
if(KEY_EQUALS_NULL(o)) {
if(containsNull) {
moveToLastIndex(nullIndex);
return false;
}
containsNull = true;
onNodeAdded(nullIndex);
}
else {
int pos = HashUtil.mix(KEY_TO_HASH(o)) & mask;
while(KEY_EQUALS_NOT_NULL(keys[pos])) {
if(KEY_EQUALS(keys[pos], o)) {
moveToLastIndex(pos);
return false;
}
pos = ++pos & mask;
}
keys[pos] = o;
onNodeAdded(pos);
}
if(size++ >= maxFill) rehash(HashUtil.arraySize(size+1, loadFactor));
return true;
}
@Override
public boolean moveToFirst(KEY_TYPE o) {
if(KEY_EQUALS(FIRST_KEY(), o)) return false;
if(KEY_EQUALS_NULL(o)) {
if(containsNull) {
moveToFirstIndex(nullIndex);
return true;
}
}
else {
int pos = HashUtil.mix(KEY_TO_HASH(o)) & mask;
while(KEY_EQUALS_NOT_NULL(keys[pos])) {
if(KEY_EQUALS(keys[pos], o)) {
moveToFirstIndex(pos);
return true;
}
pos = ++pos & mask;
}
}
return false;
}
@Override
public boolean moveToLast(KEY_TYPE o) {
if(KEY_EQUALS(LAST_KEY(), o)) return false;
if(KEY_EQUALS_NULL(o)) {
if(containsNull) {
moveToLastIndex(nullIndex);
return true;
}
}
else {
int pos = HashUtil.mix(KEY_TO_HASH(o)) & mask;
while(KEY_EQUALS_NOT_NULL(keys[pos])) {
if(KEY_EQUALS(keys[pos], o)) {
moveToLastIndex(pos);
return true;
}
pos = ++pos & mask;
}
}
return false;
}
protected void moveToFirstIndex(int startPos) {
if(size == 1 || firstIndex == startPos) return;
if(lastIndex == startPos) {
lastIndex = (int)(links[startPos] >>> 32);
links[lastIndex] |= 0xFFFFFFFFL;
}
else {
long link = links[startPos];
int prev = (int)(link >>> 32);
int next = (int)link;
links[prev] ^= ((links[prev] ^ (link & 0xFFFFFFFFL)) & 0xFFFFFFFFL);
links[next] ^= ((links[next] ^ (link & 0xFFFFFFFF00000000L)) & 0xFFFFFFFF00000000L);
}
links[firstIndex] ^= ((links[firstIndex] ^ ((startPos & 0xFFFFFFFFL) << 32)) & 0xFFFFFFFF00000000L);
links[startPos] = 0xFFFFFFFF00000000L | (firstIndex & 0xFFFFFFFFL);
firstIndex = startPos;
}
protected void moveToLastIndex(int startPos) {
if(size == 1 || lastIndex == startPos) return;
if(firstIndex == startPos) {
firstIndex = (int)links[startPos];
links[lastIndex] |= 0xFFFFFFFF00000000L;
}
else {
long link = links[startPos];
int prev = (int)(link >>> 32);
int next = (int)link;
links[prev] ^= ((links[prev] ^ (link & 0xFFFFFFFFL)) & 0xFFFFFFFFL);
links[next] ^= ((links[next] ^ (link & 0xFFFFFFFF00000000L)) & 0xFFFFFFFF00000000L);
}
links[lastIndex] ^= ((links[lastIndex] ^ (startPos & 0xFFFFFFFFL)) & 0xFFFFFFFFL);
links[startPos] = ((lastIndex & 0xFFFFFFFFL) << 32) | 0xFFFFFFFFL;
lastIndex = startPos;
}
@Override
public KEY_TYPE FIRST_KEY() {
if(size == 0) throw new NoSuchElementException();
return keys[firstIndex];
}
@Override
public KEY_TYPE POLL_FIRST_KEY() {
if(size == 0) throw new NoSuchElementException();
int pos = firstIndex;
firstIndex = (int)links[pos];
if(0 <= firstIndex) links[firstIndex] |= 0xFFFFFFFF00000000L;
KEY_TYPE result = keys[pos];
size--;
if(KEY_EQUALS_NULL(result)) {
containsNull = false;
keys[nullIndex] = EMPTY_KEY_VALUE;
}
else shiftKeys(pos);
if(nullIndex > minCapacity && size < maxFill / 4 && nullIndex > HashUtil.DEFAULT_MIN_CAPACITY) rehash(nullIndex / 2);
return result;
}
@Override
public KEY_TYPE LAST_KEY() {
if(size == 0) throw new NoSuchElementException();
return keys[lastIndex];
}
@Override
public KEY_TYPE POLL_LAST_KEY() {
if(size == 0) throw new NoSuchElementException();
int pos = lastIndex;
lastIndex = (int)(links[pos] >>> 32);
if(0 <= lastIndex) links[lastIndex] |= 0xFFFFFFFFL;
KEY_TYPE result = keys[pos];
size--;
if(KEY_EQUALS_NULL(result)) {
containsNull = false;
keys[nullIndex] = EMPTY_KEY_VALUE;
}
else shiftKeys(pos);
if(nullIndex > minCapacity && size < maxFill / 4 && nullIndex > HashUtil.DEFAULT_MIN_CAPACITY) rehash(nullIndex / 2);
return result;
}
@Override
protected void onNodeAdded(int pos) {
if(size == 0) {
firstIndex = lastIndex = pos;
links[pos] = -1L;
}
else {
links[lastIndex] ^= ((links[lastIndex] ^ (pos & 0xFFFFFFFFL)) & 0xFFFFFFFFL);
links[pos] = ((lastIndex & 0xFFFFFFFFL) << 32) | 0xFFFFFFFFL;
lastIndex = pos;
}
}
@Override
protected void onNodeRemoved(int pos) {
if(size == 0) firstIndex = lastIndex = -1;
else if(firstIndex == pos) {
firstIndex = (int)links[pos];
if(0 <= firstIndex) links[firstIndex] |= 0xFFFFFFFF00000000L;
}
else if(lastIndex == pos) {
lastIndex = (int)(links[pos] >>> 32);
if(0 <= lastIndex) links[pos] |= 0xFFFFFFFFL;
}
else {
long link = links[pos];
int prev = (int)(link >>> 32);
int next = (int)link;
links[prev] ^= ((links[prev] ^ (link & 0xFFFFFFFFL)) & 0xFFFFFFFFL);
links[next] ^= ((links[next] ^ (link & 0xFFFFFFFF00000000L)) & 0xFFFFFFFF00000000L);
}
}
@Override
protected void onNodeMoved(int from, int to) {
if(size == 1) {
firstIndex = lastIndex = to;
links[to] = -1L;
}
else if(firstIndex == from) {
firstIndex = to;
links[(int)links[from]] ^= ((links[(int)links[from]] ^ ((to & 0xFFFFFFFFL) << 32)) & 0xFFFFFFFF00000000L);
links[to] = links[from];
}
else if(lastIndex == from) {
lastIndex = to;
links[(int)(links[from] >>> 32)] ^= ((links[(int)(links[from] >>> 32)] ^ (to & 0xFFFFFFFFL)) & 0xFFFFFFFFL);
links[to] = links[from];
}
else {
long link = links[from];
int prev = (int)(link >>> 32);
int next = (int)link;
links[prev] ^= ((links[prev] ^ (to & 0xFFFFFFFFL)) & 0xFFFFFFFFL);
links[next] ^= ((links[next] ^ ((to & 0xFFFFFFFFL) << 32)) & 0xFFFFFFFF00000000L);
links[to] = link;
}
}
@Override
protected void rehash(int newSize) {
int newMask = newSize - 1;
KEY_TYPE[] newKeys = NEW_KEY_ARRAY(newSize + 1);
long[] newLinks = new long[newSize + 1];
int newPrev = -1;
for(int j = size, i = firstIndex, pos = 0, prev = -1;j != 0;) {
if(KEY_EQUALS_NULL(keys[i])) pos = newSize;
else {
pos = HashUtil.mix(KEY_TO_HASH(keys[i])) & newMask;
while(KEY_EQUALS_NOT_NULL(newKeys[pos])) pos = ++pos & newMask;
}
newKeys[pos] = keys[i];
if(prev != -1) {
newLinks[newPrev] ^= ((newLinks[newPrev] ^ (pos & 0xFFFFFFFFL)) & 0xFFFFFFFFL);
newLinks[pos] ^= ((newLinks[pos] ^ ((newPrev & 0xFFFFFFFFL) << 32)) & 0xFFFFFFFF00000000L);
newPrev = pos;
}
else {
newPrev = firstIndex = pos;
newLinks[pos] = -1L;
}
i = (int)links[prev = i];
}
links = newLinks;
lastIndex = newPrev;
if(newPrev != -1) newLinks[newPrev] |= 0xFFFFFFFFL;
nullIndex = newSize;
mask = newMask;
maxFill = Math.min((int)Math.ceil(nullIndex * loadFactor), nullIndex - 1);
keys = newKeys;
}
@Override
public void clear() {
super.clear();
firstIndex = lastIndex = -1;
}
@Override
public LIST_ITERATOR KEY_GENERIC_TYPE iterator() {
return new SetIterator();
}
@Override
public BI_ITERATOR KEY_GENERIC_TYPE iterator(KEY_TYPE fromElement) {
return new SetIterator(fromElement);
}
@Override
public COMPARATOR KEY_GENERIC_TYPE comparator() { return null; }
@Override
public SORTED_SET KEY_GENERIC_TYPE subSet(KEY_TYPE fromElement, KEY_TYPE toElement) { throw new UnsupportedOperationException(); }
@Override
public SORTED_SET KEY_GENERIC_TYPE headSet(KEY_TYPE toElement) { throw new UnsupportedOperationException(); }
@Override
public SORTED_SET KEY_GENERIC_TYPE tailSet(KEY_TYPE fromElement) { throw new UnsupportedOperationException(); }
private class SetIterator implements LIST_ITERATOR KEY_GENERIC_TYPE {
int previous = -1;
int next = -1;
int current = -1;
int index = 0;
SetIterator() {
next = firstIndex;
}
SetIterator(KEY_TYPE from) {
if(KEY_EQUALS_NULL(from)) {
if(containsNull) {
next = (int) links[nullIndex];
previous = nullIndex;
}
else throw new NoSuchElementException("The null element is not in the set");
}
else if(KEY_EQUALS(keys[lastIndex], from)) {
previous = lastIndex;
index = size;
}
else {
int pos = HashUtil.mix(KEY_TO_HASH(from)) & mask;
while(KEY_EQUALS_NOT_NULL(keys[pos])) {
if(KEY_EQUALS(keys[pos], from)) {
next = (int)links[pos];
previous = pos;
break;
}
pos = ++pos & mask;
}
if(previous == -1 && next == -1)
throw new NoSuchElementException("The element was not found");
}
}
@Override
public boolean hasNext() {
return next != -1;
}
@Override
public boolean hasPrevious() {
return previous != -1;
}
@Override
public int nextIndex() {
ensureIndexKnown();
return index;
}
@Override
public int previousIndex() {
ensureIndexKnown();
return index - 1;
}
@Override
public void remove() {
if(current == -1) throw new IllegalStateException();
ensureIndexKnown();
if(current == previous) {
index--;
previous = (int)(links[current] >>> 32);
}
else next = (int)links[current];
size--;
if(previous == -1) firstIndex = next;
else links[previous] ^= ((links[previous] ^ (next & 0xFFFFFFFFL)) & 0xFFFFFFFFL);
if (next == -1) lastIndex = previous;
else links[next] ^= ((links[next] ^ ((previous & 0xFFFFFFFFL) << 32)) & 0xFFFFFFFF00000000L);
if(current == nullIndex) {
current = -1;
containsNull = false;
keys[nullIndex] = EMPTY_KEY_VALUE;
}
else {
int slot, last, startPos = current;
current = -1;
KEY_TYPE current;
while(true) {
startPos = ((last = startPos) + 1) & mask;
while(true){
if(KEY_EQUALS_NULL((current = keys[startPos]))) {
keys[last] = EMPTY_KEY_VALUE;
return;
}
slot = HashUtil.mix(KEY_TO_HASH(current)) & mask;
if(last <= startPos ? (last >= slot || slot > startPos) : (last >= slot && slot > startPos)) break;
startPos = ++startPos & mask;
}
keys[last] = current;
if(next == startPos) next = last;
if(previous == startPos) previous = last;
onNodeMoved(startPos, last);
}
}
}
@Override
public KEY_TYPE PREVIOUS() {
if(!hasPrevious()) throw new NoSuchElementException();
current = previous;
previous = (int)(links[current] >> 32);
next = current;
if(index >= 0) index--;
return keys[current];
}
@Override
public KEY_TYPE NEXT() {
if(!hasNext()) throw new NoSuchElementException();
current = next;
next = (int)(links[current]);
previous = current;
if(index >= 0) index++;
return keys[current];
}
private void ensureIndexKnown() {
if(index == -1) {
if(previous == -1) {
index = 0;
}
else if(next == -1) {
index = size;
}
else {
index = 1;
for(int pos = firstIndex;pos != previous;pos = (int)links[pos], index++);
}
}
}
#if TYPE_OBJECT
@Override
public void set(Object e) { throw new UnsupportedOperationException(); }
@Override
public void add(Object e) { throw new UnsupportedOperationException(); }
#else
@Override
public void set(KEY_TYPE e) { throw new UnsupportedOperationException(); }
@Override
public void add(KEY_TYPE e) { throw new UnsupportedOperationException(); }
#endif
}
}
@@ -0,0 +1,127 @@
package speiger.src.collections.PACKAGE.sets;
import java.util.NavigableSet;
import speiger.src.collections.PACKAGE.collections.BI_ITERATOR;
public interface NAVIGABLE_SET KEY_GENERIC_TYPE extends NavigableSet<CLASS_TYPE>, SORTED_SET KEY_GENERIC_TYPE
{
#if !TYPE_OBJECT
public KEY_TYPE lower(KEY_TYPE e);
public KEY_TYPE floor(KEY_TYPE e);
public KEY_TYPE ceiling(KEY_TYPE e);
public KEY_TYPE higher(KEY_TYPE e);
public void setDefaultMaxValue(KEY_TYPE e);
public KEY_TYPE getDefaultMaxValue();
public void setDefaultMinValue(KEY_TYPE e);
public KEY_TYPE getDefaultMinValue();
@Override
public default NAVIGABLE_SET KEY_GENERIC_TYPE subSet(KEY_TYPE fromElement, KEY_TYPE toElement) { return subSet(fromElement, true, toElement, false); }
@Override
public default NAVIGABLE_SET KEY_GENERIC_TYPE headSet(KEY_TYPE toElement) { return headSet(toElement, false); }
@Override
public default NAVIGABLE_SET KEY_GENERIC_TYPE tailSet(KEY_TYPE fromElement) { return tailSet(fromElement, true); }
public NAVIGABLE_SET KEY_GENERIC_TYPE subSet(KEY_TYPE fromElement, boolean fromInclusive, KEY_TYPE toElement, boolean toInclusive);
public NAVIGABLE_SET KEY_GENERIC_TYPE headSet(KEY_TYPE toElement, boolean inclusive);
public NAVIGABLE_SET KEY_GENERIC_TYPE tailSet(KEY_TYPE fromElement, boolean inclusive);
#else
@Override
public default NAVIGABLE_SET KEY_GENERIC_TYPE subSet(KEY_TYPE fromElement, KEY_TYPE toElement) { return subSet(fromElement, true, toElement, false); }
@Override
public default NAVIGABLE_SET KEY_GENERIC_TYPE headSet(KEY_TYPE toElement) { return headSet(toElement, false); }
@Override
public default NAVIGABLE_SET KEY_GENERIC_TYPE tailSet(KEY_TYPE fromElement) { return tailSet(fromElement, true); }
@Override
public NAVIGABLE_SET KEY_GENERIC_TYPE subSet(KEY_TYPE fromElement, boolean fromInclusive, KEY_TYPE toElement, boolean toInclusive);
@Override
public NAVIGABLE_SET KEY_GENERIC_TYPE headSet(KEY_TYPE toElement, boolean inclusive);
@Override
public NAVIGABLE_SET KEY_GENERIC_TYPE tailSet(KEY_TYPE fromElement, boolean inclusive);
#endif
@Override
public BI_ITERATOR KEY_GENERIC_TYPE iterator();
@Override
public BI_ITERATOR KEY_GENERIC_TYPE descendingIterator();
@Override
public NAVIGABLE_SET KEY_GENERIC_TYPE descendingSet();
#if !TYPE_OBJECT
@Override
@Deprecated
public default CLASS_TYPE lower(CLASS_TYPE e) { return KEY_TO_OBJ(lower(OBJ_TO_KEY(e))); }
@Override
@Deprecated
public default CLASS_TYPE floor(CLASS_TYPE e) { return KEY_TO_OBJ(floor(OBJ_TO_KEY(e))); }
@Override
@Deprecated
public default CLASS_TYPE ceiling(CLASS_TYPE e) { return KEY_TO_OBJ(ceiling(OBJ_TO_KEY(e))); }
@Override
@Deprecated
public default CLASS_TYPE higher(CLASS_TYPE e) { return KEY_TO_OBJ(higher(OBJ_TO_KEY(e))); }
@Override
@Deprecated
default CLASS_TYPE first() { return SORTED_SET.super.first(); }
@Override
@Deprecated
default CLASS_TYPE last() { return SORTED_SET.super.last(); }
@Override
@Deprecated
public default CLASS_TYPE pollFirst() { return KEY_TO_OBJ(POLL_FIRST_KEY()); }
@Override
@Deprecated
public default CLASS_TYPE pollLast() { return KEY_TO_OBJ(POLL_LAST_KEY()); }
@Override
@Deprecated
public default NAVIGABLE_SET KEY_GENERIC_TYPE subSet(CLASS_TYPE fromElement, boolean fromInclusive, CLASS_TYPE toElement, boolean toInclusive) { return subSet(OBJ_TO_KEY(fromElement), fromInclusive, OBJ_TO_KEY(toElement), toInclusive); }
@Override
@Deprecated
public default NAVIGABLE_SET KEY_GENERIC_TYPE headSet(CLASS_TYPE toElement, boolean inclusive) { return headSet(OBJ_TO_KEY(toElement), inclusive); }
@Override
@Deprecated
public default NAVIGABLE_SET KEY_GENERIC_TYPE tailSet(CLASS_TYPE fromElement, boolean inclusive) { return tailSet(OBJ_TO_KEY(fromElement), inclusive); }
@Override
@Deprecated
public default SORTED_SET KEY_GENERIC_TYPE subSet(CLASS_TYPE fromElement, CLASS_TYPE toElement) { return SORTED_SET.super.subSet(fromElement, toElement); }
@Override
@Deprecated
public default SORTED_SET KEY_GENERIC_TYPE headSet(CLASS_TYPE toElement) { return SORTED_SET.super.headSet(toElement); }
@Override
@Deprecated
public default SORTED_SET KEY_GENERIC_TYPE tailSet(CLASS_TYPE fromElement) { return SORTED_SET.super.tailSet(fromElement); }
#endif
}
@@ -0,0 +1,391 @@
package speiger.src.collections.PACKAGE.sets;
import java.util.Arrays;
import java.util.Collection;
import java.util.Iterator;
import java.util.NoSuchElementException;
import speiger.src.collections.PACKAGE.collections.COLLECTION;
import speiger.src.collections.PACKAGE.collections.ITERATOR;
import speiger.src.collections.PACKAGE.lists.ARRAY_LIST;
import speiger.src.collections.PACKAGE.lists.LIST;
#if !TYPE_OBJECT
import speiger.src.collections.PACKAGE.utils.ITERATORS;
#endif
import speiger.src.collections.PACKAGE.utils.STRATEGY;
import speiger.src.collections.utils.HashUtil;
import speiger.src.collections.utils.ITrimmable;
import speiger.src.collections.utils.SanityChecks;
public class CUSTOM_HASH_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_TYPE implements ITrimmable
{
protected transient KEY_TYPE[] keys;
protected transient boolean containsNull;
protected transient int minCapacity;
protected transient int nullIndex;
protected transient int maxFill;
protected transient int mask;
protected int size;
protected final float loadFactor;
protected final STRATEGY KEY_SUPER_GENERIC_TYPE strategy;
public CUSTOM_HASH_SET(STRATEGY KEY_SUPER_GENERIC_TYPE strategy) {
this(HashUtil.DEFAULT_MIN_CAPACITY, HashUtil.DEFAULT_LOAD_FACTOR, strategy);
}
public CUSTOM_HASH_SET(int minCapacity, STRATEGY KEY_SUPER_GENERIC_TYPE strategy) {
this(minCapacity, HashUtil.DEFAULT_LOAD_FACTOR, strategy);
}
public CUSTOM_HASH_SET(int minCapacity, float loadFactor, STRATEGY KEY_SUPER_GENERIC_TYPE strategy) {
if(minCapacity < 0) throw new IllegalStateException("Minimum Capacity is negative. This is not allowed");
if(loadFactor <= 0 || loadFactor >= 1F) throw new IllegalStateException("Load Factor is not between 0 and 1");
this.loadFactor = loadFactor;
this.minCapacity = nullIndex = HashUtil.arraySize(minCapacity, loadFactor);
mask = nullIndex - 1;
maxFill = Math.min((int)Math.ceil(nullIndex * loadFactor), nullIndex - 1);
keys = NEW_KEY_ARRAY(nullIndex + 1);
this.strategy = strategy;
}
public CUSTOM_HASH_SET(KEY_TYPE[] array, STRATEGY KEY_SUPER_GENERIC_TYPE strategy) {
this(array, 0, array.length, HashUtil.DEFAULT_LOAD_FACTOR, strategy);
}
public CUSTOM_HASH_SET(KEY_TYPE[] array, float loadFactor, STRATEGY KEY_SUPER_GENERIC_TYPE strategy) {
this(array, 0, array.length, loadFactor, strategy);
}
public CUSTOM_HASH_SET(KEY_TYPE[] array, int offset, int length, STRATEGY KEY_SUPER_GENERIC_TYPE strategy) {
this(array, offset, length, HashUtil.DEFAULT_LOAD_FACTOR, strategy);
}
public CUSTOM_HASH_SET(KEY_TYPE[] array, int offset, int length, float loadFactor, STRATEGY KEY_SUPER_GENERIC_TYPE strategy) {
this(length < 0 ? 0 : length, strategy);
SanityChecks.checkArrayCapacity(array.length, offset, length);
for(int i = 0;i<length;i++) add(array[offset+i]);
}
@Deprecated
public CUSTOM_HASH_SET(Collection<? extends CLASS_TYPE> collection, STRATEGY KEY_SUPER_GENERIC_TYPE strategy) {
this(collection, HashUtil.DEFAULT_LOAD_FACTOR, strategy);
}
@Deprecated
public CUSTOM_HASH_SET(Collection<? extends CLASS_TYPE> collection, float loadFactor, STRATEGY KEY_SUPER_GENERIC_TYPE strategy) {
this(collection.size(), loadFactor, strategy);
addAll(collection);
}
public CUSTOM_HASH_SET(COLLECTION KEY_GENERIC_TYPE collection, STRATEGY KEY_SUPER_GENERIC_TYPE strategy) {
this(collection, HashUtil.DEFAULT_LOAD_FACTOR, strategy);
}
public CUSTOM_HASH_SET(COLLECTION KEY_GENERIC_TYPE collection, float loadFactor, STRATEGY KEY_SUPER_GENERIC_TYPE strategy) {
this(collection.size(), strategy);
addAll(collection);
}
public CUSTOM_HASH_SET(Iterator<CLASS_TYPE> iterator, STRATEGY KEY_SUPER_GENERIC_TYPE strategy) {
this(iterator, HashUtil.DEFAULT_LOAD_FACTOR, strategy);
}
public CUSTOM_HASH_SET(Iterator<CLASS_TYPE> iterator, float loadFactor, STRATEGY KEY_SUPER_GENERIC_TYPE strategy) {
#if !TYPE_OBJECT
this(ITERATORS.wrap(iterator), loadFactor, strategy);
#else
this(HashUtil.DEFAULT_MIN_CAPACITY, loadFactor, strategy);
while(iterator.hasNext()) add(iterator.next());
#endif
}
#if !TYPE_OBJECT
public CUSTOM_HASH_SET(ITERATOR KEY_GENERIC_TYPE iterator, STRATEGY KEY_SUPER_GENERIC_TYPE strategy) {
this(iterator, HashUtil.DEFAULT_LOAD_FACTOR, strategy);
}
public CUSTOM_HASH_SET(ITERATOR KEY_GENERIC_TYPE iterator, float loadFactor, STRATEGY KEY_SUPER_GENERIC_TYPE strategy) {
this(HashUtil.DEFAULT_MIN_CAPACITY, loadFactor, strategy);
while(iterator.hasNext()) add(iterator.NEXT());
}
#endif
public STRATEGY KEY_SUPER_GENERIC_TYPE getStrategy() {
return strategy;
}
@Override
public boolean add(KEY_TYPE o) {
if(strategy.equals(o, EMPTY_KEY_VALUE)) {
if(containsNull) return false;
containsNull = true;
onNodeAdded(nullIndex);
}
else {
int pos = HashUtil.mix(strategy.hashCode(o)) & mask;
KEY_TYPE current = keys[pos];
if(!strategy.equals(current, EMPTY_KEY_VALUE)) {
if(strategy.equals(current, o)) return false;
while(!strategy.equals((current = keys[pos = (++pos & mask)]), EMPTY_KEY_VALUE))
if(strategy.equals(current, o)) return false;
}
keys[pos] = o;
onNodeAdded(pos);
}
if(size++ >= maxFill) rehash(HashUtil.arraySize(size+1, loadFactor));
return true;
}
@Override
@Deprecated
public boolean addAll(Collection<? extends CLASS_TYPE> c) {
if(loadFactor <= 0.5F) ensureCapacity(c.size());
else ensureCapacity(c.size() + size());
return super.addAll(c);
}
@Override
public boolean addAll(COLLECTION KEY_GENERIC_TYPE c) {
if(loadFactor <= 0.5F) ensureCapacity(c.size());
else ensureCapacity(c.size() + size());
return super.addAll(c);
}
#if TYPE_OBJECT
@Override
public boolean contains(Object o) {
if(strategy.equals((KEY_TYPE)o, EMPTY_KEY_VALUE)) return containsNull;
int pos = HashUtil.mix(strategy.hashCode((KEY_TYPE)o)) & mask;
KEY_TYPE current = keys[pos];
if(strategy.equals(current, EMPTY_KEY_VALUE)) return false;
if(strategy.equals(current, (KEY_TYPE)o)) return true;
while(true) {
if(strategy.equals((current = keys[pos = (++pos & mask)]), EMPTY_KEY_VALUE)) return false;
else if(strategy.equals(current, (KEY_TYPE)o)) return true;
}
}
@Override
public boolean remove(Object o) {
if(strategy.equals((KEY_TYPE)o, EMPTY_KEY_VALUE)) return (containsNull ? removeNullIndex() : false);
int pos = HashUtil.mix(strategy.hashCode((KEY_TYPE)o)) & mask;
KEY_TYPE current = keys[pos];
if(strategy.equals(current, EMPTY_KEY_VALUE)) return false;
if(strategy.equals(current, (KEY_TYPE)o)) return removeIndex(pos);
while(true) {
if(strategy.equals((current = keys[pos = (++pos & mask)]), EMPTY_KEY_VALUE)) return false;
else if(strategy.equals(current, (KEY_TYPE)o)) return removeIndex(pos);
}
}
#else
@Override
public boolean contains(KEY_TYPE o) {
if(strategy.equals(o, EMPTY_KEY_VALUE)) return containsNull;
int pos = HashUtil.mix(strategy.hashCode(o)) & mask;
KEY_TYPE current = keys[pos];
if(strategy.equals(current, EMPTY_KEY_VALUE)) return false;
if(strategy.equals(current, o)) return true;
while(true) {
if(strategy.equals((current = keys[pos = (++pos & mask)]), EMPTY_KEY_VALUE)) return false;
else if(strategy.equals(current, o)) return true;
}
}
@Override
public boolean remove(KEY_TYPE o) {
if(strategy.equals(o, EMPTY_KEY_VALUE)) return (containsNull ? removeNullIndex() : false);
int pos = HashUtil.mix(strategy.hashCode(o)) & mask;
KEY_TYPE current = keys[pos];
if(strategy.equals(current, EMPTY_KEY_VALUE)) return false;
if(strategy.equals(current, o)) return removeIndex(pos);
while(true) {
if(strategy.equals((current = keys[pos = (++pos & mask)]), EMPTY_KEY_VALUE)) return false;
else if(strategy.equals(current, o)) return removeIndex(pos);
}
}
#endif
@Override
public boolean trim(int size) {
int newSize = HashUtil.nextPowerOfTwo((int)Math.ceil(size / loadFactor));
if(newSize >= nullIndex || size >= Math.min((int)Math.ceil(newSize * loadFactor), newSize - 1)) return false;
try {
rehash(newSize);
}
catch(OutOfMemoryError e) { return false; }
return true;
}
private void ensureCapacity(int newCapacity) {
int size = HashUtil.arraySize(newCapacity, loadFactor);
if(size > nullIndex) rehash(size);
}
protected boolean removeIndex(int pos) {
size--;
onNodeRemoved(pos);
shiftKeys(pos);
if(nullIndex > minCapacity && size < maxFill / 4 && nullIndex > HashUtil.DEFAULT_MIN_CAPACITY) rehash(nullIndex / 2);
return true;
}
protected boolean removeNullIndex() {
containsNull = false;
keys[nullIndex] = EMPTY_KEY_VALUE;
size--;
onNodeRemoved(nullIndex);
if(nullIndex > minCapacity && size < maxFill / 4 && nullIndex > HashUtil.DEFAULT_MIN_CAPACITY) rehash(nullIndex / 2);
return true;
}
protected void onNodeAdded(int pos) {
}
protected void onNodeRemoved(int pos) {
}
protected void onNodeMoved(int from, int to) {
}
protected void shiftKeys(int startPos) {
int slot, last;
KEY_TYPE current;
while(true) {
startPos = ((last = startPos) + 1) & mask;
while(true){
if(strategy.equals((current = keys[startPos]), EMPTY_KEY_VALUE)) {
keys[last] = EMPTY_KEY_VALUE;
return;
}
slot = HashUtil.mix(strategy.hashCode(current)) & mask;
if(last <= startPos ? (last >= slot || slot > startPos) : (last >= slot && slot > startPos)) break;
startPos = ++startPos & mask;
}
keys[last] = current;
onNodeMoved(startPos, last);
}
}
protected void rehash(int newSize) {
int newMask = newSize - 1;
KEY_TYPE[] newKeys = NEW_KEY_ARRAY(newSize + 1);
for(int i = nullIndex, pos = 0, j = (size - (containsNull ? 1 : 0));j-- != 0;) {
while(strategy.equals(keys[--i], EMPTY_KEY_VALUE));
if(!strategy.equals(newKeys[pos = HashUtil.mix(KEY_TO_HASH(keys[i])) & newMask], EMPTY_KEY_VALUE))
while(!strategy.equals(newKeys[pos = (++pos & newMask)], EMPTY_KEY_VALUE));
newKeys[pos] = keys[i];
}
nullIndex = newSize;
mask = newMask;
maxFill = Math.min((int)Math.ceil(nullIndex * loadFactor), nullIndex - 1);
keys = newKeys;
}
@Override
public ITERATOR KEY_GENERIC_TYPE iterator() {
return new SetIterator();
}
@Override
public void clear() {
if(size == 0) return;
size = 0;
containsNull = false;
Arrays.fill(keys, EMPTY_KEY_VALUE);
}
@Override
public int size() {
return size;
}
private class SetIterator implements ITERATOR KEY_GENERIC_TYPE {
int pos = nullIndex;
int lastReturned = -1;
int nextIndex = Integer.MIN_VALUE;
boolean returnNull = containsNull;
LIST KEY_GENERIC_TYPE wrapped = null;
@Override
public boolean hasNext() {
if(nextIndex == Integer.MIN_VALUE) {
if(returnNull) {
returnNull = false;
nextIndex = nullIndex;
}
else {
while(true) {
if(--pos < 0) {
if(wrapped == null || wrapped.size() <= -pos - 1) break;
nextIndex = -pos - 1;
break;
}
if(KEY_EQUALS_NOT_NULL(keys[pos])){
nextIndex = pos;
break;
}
}
}
}
return nextIndex != Integer.MIN_VALUE;
}
@Override
public KEY_TYPE NEXT() {
if(!hasNext()) throw new NoSuchElementException();
if(nextIndex < 0){
lastReturned = Integer.MAX_VALUE;
KEY_TYPE value = wrapped.GET_KEY(nextIndex);
nextIndex = Integer.MIN_VALUE;
return value;
}
KEY_TYPE value = keys[(lastReturned = nextIndex)];
nextIndex = Integer.MIN_VALUE;
return value;
}
@Override
public void remove() {
if(lastReturned == -1) throw new IllegalStateException();
if(lastReturned == nullIndex) {
containsNull = false;
keys[nullIndex] = EMPTY_KEY_VALUE;
}
else if(pos >= 0) shiftKeys(pos);
else {
CUSTOM_HASH_SET.this.remove(wrapped.GET_KEY(-pos - 1));
return;
}
size--;
lastReturned = -1;
}
private void shiftKeys(int startPos) {
int slot, last;
KEY_TYPE current;
while(true) {
startPos = ((last = startPos) + 1) & mask;
while(true){
if(strategy.equals((current = keys[startPos]), EMPTY_KEY_VALUE)) {
keys[last] = EMPTY_KEY_VALUE;
return;
}
slot = HashUtil.mix(strategy.hashCode(current)) & mask;
if(last <= startPos ? (last >= slot || slot > startPos) : (last >= slot && slot > startPos)) break;
startPos = ++startPos & mask;
}
if(startPos < last) {
if(wrapped == null) wrapped = new ARRAY_LISTBRACES(2);
wrapped.add(keys[startPos]);
}
keys[last] = current;
}
}
}
}
@@ -0,0 +1,384 @@
package speiger.src.collections.PACKAGE.sets;
import java.util.Arrays;
import java.util.Collection;
import java.util.Iterator;
import java.util.NoSuchElementException;
import java.util.Objects;
import speiger.src.collections.PACKAGE.collections.COLLECTION;
import speiger.src.collections.PACKAGE.collections.ITERATOR;
import speiger.src.collections.PACKAGE.lists.ARRAY_LIST;
import speiger.src.collections.PACKAGE.lists.LIST;
#if !TYPE_OBJECT
import speiger.src.collections.PACKAGE.utils.ITERATORS;
#endif
import speiger.src.collections.utils.HashUtil;
import speiger.src.collections.utils.ITrimmable;
import speiger.src.collections.utils.SanityChecks;
public class HASH_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_TYPE implements ITrimmable
{
protected transient KEY_TYPE[] keys;
protected transient boolean containsNull;
protected transient int minCapacity;
protected transient int nullIndex;
protected transient int maxFill;
protected transient int mask;
protected int size;
protected final float loadFactor;
public HASH_SET() {
this(HashUtil.DEFAULT_MIN_CAPACITY, HashUtil.DEFAULT_LOAD_FACTOR);
}
public HASH_SET(int minCapacity) {
this(minCapacity, HashUtil.DEFAULT_LOAD_FACTOR);
}
public HASH_SET(int minCapacity, float loadFactor) {
if(minCapacity < 0) throw new IllegalStateException("Minimum Capacity is negative. This is not allowed");
if(loadFactor <= 0 || loadFactor >= 1F) throw new IllegalStateException("Load Factor is not between 0 and 1");
this.loadFactor = loadFactor;
this.minCapacity = nullIndex = HashUtil.arraySize(minCapacity, loadFactor);
mask = nullIndex - 1;
maxFill = Math.min((int)Math.ceil(nullIndex * loadFactor), nullIndex - 1);
keys = NEW_KEY_ARRAY(nullIndex + 1);
}
public HASH_SET(KEY_TYPE[] array) {
this(array, 0, array.length, HashUtil.DEFAULT_LOAD_FACTOR);
}
public HASH_SET(KEY_TYPE[] array, float loadFactor) {
this(array, 0, array.length, loadFactor);
}
public HASH_SET(KEY_TYPE[] array, int offset, int length) {
this(array, offset, length, HashUtil.DEFAULT_LOAD_FACTOR);
}
public HASH_SET(KEY_TYPE[] array, int offset, int length, float loadFactor) {
this(length < 0 ? 0 : length);
SanityChecks.checkArrayCapacity(array.length, offset, length);
for(int i = 0;i<length;i++) add(array[offset+i]);
}
@Deprecated
public HASH_SET(Collection<? extends CLASS_TYPE> collection) {
this(collection, HashUtil.DEFAULT_LOAD_FACTOR);
}
@Deprecated
public HASH_SET(Collection<? extends CLASS_TYPE> collection, float loadFactor) {
this(collection.size(), loadFactor);
addAll(collection);
}
public HASH_SET(COLLECTION KEY_GENERIC_TYPE collection) {
this(collection, HashUtil.DEFAULT_LOAD_FACTOR);
}
public HASH_SET(COLLECTION KEY_GENERIC_TYPE collection, float loadFactor) {
this(collection.size());
addAll(collection);
}
public HASH_SET(Iterator<CLASS_TYPE> iterator) {
this(iterator, HashUtil.DEFAULT_LOAD_FACTOR);
}
public HASH_SET(Iterator<CLASS_TYPE> iterator, float loadFactor) {
#if !TYPE_OBJECT
this(ITERATORS.wrap(iterator), loadFactor);
#else
this(HashUtil.DEFAULT_MIN_CAPACITY, loadFactor);
while(iterator.hasNext()) add(iterator.next());
#endif
}
#if !TYPE_OBJECT
public HASH_SET(ITERATOR KEY_GENERIC_TYPE iterator) {
this(iterator, HashUtil.DEFAULT_LOAD_FACTOR);
}
public HASH_SET(ITERATOR KEY_GENERIC_TYPE iterator, float loadFactor) {
this(HashUtil.DEFAULT_MIN_CAPACITY, loadFactor);
while(iterator.hasNext()) add(iterator.NEXT());
}
#endif
@Override
public boolean add(KEY_TYPE o) {
if(KEY_EQUALS_NULL(o)) {
if(containsNull) return false;
containsNull = true;
onNodeAdded(nullIndex);
}
else {
int pos = HashUtil.mix(KEY_TO_HASH(o)) & mask;
KEY_TYPE current = keys[pos];
if(KEY_EQUALS_NOT_NULL(current)) {
if(KEY_EQUALS(current, o)) return false;
while(KEY_EQUALS_NOT_NULL((current = keys[pos = (++pos & mask)])))
if(KEY_EQUALS(current, o)) return false;
}
keys[pos] = o;
onNodeAdded(pos);
}
if(size++ >= maxFill) rehash(HashUtil.arraySize(size+1, loadFactor));
return true;
}
@Override
@Deprecated
public boolean addAll(Collection<? extends CLASS_TYPE> c) {
if(loadFactor <= 0.5F) ensureCapacity(c.size());
else ensureCapacity(c.size() + size());
return super.addAll(c);
}
@Override
public boolean addAll(COLLECTION KEY_GENERIC_TYPE c) {
if(loadFactor <= 0.5F) ensureCapacity(c.size());
else ensureCapacity(c.size() + size());
return super.addAll(c);
}
@Override
public boolean contains(Object o) {
if(o == null) return containsNull;
int pos = HashUtil.mix(o.hashCode()) & mask;
KEY_TYPE current = keys[pos];
if(KEY_EQUALS_NULL(current)) return false;
if(EQUALS_KEY_TYPE(current, o)) return true;
while(true) {
if(KEY_EQUALS_NULL((current = keys[pos = (++pos & mask)]))) return false;
else if(EQUALS_KEY_TYPE(current, o)) return true;
}
}
@Override
public boolean remove(Object o) {
if(o == null) return (containsNull ? removeNullIndex() : false);
int pos = HashUtil.mix(o.hashCode()) & mask;
KEY_TYPE current = keys[pos];
if(KEY_EQUALS_NULL(current)) return false;
if(EQUALS_KEY_TYPE(current, o)) return removeIndex(pos);
while(true) {
if(KEY_EQUALS_NULL((current = keys[pos = (++pos & mask)]))) return false;
else if(EQUALS_KEY_TYPE(current, o)) return removeIndex(pos);
}
}
#if !TYPE_OBJECT
@Override
public boolean contains(KEY_TYPE o) {
if(KEY_EQUALS_NULL(o)) return containsNull;
int pos = HashUtil.mix(KEY_TO_HASH(o)) & mask;
KEY_TYPE current = keys[pos];
if(KEY_EQUALS_NULL(current)) return false;
if(KEY_EQUALS(current, o)) return true;
while(true) {
if(KEY_EQUALS_NULL((current = keys[pos = (++pos & mask)]))) return false;
else if(KEY_EQUALS(current, o)) return true;
}
}
@Override
public boolean remove(KEY_TYPE o) {
if(KEY_EQUALS_NULL(o)) return (containsNull ? removeNullIndex() : false);
int pos = HashUtil.mix(KEY_TO_HASH(o)) & mask;
KEY_TYPE current = keys[pos];
if(KEY_EQUALS_NULL(current)) return false;
if(KEY_EQUALS(current, o)) return removeIndex(pos);
while(true) {
if(KEY_EQUALS_NULL((current = keys[pos = (++pos & mask)]))) return false;
else if(KEY_EQUALS(current, o)) return removeIndex(pos);
}
}
#endif
@Override
public boolean trim(int size) {
int newSize = HashUtil.nextPowerOfTwo((int)Math.ceil(size / loadFactor));
if(newSize >= nullIndex || size >= Math.min((int)Math.ceil(newSize * loadFactor), newSize - 1)) return false;
try {
rehash(newSize);
}
catch(OutOfMemoryError e) { return false; }
return true;
}
private void ensureCapacity(int newCapacity) {
int size = HashUtil.arraySize(newCapacity, loadFactor);
if(size > nullIndex) rehash(size);
}
protected boolean removeIndex(int pos) {
size--;
onNodeRemoved(pos);
shiftKeys(pos);
if(nullIndex > minCapacity && size < maxFill / 4 && nullIndex > HashUtil.DEFAULT_MIN_CAPACITY) rehash(nullIndex / 2);
return true;
}
protected boolean removeNullIndex() {
containsNull = false;
keys[nullIndex] = EMPTY_KEY_VALUE;
size--;
onNodeRemoved(nullIndex);
if(nullIndex > minCapacity && size < maxFill / 4 && nullIndex > HashUtil.DEFAULT_MIN_CAPACITY) rehash(nullIndex / 2);
return true;
}
protected void onNodeAdded(int pos) {
}
protected void onNodeRemoved(int pos) {
}
protected void onNodeMoved(int from, int to) {
}
protected void shiftKeys(int startPos) {
int slot, last;
KEY_TYPE current;
while(true) {
startPos = ((last = startPos) + 1) & mask;
while(true){
if(KEY_EQUALS_NULL((current = keys[startPos]))) {
keys[last] = EMPTY_KEY_VALUE;
return;
}
slot = HashUtil.mix(KEY_TO_HASH(current)) & mask;
if(last <= startPos ? (last >= slot || slot > startPos) : (last >= slot && slot > startPos)) break;
startPos = ++startPos & mask;
}
keys[last] = current;
onNodeMoved(startPos, last);
}
}
protected void rehash(int newSize) {
int newMask = newSize - 1;
KEY_TYPE[] newKeys = NEW_KEY_ARRAY(newSize + 1);
for(int i = nullIndex, pos = 0, j = (size - (containsNull ? 1 : 0));j-- != 0;) {
while(KEY_EQUALS_NULL(keys[--i]));
if(KEY_EQUALS_NOT_NULL(newKeys[pos = HashUtil.mix(KEY_TO_HASH(keys[i])) & newMask]))
while(KEY_EQUALS_NOT_NULL(newKeys[pos = (++pos & newMask)]));
newKeys[pos] = keys[i];
}
nullIndex = newSize;
mask = newMask;
maxFill = Math.min((int)Math.ceil(nullIndex * loadFactor), nullIndex - 1);
keys = newKeys;
}
@Override
public ITERATOR KEY_GENERIC_TYPE iterator() {
return new SetIterator();
}
@Override
public void clear() {
if(size == 0) return;
size = 0;
containsNull = false;
Arrays.fill(keys, EMPTY_KEY_VALUE);
}
@Override
public int size() {
return size;
}
private class SetIterator implements ITERATOR KEY_GENERIC_TYPE {
int pos = nullIndex;
int lastReturned = -1;
int nextIndex = Integer.MIN_VALUE;
boolean returnNull = containsNull;
LIST KEY_GENERIC_TYPE wrapped = null;
@Override
public boolean hasNext() {
if(nextIndex == Integer.MIN_VALUE) {
if(returnNull) {
returnNull = false;
nextIndex = nullIndex;
}
else
{
while(true) {
if(--pos < 0) {
if(wrapped == null || wrapped.size() <= -pos - 1) break;
nextIndex = -pos - 1;
break;
}
if(KEY_EQUALS_NOT_NULL(keys[pos])){
nextIndex = pos;
break;
}
}
}
}
return nextIndex != Integer.MIN_VALUE;
}
@Override
public KEY_TYPE NEXT() {
if(!hasNext()) throw new NoSuchElementException();
if(nextIndex < 0){
lastReturned = Integer.MAX_VALUE;
KEY_TYPE value = wrapped.GET_KEY(nextIndex);
nextIndex = Integer.MIN_VALUE;
return value;
}
KEY_TYPE value = keys[(lastReturned = nextIndex)];
nextIndex = Integer.MIN_VALUE;
return value;
}
@Override
public void remove() {
if(lastReturned == -1) throw new IllegalStateException();
if(lastReturned == nullIndex) {
containsNull = false;
keys[nullIndex] = EMPTY_KEY_VALUE;
}
else if(pos >= 0) shiftKeys(pos);
else {
HASH_SET.this.remove(wrapped.GET_KEY(-pos - 1));
return;
}
size--;
lastReturned = -1;
}
private void shiftKeys(int startPos) {
int slot, last;
KEY_TYPE current;
while(true) {
startPos = ((last = startPos) + 1) & mask;
while(true){
if(KEY_EQUALS_NULL((current = keys[startPos]))) {
keys[last] = EMPTY_KEY_VALUE;
return;
}
slot = HashUtil.mix(KEY_TO_HASH(current)) & mask;
if(last <= startPos ? (last >= slot || slot > startPos) : (last >= slot && slot > startPos)) break;
startPos = ++startPos & mask;
}
if(startPos < last) {
if(wrapped == null) wrapped = new ARRAY_LISTBRACES(2);
wrapped.add(keys[startPos]);
}
keys[last] = current;
}
}
}
}
@@ -0,0 +1,39 @@
package speiger.src.collections.PACKAGE.sets;
import java.util.Set;
import speiger.src.collections.PACKAGE.collections.COLLECTION;
import speiger.src.collections.PACKAGE.collections.ITERATOR;
public interface SET KEY_GENERIC_TYPE extends Set<CLASS_TYPE>, COLLECTION KEY_GENERIC_TYPE
{
@Override
public ITERATOR KEY_GENERIC_TYPE iterator();
#if !TYPE_OBJECT
public boolean remove(KEY_TYPE o);
@Override
public default boolean REMOVE_KEY(KEY_TYPE o) {
return remove(o);
}
@Override
@Primitive
public default boolean add(CLASS_TYPE e) {
return COLLECTION.super.add(e);
}
@Override
@Primitive
public default boolean contains(Object o) {
return COLLECTION.super.contains(o);
}
@Override
@Primitive
public default boolean remove(Object o) {
return COLLECTION.super.remove(o);
}
#endif
}
@@ -0,0 +1,64 @@
package speiger.src.collections.PACKAGE.sets;
import java.util.SortedSet;
import speiger.src.collections.PACKAGE.collections.BI_ITERATOR;
#if TYPE_OBJECT
import java.util.Comparator;
#else
import speiger.src.collections.PACKAGE.functions.COMPARATOR;
#endif
public interface SORTED_SET KEY_GENERIC_TYPE extends SET KEY_GENERIC_TYPE, SortedSet<CLASS_TYPE>
{
public boolean addAndMoveToFirst(KEY_TYPE o);
public boolean addAndMoveToLast(KEY_TYPE o);
public boolean moveToFirst(KEY_TYPE o);
public boolean moveToLast(KEY_TYPE o);
@Override
public COMPARATOR KEY_GENERIC_TYPE comparator();
@Override
public BI_ITERATOR KEY_GENERIC_TYPE iterator();
public BI_ITERATOR KEY_GENERIC_TYPE iterator(KEY_TYPE fromElement);
#if !TYPE_OBJECT
public SORTED_SET KEY_GENERIC_TYPE subSet(KEY_TYPE fromElement, KEY_TYPE toElement);
public SORTED_SET KEY_GENERIC_TYPE headSet(KEY_TYPE toElement);
public SORTED_SET KEY_GENERIC_TYPE tailSet(KEY_TYPE fromElement);
public KEY_TYPE FIRST_KEY();
public KEY_TYPE POLL_FIRST_KEY();
public KEY_TYPE LAST_KEY();
public KEY_TYPE POLL_LAST_KEY();
@Override
@Deprecated
public default SORTED_SET KEY_GENERIC_TYPE subSet(CLASS_TYPE fromElement, CLASS_TYPE toElement) { return subSet(OBJ_TO_KEY(fromElement), OBJ_TO_KEY(toElement)); }
@Override
@Deprecated
public default SORTED_SET KEY_GENERIC_TYPE headSet(CLASS_TYPE toElement) { return headSet(OBJ_TO_KEY(toElement)); }
@Override
@Deprecated
public default SORTED_SET KEY_GENERIC_TYPE tailSet(CLASS_TYPE fromElement) { return tailSet(OBJ_TO_KEY(fromElement)); }
@Override
@Deprecated
public default CLASS_TYPE first() { return KEY_TO_OBJ(FIRST_KEY()); }
@Override
@Deprecated
default CLASS_TYPE last() { return KEY_TO_OBJ(LAST_KEY()); }
#else
public CLASS_TYPE pollFirst();
public CLASS_TYPE pollLast();
@Override
public SORTED_SET KEY_GENERIC_TYPE subSet(CLASS_TYPE fromElement, CLASS_TYPE toElement);
@Override
public SORTED_SET KEY_GENERIC_TYPE headSet(CLASS_TYPE toElement);
@Override
public SORTED_SET KEY_GENERIC_TYPE tailSet(CLASS_TYPE fromElement);
#endif
}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,404 @@
package speiger.src.collections.PACKAGE.utils;
import java.util.Collection;
import java.util.function.Predicate;
#if PRIMITIVES
import java.util.function.JAVA_PREDICATE;
#endif
import speiger.src.collections.PACKAGE.collections.ABSTRACT_COLLECTION;
import speiger.src.collections.PACKAGE.collections.COLLECTION;
import speiger.src.collections.PACKAGE.collections.ITERATOR;
import speiger.src.collections.objects.utils.ObjectArrays;
#if !TYPE_OBJECT
import speiger.src.collections.PACKAGE.utils.ARRAYS;
#endif
/**
* A Helper class for Collections
*/
public class COLLECTIONS
{
public static final COLLECTION NO_GENERIC_TYPE EMPTY = new EmptyCollectionBRACES();
/**
* Returns a Immutable EmptyCollection instance that is automatically casted.
* @return an empty collection
*/
public static GENERIC_KEY_BRACES COLLECTION KEY_GENERIC_TYPE emptyCollection() {
#if TYPE_OBJECT
return (COLLECTION<KEY_TYPE>)EMPTY;
#else
return EMPTY;
#endif
}
/**
* Returns a Immutable Collection instance based on the instance given.
* @param l that should be made immutable/unmodifyable
* @return a unmodifiable collection wrapper. If the Collection already a unmodifyable wrapper then it just returns itself.
*/
public static GENERIC_KEY_BRACES COLLECTION KEY_GENERIC_TYPE unmodifiableCollection(COLLECTION KEY_GENERIC_TYPE c) {
return c instanceof UnmodifiableCollection ? c : new UnmodifiableCollectionBRACES(c);
}
/**
* Returns a synchronized Collection instance based on the instance given.
* @param l that should be synchronized
* @return a synchronized collection wrapper. If the Collection already a synchronized wrapper then it just returns itself.
*/
public static GENERIC_KEY_BRACES COLLECTION KEY_GENERIC_TYPE synchronizedCollection(COLLECTION KEY_GENERIC_TYPE c) {
return c instanceof SynchronizedCollection ? c : new SynchronizedCollectionBRACES(c);
}
/**
* Returns a synchronized Collection instance based on the instance given.
* @param l that should be synchronized
* @param mutex is the controller of the synchronization block.
* @return a synchronized collection wrapper. If the Collection already a synchronized wrapper then it just returns itself.
*/
public static GENERIC_KEY_BRACES COLLECTION KEY_GENERIC_TYPE synchronizedCollection(COLLECTION KEY_GENERIC_TYPE c, Object mutex) {
return c instanceof SynchronizedCollection ? c : new SynchronizedCollectionBRACES(c, mutex);
}
public static class SynchronizedCollection KEY_GENERIC_TYPE implements COLLECTION KEY_GENERIC_TYPE {
COLLECTION KEY_GENERIC_TYPE c;
protected Object mutex;
SynchronizedCollection(COLLECTION KEY_GENERIC_TYPE c) {
this.c = c;
mutex = this;
}
SynchronizedCollection(COLLECTION KEY_GENERIC_TYPE c, Object mutex) {
this.c = c;
this.mutex = mutex;
}
@Override
public boolean add(KEY_TYPE o) { synchronized(mutex) { return c.add(o); } }
@Override
public boolean addAll(Collection<? extends CLASS_TYPE> c) { synchronized(mutex) { return this.c.addAll(c); } }
@Override
public boolean addAll(COLLECTION KEY_GENERIC_TYPE c) { synchronized(mutex) { return this.c.addAll(c); } }
#if !TYPE_OBJECT
@Override
public boolean contains(KEY_TYPE o) { synchronized(mutex) { return c.contains(o); } }
#else
@Override
public boolean contains(Object o) { synchronized(mutex) { return c.contains(o); } }
#endif
@Override
@Primitive
public boolean containsAll(Collection<?> c) { synchronized(mutex) { return this.c.containsAll(c); } }
@Override
@Primitive
public boolean containsAny(Collection<?> c) { synchronized(mutex) { return this.c.containsAny(c); } }
@Override
public boolean containsAll(COLLECTION KEY_GENERIC_TYPE c) { synchronized(mutex) { return this.c.containsAll(c); } }
@Override
public boolean containsAny(COLLECTION KEY_GENERIC_TYPE c) { synchronized(mutex) { return this.c.containsAny(c); } }
@Override
public int size() { synchronized(mutex) { return c.size(); } }
@Override
public boolean isEmpty() { synchronized(mutex) { return c.isEmpty(); } }
@Override
public ITERATOR KEY_GENERIC_TYPE iterator() {
return c.iterator();
}
@Override
@Primitive
public boolean remove(Object o) { synchronized(mutex) { return c.remove(o); } }
@Override
@Primitive
public boolean removeAll(Collection<?> c) { synchronized(mutex) { return this.c.removeAll(c); } }
@Override
@Primitive
public boolean retainAll(Collection<?> c) { synchronized(mutex) { return this.c.retainAll(c); } }
#if !TYPE_OBJECT
@Override
public boolean REMOVE_KEY(KEY_TYPE o) { synchronized(mutex) { return c.REMOVE_KEY(o); } }
#endif
@Override
public boolean removeAll(COLLECTION KEY_GENERIC_TYPE c) { synchronized(mutex) { return this.c.removeAll(c); } }
@Override
public boolean retainAll(COLLECTION KEY_GENERIC_TYPE c) { synchronized(mutex) { return this.c.retainAll(c); } }
#if PRIMITIVES
@Override
public boolean remIf(JAVA_PREDICATE filter){ synchronized(mutex) { return c.remIf(filter); } }
#endif
@Override
public void clear() { synchronized(mutex) { c.clear(); } }
@Override
public Object[] toArray() { synchronized(mutex) { return c.toArray(); } }
#if !TYPE_OBJECT
@Override
public <T> T[] toArray(T[] a) { synchronized(mutex) { return c.toArray(a); } }
@Override
public KEY_TYPE[] TO_ARRAY() { synchronized(mutex) { return c.TO_ARRAY(); } }
@Override
public KEY_TYPE[] TO_ARRAY(KEY_TYPE[] a) { synchronized(mutex) { return c.TO_ARRAY(a); } }
#else
@Override
public <E> E[] toArray(E[] a) { synchronized(mutex) { return c.toArray(a); } }
#endif
}
public static class UnmodifiableCollection KEY_GENERIC_TYPE implements COLLECTION KEY_GENERIC_TYPE {
COLLECTION KEY_GENERIC_TYPE c;
UnmodifiableCollection(COLLECTION KEY_GENERIC_TYPE c) {
this.c = c;
}
@Override
public boolean add(KEY_TYPE o) { throw new UnsupportedOperationException(); }
@Override
public boolean addAll(Collection<? extends CLASS_TYPE> c) { throw new UnsupportedOperationException(); }
@Override
public boolean addAll(COLLECTION KEY_GENERIC_TYPE c) { throw new UnsupportedOperationException(); }
#if !TYPE_OBJECT
@Override
public boolean contains(KEY_TYPE o) {
return c.contains(o);
}
#else
@Override
public boolean contains(Object o) {
return c.contains(o);
}
#endif
@Override
public boolean containsAll(COLLECTION KEY_GENERIC_TYPE c) {
return this.c.containsAll(c);
}
@Override
public boolean containsAny(COLLECTION KEY_GENERIC_TYPE c) {
return this.c.containsAny(c);
}
@Override
@Primitive
public boolean containsAny(Collection<?> c) {
return this.c.containsAny(c);
}
@Override
@Primitive
public boolean containsAll(Collection<?> c) {
return this.c.containsAll(c);
}
@Override
public int size() {
return c.size();
}
@Override
public boolean isEmpty() {
return c.isEmpty();
}
@Override
public ITERATOR KEY_GENERIC_TYPE iterator() {
return ITERATORS.unmodifiable(c.iterator());
}
@Override
@Deprecated
public boolean remove(Object o) { throw new UnsupportedOperationException(); }
@Override
@Primitive
public boolean removeAll(Collection<?> c) { throw new UnsupportedOperationException(); }
@Override
@Primitive
public boolean retainAll(Collection<?> c) { throw new UnsupportedOperationException(); }
@Override
@Primitive
public boolean removeIf(Predicate<? super CLASS_TYPE> filter) { throw new UnsupportedOperationException(); }
#if !TYPE_OBJECT
@Override
public boolean REMOVE_KEY(KEY_TYPE o) { throw new UnsupportedOperationException(); }
#endif
@Override
public boolean removeAll(COLLECTION KEY_GENERIC_TYPE c) { throw new UnsupportedOperationException(); }
@Override
public boolean retainAll(COLLECTION KEY_GENERIC_TYPE c) { throw new UnsupportedOperationException(); }
#if PRIMITIVES
@Override
public boolean remIf(JAVA_PREDICATE filter){ throw new UnsupportedOperationException(); }
#endif
@Override
public void clear() { throw new UnsupportedOperationException(); }
@Override
public Object[] toArray() {
return c.toArray();
}
#if !TYPE_OBJECT
@Override
public <T> T[] toArray(T[] a) {
return c.toArray(a);
}
@Override
public KEY_TYPE[] TO_ARRAY() {
return c.TO_ARRAY();
}
@Override
public KEY_TYPE[] TO_ARRAY(KEY_TYPE[] a) {
return c.TO_ARRAY(a);
}
#else
@Override
public <E> E[] toArray(E[] a) {
return c.toArray(a);
}
#endif
}
public static class EmptyCollection KEY_GENERIC_TYPE extends ABSTRACT_COLLECTION KEY_GENERIC_TYPE {
@Override
public boolean add(KEY_TYPE o) { throw new UnsupportedOperationException(); }
@Override
public boolean addAll(COLLECTION KEY_GENERIC_TYPE c) { throw new UnsupportedOperationException(); }
#if !TYPE_OBJECT
@Override
public boolean contains(KEY_TYPE o) {
return false;
}
@Override
public boolean containsAll(COLLECTION KEY_GENERIC_TYPE c) {
return false;
}
@Override
public boolean containsAny(COLLECTION KEY_GENERIC_TYPE c) {
return false;
}
#else
@Override
public boolean contains(Object o) {
return false;
}
#endif
@Override
@Primitive
public boolean containsAny(Collection<?> c) {
return false;
}
@Override
@Primitive
public boolean containsAll(Collection<?> c) {
return false;
}
@Override
public int hashCode() {
return 0;
}
@Override
public boolean equals(Object o) {
if(o == this) return true;
if(!(o instanceof Collection)) return false;
return ((Collection<?>)o).isEmpty();
}
@Override
@Deprecated
public boolean remove(Object o) { throw new UnsupportedOperationException(); }
@Override
@Primitive
public boolean removeAll(Collection<?> c) { throw new UnsupportedOperationException(); }
@Override
@Primitive
public boolean retainAll(Collection<?> c) { throw new UnsupportedOperationException(); }
@Override
@Primitive
public boolean removeIf(Predicate<? super CLASS_TYPE> filter) { throw new UnsupportedOperationException(); }
#if !TYPE_OBJECT
@Override
public boolean REMOVE_KEY(KEY_TYPE o) { throw new UnsupportedOperationException(); }
#endif
@Override
public boolean removeAll(COLLECTION KEY_GENERIC_TYPE c) { throw new UnsupportedOperationException(); }
@Override
public boolean retainAll(COLLECTION KEY_GENERIC_TYPE c) { throw new UnsupportedOperationException(); }
#if PRIMITIVES
@Override
public boolean remIf(JAVA_PREDICATE filter){ throw new UnsupportedOperationException(); }
#endif
@Override
public Object[] toArray() {
return ObjectArrays.EMPTY_ARRAY;
}
#if !TYPE_OBJECT
@Override
public <T> T[] toArray(T[] a) {
return a;
}
@Override
public KEY_TYPE[] TO_ARRAY() {
return ARRAYS.EMPTY_ARRAY;
}
@Override
public KEY_TYPE[] TO_ARRAY(KEY_TYPE[] a) {
return a;
}
#else
@Override
public <E> E[] toArray(E[] a) {
return a;
}
#endif
@Override
public ITERATOR KEY_GENERIC_TYPE iterator() {
return ITERATORS.emptyIterator();
}
@Override
public void clear() {
}
@Override
public int size() {
return 0;
}
}
}
@@ -0,0 +1,31 @@
package speiger.src.collections.PACKAGE.utils;
import java.util.Objects;
import java.util.function.Consumer;
import speiger.src.collections.utils.IArray;
/**
* Type-Specific Helper class to get the underlying array of array implementations.
* @see speiger.src.collections.PACKAGE.lists.ARRAY_LIST
*/
public interface IARRAY KEY_GENERIC_TYPE extends IArray
{
/**
* Provides the Underlying Array in the Implementation
* @return underlying Array
* @throws ClassCastException if the return type does not match the underlying array. (Only for Object Implementations)
*/
public KEY_TYPE[] elements();
/**
* Provides the Underlying Array in the Implementation. This function exists purely because of Synchronization wrappers to help run Synchronized Code
* @param action the action that handles the array
* @throws NullPointerException if action is null
* @throws ClassCastException if the return type does not match the underlying array. (Only for Object Implementations)
*/
public default void elements(Consumer<KEY_TYPE[]> action) {
Objects.requireNonNull(action);
action.accept(elements());
}
}
@@ -0,0 +1,428 @@
package speiger.src.collections.PACKAGE.utils;
import java.util.Iterator;
import speiger.src.collections.PACKAGE.collections.ITERATOR;
import speiger.src.collections.PACKAGE.lists.LIST_ITERATOR;
import speiger.src.collections.PACKAGE.collections.BI_ITERATOR;
/**
* A Helper class for Iterators
*/
public class ITERATORS
{
public static final EmptyIterator NO_GENERIC_TYPE EMPTY = new EmptyIteratorBRACES();
/**
* Returns a Immutable EmptyIterator instance that is automatically casted.
* @return an empty iterator
*/
public static GENERIC_KEY_BRACES EmptyIterator KEY_GENERIC_TYPE emptyIterator() {
#if TYPE_OBJECT
return (EmptyIterator<KEY_TYPE>)EMPTY;
#else
return EMPTY;
#endif
}
public static GENERIC_KEY_BRACES BI_ITERATOR KEY_GENERIC_TYPE invert(BI_ITERATOR KEY_GENERIC_TYPE it) {
return new BI_ITERATOR KEY_GENERIC_TYPE() {
@Override
public KEY_TYPE NEXT() { return it.PREVIOUS(); }
@Override
public boolean hasNext() { return it.hasPrevious(); }
@Override
public boolean hasPrevious() { return it.hasNext(); }
@Override
public KEY_TYPE PREVIOUS() { return it.NEXT(); }
@Override
public void remove() { it.remove(); }
};
}
public static GENERIC_KEY_BRACES LIST_ITERATOR KEY_GENERIC_TYPE invert(LIST_ITERATOR KEY_GENERIC_TYPE it) {
return new LIST_ITERATOR KEY_GENERIC_TYPE() {
@Override
public KEY_TYPE NEXT() { return it.PREVIOUS(); }
@Override
public boolean hasNext() { return it.hasPrevious(); }
@Override
public boolean hasPrevious() { return it.hasNext(); }
@Override
public KEY_TYPE PREVIOUS() { return it.NEXT(); }
@Override
public void remove() { it.remove(); }
@Override
public int nextIndex() { return it.previousIndex(); }
@Override
public int previousIndex() { return it.nextIndex(); }
@Override
public void set(KEY_TYPE e) { it.set(e); }
@Override
public void add(KEY_TYPE e) { it.add(e); }
};
}
/**
* Returns a Immutable Iterator instance based on the instance given.
* @param l that should be made immutable/unmodifyable
* @return a unmodifiable iterator wrapper. If the Iterator already a unmodifyable wrapper then it just returns itself.
*/
public static GENERIC_KEY_BRACES ITERATOR KEY_GENERIC_TYPE unmodifiable(ITERATOR KEY_GENERIC_TYPE iterator) {
return iterator instanceof UnmodifiableIterator ? iterator : new UnmodifiableIteratorBRACES(iterator);
}
public static GENERIC_KEY_BRACES BI_ITERATOR KEY_GENERIC_TYPE unmodifiable(BI_ITERATOR KEY_GENERIC_TYPE iterator) {
return iterator instanceof UnmodifiableBiIterator ? iterator : new UnmodifiableBiIteratorBRACES(iterator);
}
/**
* Returns a Immutable ListIterator instance based on the instance given.
* @param l that should be made immutable/unmodifyable
* @return a unmodifiable listiterator wrapper. If the ListIterator already a unmodifyable wrapper then it just returns itself.
*/
public static GENERIC_KEY_BRACES LIST_ITERATOR KEY_GENERIC_TYPE unmodifiable(LIST_ITERATOR KEY_GENERIC_TYPE iterator) {
return iterator instanceof UnmodifiableListIterator ? iterator : new UnmodifiableListIteratorBRACES(iterator);
}
#if !TYPE_OBJECT
public static ITERATOR wrap(Iterator<CLASS_TYPE> iterator) {
return iterator instanceof ITERATOR ? (ITERATOR)iterator : new IteratorWrapper(iterator);
}
#endif
/**
* Returns a Array Wrapping iterator
* @param a the array that should be wrapped
* @return a Iterator that is wrapping a array.
*/
public static GENERIC_KEY_BRACES ArrayIterator KEY_GENERIC_TYPE wrap(KEY_TYPE[] a) {
return wrap(a, 0, a.length);
}
/**
* Returns a Array Wrapping iterator
* @param a the array that should be wrapped.
* @param start the index to be started from.
* @param end the index that should be ended.
* @return a Iterator that is wrapping a array.
*/
public static GENERIC_KEY_BRACES ArrayIterator KEY_GENERIC_TYPE wrap(KEY_TYPE[] a, int start, int end) {
return new ArrayIteratorBRACES(a, start, end);
}
/**
* Iterates over a iterator and inserts the values into the array and returns the amount that was inserted
* @param a where the elements should be inserted
* @param i the source iterator
* @return the amount of elements that were inserted into the array.
*/
public static GENERIC_KEY_BRACES int unwrap(KEY_TYPE[] a, Iterator<? extends CLASS_TYPE> i) {
return unwrap(a, i, 0, a.length);
}
/**
* Iterates over a iterator and inserts the values into the array and returns the amount that was inserted
* @param a where the elements should be inserted
* @param i the source iterator
* @param offset the array offset where the start should be
* @return the amount of elements that were inserted into the array.
*/
public static GENERIC_KEY_BRACES int unwrap(KEY_TYPE[] a, Iterator<? extends CLASS_TYPE> i, int offset) {
return unwrap(a, i, offset, a.length - offset);
}
/**
* Iterates over a iterator and inserts the values into the array and returns the amount that was inserted
* @param a where the elements should be inserted
* @param i the source iterator
* @param offset the array offset where the start should be
* @param max the maximum values that should be extracted from the source
* @return the amount of elements that were inserted into the array.
* @throws IllegalStateException if max is smaller the 0 or if the maximum index is larger then the array
*/
public static GENERIC_KEY_BRACES int unwrap(KEY_TYPE[] a, Iterator<? extends CLASS_TYPE> i, int offset, int max) {
if(max < 0) throw new IllegalStateException("The max size is smaller then 0");
if(offset + max > a.length) throw new IllegalStateException("largest array index exceeds array size");
int index = 0;
for(;index<max && i.hasNext();index++) a[index+offset] = OBJ_TO_KEY(i.next());
return index;
}
/**
* A Primitive iterator variant of the {@link #unwrap(KEY_TYPE[], Iterator)} function
* Iterates over a iterator and inserts the values into the array and returns the amount that was inserted
* @param a where the elements should be inserted
* @param i the source iterator
* @return the amount of elements that were inserted into the array.
*/
public static GENERIC_KEY_BRACES int unwrap(KEY_TYPE[] a, ITERATOR KEY_GENERIC_TYPE i) {
return unwrap(a, i, 0, a.length);
}
/**
* A Primitive iterator variant of the {@link #unwrap(KEY_TYPE[], Iterator, int)} function
* Iterates over a iterator and inserts the values into the array and returns the amount that was inserted
* @param a where the elements should be inserted
* @param i the source iterator
* @param offset the array offset where the start should be
* @return the amount of elements that were inserted into the array.
*/
public static GENERIC_KEY_BRACES int unwrap(KEY_TYPE[] a, ITERATOR KEY_GENERIC_TYPE i, int offset) {
return unwrap(a, i, offset, a.length - offset);
}
/**
* A Primitive iterator variant of the {@link #unwrap(KEY_TYPE[], Iterator, int, int)} function
* Iterates over a iterator and inserts the values into the array and returns the amount that was inserted
* @param a where the elements should be inserted
* @param i the source iterator
* @param offset the array offset where the start should be
* @param max the maximum values that should be extracted from the source
* @return the amount of elements that were inserted into the array.
* @throws IllegalStateException if max is smaller the 0 or if the maximum index is larger then the array
*/
public static GENERIC_KEY_BRACES int unwrap(KEY_TYPE[] a, ITERATOR KEY_GENERIC_TYPE i, int offset, int max) {
if(max < 0) throw new IllegalStateException("The max size is smaller then 0");
if(offset + max > a.length) throw new IllegalStateException("largest array index exceeds array size");
int index = 0;
for(;index<max && i.hasNext();index++) a[index+offset] = i.NEXT();
return index;
}
#if !TYPE_OBJECT
/**
* A Function to convert a Primitive Iterator to a Object array.
* Iterates over a iterator and inserts the values into the array and returns the amount that was inserted
* @param a where the elements should be inserted
* @param i the source iterator
* @return the amount of elements that were inserted into the array.
*/
public static GENERIC_KEY_BRACES int unwrap(CLASS_TYPE[] a, ITERATOR KEY_GENERIC_TYPE i) {
return unwrap(a, i, 0, a.length);
}
/**
* A Function to convert a Primitive Iterator to a Object array.
* Iterates over a iterator and inserts the values into the array and returns the amount that was inserted
* @param a where the elements should be inserted
* @param i the source iterator
* @param offset the array offset where the start should be
* @return the amount of elements that were inserted into the array.
*/
public static GENERIC_KEY_BRACES int unwrap(CLASS_TYPE[] a, ITERATOR KEY_GENERIC_TYPE i, int offset) {
return unwrap(a, i, offset, a.length - offset);
}
/**
* A Function to convert a Primitive Iterator to a Object array.
* Iterates over a iterator and inserts the values into the array and returns the amount that was inserted
* @param a where the elements should be inserted
* @param i the source iterator
* @param offset the array offset where the start should be
* @param max the maximum values that should be extracted from the source
* @return the amount of elements that were inserted into the array.
* @throws IllegalStateException if max is smaller the 0 or if the maximum index is larger then the array
*/
public static GENERIC_KEY_BRACES int unwrap(CLASS_TYPE[] a, ITERATOR KEY_GENERIC_TYPE i, int offset, int max) {
if(max < 0) throw new IllegalStateException("The max size is smaller then 0");
if(offset + max > a.length) throw new IllegalStateException("largest array index exceeds array size");
int index = 0;
for(;index<max && i.hasNext();index++) a[index+offset] = KEY_TO_OBJ(i.NEXT());
return index;
}
private static class IteratorWrapper implements ITERATOR
{
Iterator<CLASS_TYPE> iter;
public IteratorWrapper(Iterator<CLASS_TYPE> iter) {
this.iter = iter;
}
@Override
public boolean hasNext() {
return iter.hasNext();
}
@Override
public KEY_TYPE NEXT() {
return OBJ_TO_KEY(iter.next());
}
@Override
@Deprecated
public CLASS_TYPE next() {
return iter.next();
}
}
#endif
private static class UnmodifiableListIterator KEY_GENERIC_TYPE implements LIST_ITERATOR KEY_GENERIC_TYPE
{
LIST_ITERATOR KEY_GENERIC_TYPE iter;
UnmodifiableListIterator(LIST_ITERATOR KEY_GENERIC_TYPE iter) {
this.iter = iter;
}
@Override
public boolean hasNext() {
return iter.hasNext();
}
@Override
public boolean hasPrevious() {
return iter.hasPrevious();
}
@Override
public int nextIndex() {
return iter.nextIndex();
}
@Override
public int previousIndex() {
return iter.previousIndex();
}
@Override
public void remove() { throw new UnsupportedOperationException(); }
@Override
public KEY_TYPE PREVIOUS() {
return iter.PREVIOUS();
}
@Override
public KEY_TYPE NEXT() {
return iter.NEXT();
}
@Override
public void set(KEY_TYPE e) { throw new UnsupportedOperationException(); }
@Override
public void add(KEY_TYPE e) { throw new UnsupportedOperationException(); }
}
private static class UnmodifiableBiIterator KEY_GENERIC_TYPE implements BI_ITERATOR KEY_GENERIC_TYPE
{
BI_ITERATOR KEY_GENERIC_TYPE iter;
UnmodifiableBiIterator(BI_ITERATOR KEY_GENERIC_TYPE iter) {
this.iter = iter;
}
@Override
public KEY_TYPE NEXT() {
return iter.NEXT();
}
@Override
public boolean hasNext() {
return iter.hasNext();
}
@Override
public boolean hasPrevious() {
return iter.hasPrevious();
}
@Override
public KEY_TYPE PREVIOUS() {
return iter.PREVIOUS();
}
}
private static class UnmodifiableIterator KEY_GENERIC_TYPE implements ITERATOR KEY_GENERIC_TYPE
{
ITERATOR KEY_GENERIC_TYPE iterator;
UnmodifiableIterator(ITERATOR KEY_GENERIC_TYPE iterator) {
this.iterator = iterator;
}
@Override
public boolean hasNext() {
return iterator.hasNext();
}
@Override
public KEY_TYPE NEXT() {
return iterator.NEXT();
}
}
private static class EmptyIterator KEY_GENERIC_TYPE implements LIST_ITERATOR KEY_GENERIC_TYPE
{
@Override
public boolean hasNext() {
return false;
}
@Override
public KEY_TYPE NEXT() {
return EMPTY_KEY_VALUE;
}
@Override
public boolean hasPrevious() {
return false;
}
@Override
public KEY_TYPE PREVIOUS() {
return EMPTY_KEY_VALUE;
}
@Override
public int nextIndex() {
return 0;
}
@Override
public int previousIndex() {
return 0;
}
@Override
public void remove() { throw new UnsupportedOperationException(); }
@Override
public void set(KEY_TYPE e) { throw new UnsupportedOperationException(); }
@Override
public void add(KEY_TYPE e) { throw new UnsupportedOperationException(); }
}
private static class ArrayIterator KEY_GENERIC_TYPE implements ITERATOR KEY_GENERIC_TYPE
{
KEY_TYPE[] a;
int from;
int to;
ArrayIterator(KEY_TYPE[] a, int from, int to) {
this.a = a;
this.from = from;
this.to = to;
}
@Override
public boolean hasNext() {
return from < to;
}
@Override
public KEY_TYPE NEXT() {
return a[from++];
}
@Override
public int skip(int amount) {
if(amount < 0) throw new IllegalStateException("Negative Numbers are not allowed");
int left = Math.min(amount, to - from);
from += left;
return amount - left;
}
}
}
@@ -0,0 +1,400 @@
package speiger.src.collections.PACKAGE.utils;
import java.util.Collection;
import java.util.Objects;
import java.util.RandomAccess;
import java.util.function.Consumer;
import speiger.src.collections.PACKAGE.collections.COLLECTION;
#if !TYPE_OBJECT
import speiger.src.collections.PACKAGE.functions.CONSUMER;
#endif
import speiger.src.collections.PACKAGE.lists.LIST;
import speiger.src.collections.PACKAGE.lists.LIST_ITERATOR;
/**
* A Helper class for Lists
*/
public class LISTS
{
public static final EmptyList NO_GENERIC_TYPE EMPTY = new EmptyListBRACES();
/**
* Returns a Immutable EmptyList instance that is automatically casted.
* @return an empty list
*/
public static GENERIC_KEY_BRACES EmptyList KEY_GENERIC_TYPE emptyList() {
#if TYPE_OBJECT
return (EmptyList<KEY_TYPE>)EMPTY;
#else
return EMPTY;
#endif
}
/**
* Returns a Immutable List instance based on the instance given.
* @param l that should be made immutable/unmodifyable
* @return a unmodifiable list wrapper. If the list is implementing RandomAccess that is also transferred. If the List already a unmodifyable wrapper then it just returns itself.
*/
public static GENERIC_KEY_BRACES LIST KEY_GENERIC_TYPE unmodifiableList(LIST KEY_GENERIC_TYPE l) {
return l instanceof UnmodifiableList ? l : l instanceof RandomAccess ? new UnmodifiableRandomListBRACES(l) : new UnmodifiableListBRACES(l);
}
/**
* Returns a synchronized List instance based on the instance given.
* @param l that should be synchronized
* @return a synchronized list wrapper. If the list is implementing RandomAccess or IARRAY that is also transferred. If the List already a synchronized wrapper then it just returns itself.
*/
public static GENERIC_KEY_BRACES LIST KEY_GENERIC_TYPE synchronizedList(LIST KEY_GENERIC_TYPE l) {
return l instanceof SynchronizedList ? l : (l instanceof IARRAY ? new SynchronizedArrayListBRACES(l) : (l instanceof RandomAccess ? new SynchronizedRandomAccessListBRACES(l) : new SynchronizedListBRACES(l)));
}
/**
* Returns a synchronized List instance based on the instance given.
* @param l that should be synchronized
* @param mutex is the controller of the synchronization block.
* @return a synchronized list wrapper. If the list is implementing RandomAccess or IARRAY that is also transferred. If the List already a synchronized wrapper then it just returns itself.
*/
public static GENERIC_KEY_BRACES LIST KEY_GENERIC_TYPE synchronizedList(LIST KEY_GENERIC_TYPE l, Object mutex) {
return l instanceof SynchronizedList ? l : (l instanceof IARRAY ? new SynchronizedArrayListBRACES(l, mutex) : (l instanceof RandomAccess ? new SynchronizedRandomAccessListBRACES(l, mutex) : new SynchronizedListBRACES(l, mutex)));
}
public static class SynchronizedArrayList KEY_GENERIC_TYPE extends SynchronizedList KEY_GENERIC_TYPE implements IARRAY KEY_GENERIC_TYPE
{
IARRAY KEY_GENERIC_TYPE l;
SynchronizedArrayList(LIST KEY_GENERIC_TYPE l) {
super(l);
this.l = (IARRAY KEY_GENERIC_TYPE)l;
}
SynchronizedArrayList(LIST KEY_GENERIC_TYPE l, Object mutex) {
super(l, mutex);
this.l = (IARRAY KEY_GENERIC_TYPE)l;
}
@Override
public void ensureCapacity(int size) { synchronized(mutex) { l.ensureCapacity(size); } }
@Override
public boolean trim(int size) { synchronized(mutex) { return l.trim(size); } }
@Override
public KEY_TYPE[] elements() { synchronized(mutex) { return l.elements(); } }
@Override
public void elements(Consumer<KEY_TYPE[]> action) {
Objects.requireNonNull(action);
synchronized(mutex) {
action.accept(elements());
}
}
}
public static class SynchronizedRandomAccessList KEY_GENERIC_TYPE extends SynchronizedList KEY_GENERIC_TYPE implements RandomAccess
{
SynchronizedRandomAccessList(LIST KEY_GENERIC_TYPE l) {
super(l);
}
SynchronizedRandomAccessList(LIST KEY_GENERIC_TYPE l, Object mutex) {
super(l, mutex);
}
}
public static class SynchronizedList KEY_GENERIC_TYPE extends COLLECTIONS.SynchronizedCollection KEY_GENERIC_TYPE implements LIST KEY_GENERIC_TYPE
{
LIST KEY_GENERIC_TYPE l;
SynchronizedList(LIST KEY_GENERIC_TYPE l) {
super(l);
this.l = l;
}
SynchronizedList(LIST KEY_GENERIC_TYPE l, Object mutex) {
super(l, mutex);
this.l = l;
}
@Override
public boolean addAll(int index, Collection<? extends CLASS_TYPE> c) { synchronized(mutex) { return l.addAll(index, c); } }
@Override
public void add(int index, CLASS_TYPE element) { synchronized(mutex) { l.add(index, element); } }
#if !TYPE_OBJECT
@Override
public void add(int index, KEY_TYPE e) { synchronized(mutex) { l.add(index, e); } }
#endif
@Override
public boolean addAll(int index, COLLECTION KEY_GENERIC_TYPE c) { synchronized(mutex) { return l.addAll(index, c); } }
@Override
public boolean addAll(LIST KEY_GENERIC_TYPE c) { synchronized(mutex) { return l.addAll(c); } }
@Override
public boolean addAll(int index, LIST KEY_GENERIC_TYPE c) { synchronized(mutex) { return l.addAll(index, c); } }
@Override
public KEY_TYPE GET_KEY(int index) { synchronized(mutex) { return l.GET_KEY(index); } }
#if !TYPE_OBJECT
@Override
public void forEach(CONSUMER action) { synchronized(mutex) { l.forEach(action); } }
#else
@Override
public void forEach(Consumer<? super KEY_TYPE> action) { synchronized(mutex) { l.forEach(action); } }
#endif
@Override
public KEY_TYPE set(int index, KEY_TYPE e) { synchronized(mutex) { return l.set(index, e); } }
@Override
public KEY_TYPE REMOVE(int index) { synchronized(mutex) { return l.REMOVE(index); } }
@Override
@Primitive
public int indexOf(Object e) { synchronized(mutex) { return l.indexOf(e); } }
@Override
@Primitive
public int lastIndexOf(Object e) { synchronized(mutex) { return l.lastIndexOf(e); } }
#if !TYPE_OBJECT
@Override
public int indexOf(KEY_TYPE e) { synchronized(mutex) { return l.indexOf(e); } }
@Override
public int lastIndexOf(KEY_TYPE e) { synchronized(mutex) { return l.lastIndexOf(e); } }
#endif
@Override
public void addElements(int from, KEY_TYPE[] a, int offset, int length) { synchronized(mutex) { addElements(from, a, offset, length); } }
@Override
public KEY_TYPE[] getElements(int from, KEY_TYPE[] a, int offset, int length) { synchronized(mutex) { return l.getElements(from, a, offset, length); } }
@Override
public void removeElements(int from, int to) { synchronized(mutex) { l.removeElements(from, to); } }
#if !TYPE_OBJECT
@Override
public KEY_TYPE[] extractElements(int from, int to) { synchronized(mutex) { return l.extractElements(from, to); } }
#else
@Override
public <K> K[] extractElements(int from, int to, Class<K> clz) { synchronized(mutex) { return l.extractElements(from, to, clz); } }
#endif
@Override
public LIST_ITERATOR KEY_GENERIC_TYPE listIterator() {
return l.listIterator();
}
@Override
public LIST_ITERATOR KEY_GENERIC_TYPE listIterator(int index) {
return l.listIterator(index);
}
@Override
public LIST KEY_GENERIC_TYPE subList(int from, int to) {
return synchronizedList(l.subList(from, to));
}
@Override
public void size(int size) { synchronized(mutex) { l.size(size); } }
}
public static class UnmodifiableRandomList KEY_GENERIC_TYPE extends UnmodifiableList KEY_GENERIC_TYPE implements RandomAccess
{
UnmodifiableRandomList(LIST KEY_GENERIC_TYPE l) {
super(l);
}
}
public static class UnmodifiableList KEY_GENERIC_TYPE extends COLLECTIONS.UnmodifiableCollection KEY_GENERIC_TYPE implements LIST KEY_GENERIC_TYPE
{
final LIST KEY_GENERIC_TYPE l;
UnmodifiableList(LIST KEY_GENERIC_TYPE l) {
super(l);
this.l = l;
}
@Override
public boolean addAll(int index, Collection<? extends CLASS_TYPE> c) { throw new UnsupportedOperationException(); }
@Override
public void add(int index, CLASS_TYPE element) { throw new UnsupportedOperationException(); }
#if !TYPE_OBJECT
@Override
public void add(int index, KEY_TYPE e) { throw new UnsupportedOperationException(); }
#endif
@Override
public boolean addAll(int index, COLLECTION KEY_GENERIC_TYPE c) { throw new UnsupportedOperationException(); }
@Override
public boolean addAll(LIST KEY_GENERIC_TYPE c) { throw new UnsupportedOperationException(); }
@Override
public boolean addAll(int index, LIST KEY_GENERIC_TYPE c) { throw new UnsupportedOperationException(); }
@Override
public KEY_TYPE GET_KEY(int index) { return l.GET_KEY(index); }
#if !TYPE_OBJECT
@Override
public void forEach(CONSUMER action) { l.forEach(action); }
#else
@Override
public void forEach(Consumer<? super KEY_TYPE> action) { l.forEach(action); }
#endif
@Override
public KEY_TYPE set(int index, KEY_TYPE e) { throw new UnsupportedOperationException(); }
@Override
public KEY_TYPE REMOVE(int index) { throw new UnsupportedOperationException(); }
@Override
@Primitive
public int indexOf(Object e) { return l.indexOf(e); }
@Override
@Primitive
public int lastIndexOf(Object e) { return l.lastIndexOf(e); }
#if !TYPE_OBJECT
@Override
public int indexOf(KEY_TYPE e) { return l.indexOf(e); }
@Override
public int lastIndexOf(KEY_TYPE e) { return l.lastIndexOf(e); }
#endif
@Override
public void addElements(int from, KEY_TYPE[] a, int offset, int length) { throw new UnsupportedOperationException(); }
@Override
public KEY_TYPE[] getElements(int from, KEY_TYPE[] a, int offset, int length) {
return l.getElements(from, a, offset, length);
}
@Override
public void removeElements(int from, int to) { throw new UnsupportedOperationException(); }
#if !TYPE_OBJECT
@Override
public KEY_TYPE[] extractElements(int from, int to) { throw new UnsupportedOperationException(); }
#else
@Override
public <K> K[] extractElements(int from, int to, Class<K> clz) { throw new UnsupportedOperationException(); }
#endif
@Override
public LIST_ITERATOR KEY_GENERIC_TYPE listIterator() {
return ITERATORS.unmodifiable(l.listIterator());
}
@Override
public LIST_ITERATOR KEY_GENERIC_TYPE listIterator(int index) {
return ITERATORS.unmodifiable(l.listIterator(index));
}
@Override
public LIST KEY_GENERIC_TYPE subList(int from, int to) {
return unmodifiableList(l.subList(from, to));
}
@Override
public void size(int size) { throw new UnsupportedOperationException(); }
}
public static class EmptyList KEY_GENERIC_TYPE extends COLLECTIONS.EmptyCollection KEY_GENERIC_TYPE implements LIST KEY_GENERIC_TYPE
{
@Override
public boolean addAll(int index, Collection<? extends CLASS_TYPE> c) { throw new UnsupportedOperationException(); }
@Override
public void add(int index, CLASS_TYPE element) { throw new UnsupportedOperationException(); }
#if !TYPE_OBJECT
@Override
public void add(int index, KEY_TYPE e) { throw new UnsupportedOperationException(); }
#endif
@Override
public boolean addAll(int index, COLLECTION KEY_GENERIC_TYPE c) { throw new UnsupportedOperationException(); }
@Override
public boolean addAll(LIST KEY_GENERIC_TYPE c) { throw new UnsupportedOperationException(); }
@Override
public boolean addAll(int index, LIST KEY_GENERIC_TYPE c) { throw new UnsupportedOperationException(); }
@Override
public KEY_TYPE GET_KEY(int index) { throw new IndexOutOfBoundsException(); }
@Override
public KEY_TYPE set(int index, KEY_TYPE e) { throw new UnsupportedOperationException(); }
@Override
public KEY_TYPE REMOVE(int index) { throw new UnsupportedOperationException(); }
@Override
public int indexOf(Object e) { return -1; }
@Override
public int lastIndexOf(Object e) { return -1; }
#if !TYPE_OBJECT
@Override
public int indexOf(KEY_TYPE e) { return -1; }
@Override
public int lastIndexOf(KEY_TYPE e) { return -1; }
#endif
@Override
public void addElements(int from, KEY_TYPE[] a, int offset, int length){ throw new UnsupportedOperationException(); }
@Override
public KEY_TYPE[] getElements(int from, KEY_TYPE[] a, int offset, int length) { throw new IndexOutOfBoundsException(); }
@Override
public void removeElements(int from, int to) { throw new UnsupportedOperationException(); }
#if !TYPE_OBJECT
@Override
public KEY_TYPE[] extractElements(int from, int to) { throw new UnsupportedOperationException(); }
#else
@Override
public <K> K[] extractElements(int from, int to, Class<K> clz) { throw new UnsupportedOperationException(); }
#endif
@Override
public LIST_ITERATOR KEY_GENERIC_TYPE listIterator() {
return ITERATORS.emptyIterator();
}
@Override
public LIST_ITERATOR KEY_GENERIC_TYPE listIterator(int index) {
if(index != 0)
throw new IndexOutOfBoundsException();
return ITERATORS.emptyIterator();
}
@Override
public LIST KEY_GENERIC_TYPE subList(int from, int to) { throw new UnsupportedOperationException(); }
@Override
public void size(int size) { throw new UnsupportedOperationException(); }
}
}
@@ -0,0 +1,417 @@
package speiger.src.collections.PACKAGE.utils;
#if TYPE_OBJECT
import java.util.Comparator;
#endif
import speiger.src.collections.PACKAGE.collections.BI_ITERATOR;
#if !TYPE_OBJECT
import speiger.src.collections.PACKAGE.functions.COMPARATOR;
#endif
import speiger.src.collections.PACKAGE.sets.NAVIGABLE_SET;
import speiger.src.collections.PACKAGE.sets.SET;
import speiger.src.collections.PACKAGE.sets.SORTED_SET;
import speiger.src.collections.PACKAGE.utils.COLLECTIONS.EmptyCollection;
import speiger.src.collections.PACKAGE.utils.COLLECTIONS.SynchronizedCollection;
import speiger.src.collections.PACKAGE.utils.COLLECTIONS.UnmodifiableCollection;
import speiger.src.collections.utils.ITrimmable;
public class SETS
{
public static final SET NO_GENERIC_TYPE EMPTY = new EmptySetBRACES();
public static GENERIC_KEY_BRACES SET KEY_GENERIC_TYPE empty() {
#if TYPE_OBJECT
return (SET<KEY_TYPE>)EMPTY;
#else
return EMPTY;
#endif
}
public static GENERIC_KEY_BRACES SET KEY_GENERIC_TYPE synchronizedSet(SET KEY_GENERIC_TYPE s) {
return s instanceof SynchronizedSet ? s : (s instanceof ITrimmable ? new SynchronizedTrimSetBRACES(s) : new SynchronizedSetBRACES(s));
}
public static GENERIC_KEY_BRACES SET KEY_GENERIC_TYPE synchronizedSet(SET KEY_GENERIC_TYPE s, Object mutex) {
return s instanceof SynchronizedSet ? s : (s instanceof ITrimmable ? new SynchronizedTrimSetBRACES(s, mutex) : new SynchronizedSetBRACES(s, mutex));
}
public static GENERIC_KEY_BRACES SORTED_SET KEY_GENERIC_TYPE synchronizedSet(SORTED_SET KEY_GENERIC_TYPE s) {
return s instanceof SynchronizedSortedSet ? s : (s instanceof ITrimmable ? new SynchronizedSortedTrimSetBRACES(s) : new SynchronizedSortedSetBRACES(s));
}
public static GENERIC_KEY_BRACES SORTED_SET KEY_GENERIC_TYPE synchronizedSet(SORTED_SET KEY_GENERIC_TYPE s, Object mutex) {
return s instanceof SynchronizedSortedSet ? s : (s instanceof ITrimmable ? new SynchronizedSortedTrimSetBRACES(s, mutex) : new SynchronizedSortedSetBRACES(s, mutex));
}
public static GENERIC_KEY_BRACES NAVIGABLE_SET KEY_GENERIC_TYPE synchronizedSet(NAVIGABLE_SET KEY_GENERIC_TYPE s) {
return s instanceof SynchronizedNavigableSet ? s : (s instanceof ITrimmable ? new SynchronizedNavigableTrimSetBRACES(s) : new SynchronizedNavigableSetBRACES(s));
}
public static GENERIC_KEY_BRACES NAVIGABLE_SET KEY_GENERIC_TYPE synchronizedSet(NAVIGABLE_SET KEY_GENERIC_TYPE s, Object mutex) {
return s instanceof SynchronizedNavigableSet ? s : (s instanceof ITrimmable ? new SynchronizedNavigableTrimSetBRACES(s, mutex) : new SynchronizedNavigableSetBRACES(s, mutex));
}
public static GENERIC_KEY_BRACES SET KEY_GENERIC_TYPE unmodifiable(SET KEY_GENERIC_TYPE s) {
return s instanceof SynchronizedSet ? s : new SynchronizedSetBRACES(s);
}
public static GENERIC_KEY_BRACES SORTED_SET KEY_GENERIC_TYPE unmodifiable(SORTED_SET KEY_GENERIC_TYPE s) {
return s instanceof SynchronizedSortedSet ? s : new SynchronizedSortedSetBRACES(s);
}
public static GENERIC_KEY_BRACES NAVIGABLE_SET KEY_GENERIC_TYPE unmodifiable(NAVIGABLE_SET KEY_GENERIC_TYPE s) {
return s instanceof UnmodifiableNavigableSet ? s : new UnmodifiableNavigableSetBRACES(s);
}
public static class EmptySet KEY_GENERIC_TYPE extends EmptyCollection KEY_GENERIC_TYPE implements SET KEY_GENERIC_TYPE
{
#if !TYPE_OBJECT
@Override
public boolean remove(KEY_TYPE o) { throw new UnsupportedOperationException(); }
#endif
}
public static class UnmodifiableNavigableSet KEY_GENERIC_TYPE extends UnmodifiableSortedSet KEY_GENERIC_TYPE implements NAVIGABLE_SET KEY_GENERIC_TYPE
{
NAVIGABLE_SET KEY_GENERIC_TYPE n;
public UnmodifiableNavigableSet(NAVIGABLE_SET KEY_GENERIC_TYPE c) {
super(c);
n = c;
}
#if !TYPE_OBJECT
@Override
public boolean contains(KEY_TYPE o) { return n.contains(o); }
#endif
@Override
@Deprecated
public boolean contains(Object o) { return n.contains(o); }
@Override
public KEY_TYPE lower(KEY_TYPE e) { return n.lower(e); }
@Override
public KEY_TYPE floor(KEY_TYPE e) { return n.floor(e); }
@Override
public KEY_TYPE ceiling(KEY_TYPE e) { return n.ceiling(e); }
@Override
public KEY_TYPE higher(KEY_TYPE e) { return n.higher(e); }
#if !TYPE_OBJECT
@Override
public void setDefaultMaxValue(KEY_TYPE e) { throw new UnsupportedOperationException(); }
@Override
public KEY_TYPE getDefaultMaxValue() { return n.getDefaultMaxValue(); }
@Override
public void setDefaultMinValue(KEY_TYPE e) { throw new UnsupportedOperationException(); }
@Override
public KEY_TYPE getDefaultMinValue() { return n.getDefaultMinValue(); }
#endif
@Override
public NAVIGABLE_SET KEY_GENERIC_TYPE subSet(KEY_TYPE fromElement, boolean fromInclusive, KEY_TYPE toElement, boolean toInclusive) { return unmodifiable(n.subSet(fromElement, fromInclusive, toElement, toInclusive)); }
@Override
public NAVIGABLE_SET KEY_GENERIC_TYPE headSet(KEY_TYPE toElement, boolean inclusive) { return unmodifiable(n.headSet(toElement, inclusive)); }
@Override
public NAVIGABLE_SET KEY_GENERIC_TYPE tailSet(KEY_TYPE fromElement, boolean inclusive) { return unmodifiable(n.tailSet(fromElement, inclusive)); }
@Override
public BI_ITERATOR KEY_GENERIC_TYPE descendingIterator() { return ITERATORS.unmodifiable(n.descendingIterator()); }
@Override
public NAVIGABLE_SET KEY_GENERIC_TYPE descendingSet() { return unmodifiable(n.descendingSet()); }
@Override
public NAVIGABLE_SET KEY_GENERIC_TYPE subSet(KEY_TYPE fromElement, KEY_TYPE toElement) { return unmodifiable(n.subSet(fromElement, toElement)); }
@Override
public NAVIGABLE_SET KEY_GENERIC_TYPE headSet(KEY_TYPE toElement) { return unmodifiable(n.headSet(toElement)); }
@Override
public NAVIGABLE_SET KEY_GENERIC_TYPE tailSet(KEY_TYPE fromElement) { return unmodifiable(n.tailSet(fromElement)); }
}
public static class UnmodifiableSortedSet KEY_GENERIC_TYPE extends UnmodifiableSet KEY_GENERIC_TYPE implements SORTED_SET KEY_GENERIC_TYPE
{
SORTED_SET KEY_GENERIC_TYPE s;
public UnmodifiableSortedSet(SORTED_SET KEY_GENERIC_TYPE c)
{
super(c);
s = c;
}
@Override
public boolean addAndMoveToFirst(KEY_TYPE o) { throw new UnsupportedOperationException(); }
@Override
public boolean addAndMoveToLast(KEY_TYPE o) { throw new UnsupportedOperationException(); }
@Override
public boolean moveToFirst(KEY_TYPE o) { throw new UnsupportedOperationException(); }
@Override
public boolean moveToLast(KEY_TYPE o) { throw new UnsupportedOperationException(); }
@Override
public COMPARATOR KEY_GENERIC_TYPE comparator() { return s.comparator(); }
@Override
public BI_ITERATOR KEY_GENERIC_TYPE iterator() { return ITERATORS.unmodifiable(s.iterator()); }
@Override
public BI_ITERATOR KEY_GENERIC_TYPE iterator(KEY_TYPE fromElement) { return ITERATORS.unmodifiable(s.iterator(fromElement)); }
@Override
public SORTED_SET KEY_GENERIC_TYPE subSet(KEY_TYPE fromElement, KEY_TYPE toElement) { return unmodifiable(s.subSet(fromElement, toElement)); }
@Override
public SORTED_SET KEY_GENERIC_TYPE headSet(KEY_TYPE toElement) { return unmodifiable(s.headSet(toElement)); }
@Override
public SORTED_SET KEY_GENERIC_TYPE tailSet(KEY_TYPE fromElement) { return unmodifiable(s.tailSet(fromElement)); }
@Override
public KEY_TYPE FIRST_KEY() { return s.FIRST_KEY(); }
@Override
public KEY_TYPE POLL_FIRST_KEY() { throw new UnsupportedOperationException(); }
@Override
public KEY_TYPE LAST_KEY() { return s.LAST_KEY(); }
@Override
public KEY_TYPE POLL_LAST_KEY() { throw new UnsupportedOperationException(); }
}
public static class UnmodifiableSet KEY_GENERIC_TYPE extends UnmodifiableCollection KEY_GENERIC_TYPE implements SET KEY_GENERIC_TYPE
{
SET KEY_GENERIC_TYPE s;
public UnmodifiableSet(SET KEY_GENERIC_TYPE c)
{
super(c);
s = c;
}
#if !TYPE_OBJECT
@Override
public boolean remove(KEY_TYPE o) { throw new UnsupportedOperationException(); }
#endif
}
public static class SynchronizedNavigableTrimSet KEY_GENERIC_TYPE extends SynchronizedNavigableSet KEY_GENERIC_TYPE implements ITrimmable
{
ITrimmable trim;
public SynchronizedNavigableTrimSet(NAVIGABLE_SET KEY_GENERIC_TYPE c) {
super(c);
trim = (ITrimmable)c;
}
public SynchronizedNavigableTrimSet(NAVIGABLE_SET KEY_GENERIC_TYPE c, Object mutex) {
super(c, mutex);
trim = (ITrimmable)c;
}
@Override
public boolean trim(int size) { synchronized(mutex) { return trim.trim(size); } }
}
public static class SynchronizedNavigableSet KEY_GENERIC_TYPE extends SynchronizedSortedSet KEY_GENERIC_TYPE implements NAVIGABLE_SET KEY_GENERIC_TYPE
{
NAVIGABLE_SET KEY_GENERIC_TYPE n;
public SynchronizedNavigableSet(NAVIGABLE_SET KEY_GENERIC_TYPE c) {
super(c);
n = c;
}
public SynchronizedNavigableSet(NAVIGABLE_SET KEY_GENERIC_TYPE c, Object mutex) {
super(c, mutex);
n = c;
}
@Override
@Deprecated
public boolean contains(Object o) { synchronized(mutex) { return n.contains(o); } }
#if !TYPE_OBJECT
@Override
public boolean contains(KEY_TYPE o) { synchronized(mutex) { return n.contains(o); } }
#endif
@Override
public KEY_TYPE lower(KEY_TYPE e) { synchronized(mutex) { return n.lower(e); } }
@Override
public KEY_TYPE floor(KEY_TYPE e) { synchronized(mutex) { return n.floor(e); } }
@Override
public KEY_TYPE ceiling(KEY_TYPE e) { synchronized(mutex) { return n.ceiling(e); } }
@Override
public KEY_TYPE higher(KEY_TYPE e) { synchronized(mutex) { return n.higher(e); } }
#if !TYPE_OBJECT
@Override
public void setDefaultMaxValue(KEY_TYPE e) { synchronized(mutex) { n.setDefaultMaxValue(e); } }
@Override
public KEY_TYPE getDefaultMaxValue() { synchronized(mutex) { return n.getDefaultMaxValue(); } }
@Override
public void setDefaultMinValue(KEY_TYPE e) { synchronized(mutex) { n.setDefaultMinValue(e); } }
@Override
public KEY_TYPE getDefaultMinValue() { synchronized(mutex) { return n.getDefaultMinValue(); } }
#endif
@Override
public NAVIGABLE_SET KEY_GENERIC_TYPE subSet(KEY_TYPE fromElement, boolean fromInclusive, KEY_TYPE toElement, boolean toInclusive) { synchronized(mutex) { return synchronizedSet(n.subSet(fromElement, fromInclusive, toElement, toInclusive), mutex); } }
@Override
public NAVIGABLE_SET KEY_GENERIC_TYPE headSet(KEY_TYPE toElement, boolean inclusive) { synchronized(mutex) { return synchronizedSet(n.headSet(toElement, inclusive), mutex); } }
@Override
public NAVIGABLE_SET KEY_GENERIC_TYPE tailSet(KEY_TYPE fromElement, boolean inclusive) { synchronized(mutex) { return synchronizedSet(n.tailSet(fromElement, inclusive), mutex); } }
@Override
public BI_ITERATOR KEY_GENERIC_TYPE descendingIterator() { synchronized(mutex) { return n.descendingIterator(); } }
@Override
public NAVIGABLE_SET KEY_GENERIC_TYPE descendingSet() { synchronized(mutex) { return synchronizedSet(n.descendingSet(), mutex); } }
@Override
public NAVIGABLE_SET KEY_GENERIC_TYPE subSet(KEY_TYPE fromElement, KEY_TYPE toElement) { synchronized(mutex) { return synchronizedSet(n.subSet(fromElement, toElement), mutex); } }
@Override
public NAVIGABLE_SET KEY_GENERIC_TYPE headSet(KEY_TYPE toElement) { synchronized(mutex) { return synchronizedSet(n.headSet(toElement), mutex); } }
@Override
public NAVIGABLE_SET KEY_GENERIC_TYPE tailSet(KEY_TYPE fromElement) { synchronized(mutex) { return synchronizedSet(n.tailSet(fromElement), mutex); } }
}
public static class SynchronizedSortedTrimSet KEY_GENERIC_TYPE extends SynchronizedSortedSet KEY_GENERIC_TYPE implements ITrimmable
{
ITrimmable trim;
public SynchronizedSortedTrimSet(SORTED_SET KEY_GENERIC_TYPE c) {
super(c);
trim = (ITrimmable)c;
}
public SynchronizedSortedTrimSet(SORTED_SET KEY_GENERIC_TYPE c, Object mutex) {
super(c, mutex);
trim = (ITrimmable)c;
}
@Override
public boolean trim(int size) { synchronized(mutex) { return trim.trim(size); } }
}
public static class SynchronizedSortedSet KEY_GENERIC_TYPE extends SynchronizedSet KEY_GENERIC_TYPE implements SORTED_SET KEY_GENERIC_TYPE
{
SORTED_SET KEY_GENERIC_TYPE s;
public SynchronizedSortedSet(SORTED_SET KEY_GENERIC_TYPE c) {
super(c);
s = c;
}
public SynchronizedSortedSet(SORTED_SET KEY_GENERIC_TYPE c, Object mutex) {
super(c, mutex);
s = c;
}
@Override
public boolean addAndMoveToFirst(KEY_TYPE o) { synchronized(mutex) { return s.addAndMoveToFirst(o); } }
@Override
public boolean addAndMoveToLast(KEY_TYPE o) { synchronized(mutex) { return s.addAndMoveToLast(o); } }
@Override
public boolean moveToFirst(KEY_TYPE o) { synchronized(mutex) { return s.moveToFirst(o); } }
@Override
public boolean moveToLast(KEY_TYPE o) { synchronized(mutex) { return s.moveToLast(o); } }
@Override
public COMPARATOR KEY_GENERIC_TYPE comparator(){ synchronized(mutex) { return s.comparator(); } }
@Override
public BI_ITERATOR KEY_GENERIC_TYPE iterator() { synchronized(mutex) { return s.iterator(); } }
@Override
public BI_ITERATOR KEY_GENERIC_TYPE iterator(KEY_TYPE fromElement) { synchronized(mutex) { return s.iterator(fromElement); } }
@Override
public SORTED_SET KEY_GENERIC_TYPE subSet(KEY_TYPE fromElement, KEY_TYPE toElement) { synchronized(mutex) { return synchronizedSet(s.subSet(fromElement, toElement), mutex); } }
@Override
public SORTED_SET KEY_GENERIC_TYPE headSet(KEY_TYPE toElement) { synchronized(mutex) { return synchronizedSet(s.headSet(toElement), mutex); } }
@Override
public SORTED_SET KEY_GENERIC_TYPE tailSet(KEY_TYPE fromElement) { synchronized(mutex) { return synchronizedSet(s.tailSet(fromElement), mutex); } }
@Override
public KEY_TYPE FIRST_KEY() { synchronized(mutex) { return s.FIRST_KEY(); } }
@Override
public KEY_TYPE POLL_FIRST_KEY() { synchronized(mutex) { return s.POLL_FIRST_KEY(); } }
@Override
public KEY_TYPE LAST_KEY() { synchronized(mutex) { return s.LAST_KEY(); } }
@Override
public KEY_TYPE POLL_LAST_KEY() { synchronized(mutex) { return s.POLL_LAST_KEY(); } }
}
public static class SynchronizedTrimSet KEY_GENERIC_TYPE extends SynchronizedSet KEY_GENERIC_TYPE implements ITrimmable
{
ITrimmable trim;
public SynchronizedTrimSet(SET KEY_GENERIC_TYPE c) {
super(c);
trim = (ITrimmable)c;
}
public SynchronizedTrimSet(SET KEY_GENERIC_TYPE c, Object mutex) {
super(c, mutex);
trim = (ITrimmable)c;
}
@Override
public boolean trim(int size) { synchronized(mutex) { return trim.trim(size); } }
}
public static class SynchronizedSet KEY_GENERIC_TYPE extends SynchronizedCollection KEY_GENERIC_TYPE implements SET KEY_GENERIC_TYPE
{
SET KEY_GENERIC_TYPE s;
public SynchronizedSet(SET KEY_GENERIC_TYPE c) {
super(c);
s = c;
}
public SynchronizedSet(SET KEY_GENERIC_TYPE c, Object mutex) {
super(c, mutex);
s = c;
}
#if !TYPE_OBJECT
@Override
public boolean remove(KEY_TYPE o) { synchronized(mutex) { return s.remove(o); } }
#endif
}
}
@@ -0,0 +1,8 @@
package speiger.src.collections.PACKAGE.utils;
public interface STRATEGY KEY_GENERIC_TYPE
{
public int hashCode(KEY_TYPE o);
public boolean equals(KEY_TYPE key, KEY_TYPE value);
}
@@ -0,0 +1,32 @@
package speiger.src.collections.PACKAGE.utils.maps;
import java.util.function.Consumer;
import speiger.src.collections.objects.collections.ObjectIterable;
import speiger.src.collections.objects.collections.ObjectIterator;
import speiger.src.collections.PACKAGE.maps.interfaces.MAP;
import speiger.src.collections.objects.sets.ObjectSet;
public class MAPS
{
public static GENERIC_KEY_VALUE_BRACES ObjectIterator<MAP.Entry KEY_VALUE_GENERIC_TYPE> fastIterator(MAP KEY_VALUE_GENERIC_TYPE map) {
ObjectSet<MAP.Entry KEY_VALUE_GENERIC_TYPE> entries = map.ENTRY_SET();
return entries instanceof MAP.FastEntrySet ? ((MAP.FastEntrySet KEY_VALUE_GENERIC_TYPE)entries).fastIterator() : entries.iterator();
}
public static GENERIC_KEY_VALUE_BRACES ObjectIterable<MAP.Entry KEY_VALUE_GENERIC_TYPE> fastIterable(MAP KEY_VALUE_GENERIC_TYPE map) {
ObjectSet<MAP.Entry KEY_VALUE_GENERIC_TYPE> entries = map.ENTRY_SET();
return map instanceof MAP.FastEntrySet ? new ObjectIterable<MAP.Entry KEY_VALUE_GENERIC_TYPE>(){
@Override
public ObjectIterator<MAP.Entry KEY_VALUE_GENERIC_TYPE> iterator() { return ((MAP.FastEntrySet KEY_VALUE_GENERIC_TYPE)entries).fastIterator(); }
@Override
public void forEach(Consumer<? super MAP.Entry KEY_VALUE_GENERIC_TYPE> action) { ((MAP.FastEntrySet KEY_VALUE_GENERIC_TYPE)entries).fastForEach(action); }
} : entries;
}
public static GENERIC_KEY_VALUE_BRACES void fastForEach(MAP KEY_VALUE_GENERIC_TYPE map, Consumer<MAP.Entry KEY_VALUE_GENERIC_TYPE> action) {
ObjectSet<MAP.Entry KEY_VALUE_GENERIC_TYPE> entries = map.ENTRY_SET();
if(entries instanceof MAP.FastEntrySet) ((MAP.FastEntrySet KEY_VALUE_GENERIC_TYPE)entries).fastForEach(action);
else entries.forEach(action);
}
}