Finished first loop of JavaDoc generation.

-Fixed: A couple bugs that were found during javadoc generation.

Next loop of javadoc comes later right now i want to add splititerators
and streams
This commit is contained in:
Speiger 2021-04-26 22:25:09 +02:00
parent f7d311fd09
commit a9a38f7853
22 changed files with 1173 additions and 212 deletions

View File

@ -430,7 +430,7 @@ public class CUSTOM_HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VAL
#if !TYPE_OBJECT #if !TYPE_OBJECT
protected int findIndex(KEY_TYPE key) { protected int findIndex(KEY_TYPE key) {
if(KEY_EQUALS_NULL(key)) return containsNull ? nullIndex : -(nullIndex + 1); if(strategy.equals(key, EMPTY_KEY_VALUE)) return containsNull ? nullIndex : -(nullIndex + 1);
int pos = HashUtil.mix(strategy.hashCode(key)) & mask; int pos = HashUtil.mix(strategy.hashCode(key)) & mask;
KEY_TYPE current = keys[pos]; KEY_TYPE current = keys[pos];
if(!strategy.equals(current, EMPTY_KEY_VALUE)) { if(!strategy.equals(current, EMPTY_KEY_VALUE)) {

View File

@ -43,7 +43,7 @@ import speiger.src.collections.objects.sets.ObjectSet;
* A Simple Type Specific AVL TreeMap implementation that reduces boxing/unboxing. * A Simple Type Specific AVL TreeMap implementation that reduces boxing/unboxing.
* It is using a bit more memory then <a href="https://github.com/vigna/fastutil">FastUtil</a>, * It is using a bit more memory then <a href="https://github.com/vigna/fastutil">FastUtil</a>,
* but it saves a lot of Performance on the Optimized removal and iteration logic. * but it saves a lot of Performance on the Optimized removal and iteration logic.
* Which makes the implementation actually useable and does not force to use Javas default implementation. * Which makes the implementation actually useable and does not get outperformed by Javas default implementation.
* @Type(T) * @Type(T)
* @ValueType(V) * @ValueType(V)
*/ */

View File

@ -43,7 +43,7 @@ import speiger.src.collections.objects.sets.ObjectSet;
* A Simple Type Specific RB TreeMap implementation that reduces boxing/unboxing. * A Simple Type Specific RB TreeMap implementation that reduces boxing/unboxing.
* It is using a bit more memory then <a href="https://github.com/vigna/fastutil">FastUtil</a>, * It is using a bit more memory then <a href="https://github.com/vigna/fastutil">FastUtil</a>,
* but it saves a lot of Performance on the Optimized removal and iteration logic. * but it saves a lot of Performance on the Optimized removal and iteration logic.
* Which makes the implementation actually useable and does not force to use Javas default implementation. * Which makes the implementation actually useable and does not get outperformed by Javas default implementation.
* @Type(T) * @Type(T)
* @ValueType(V) * @ValueType(V)
*/ */

View File

@ -18,74 +18,141 @@ import speiger.src.collections.PACKAGE.utils.ITERATORS;
#endif #endif
import speiger.src.collections.utils.SanityChecks; import speiger.src.collections.utils.SanityChecks;
/**
* A Simple Type Specific AVL TreeSet implementation that reduces boxing/unboxing.
* It is using a bit more memory then <a href="https://github.com/vigna/fastutil">FastUtil</a>,
* but it saves a lot of Performance on the Optimized removal and iteration logic.
* Which makes the implementation actually useable and does not get outperformed by Javas default implementation.
* @Type(T)
*/
public class AVL_TREE_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_TYPE implements NAVIGABLE_SET KEY_GENERIC_TYPE public class AVL_TREE_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_TYPE implements NAVIGABLE_SET KEY_GENERIC_TYPE
{ {
/** The center of the Tree */
protected transient Entry KEY_GENERIC_TYPE tree; protected transient Entry KEY_GENERIC_TYPE tree;
/** The Lowest possible Node */
protected transient Entry KEY_GENERIC_TYPE first; protected transient Entry KEY_GENERIC_TYPE first;
/** The Highest possible Node */
protected transient Entry KEY_GENERIC_TYPE last; protected transient Entry KEY_GENERIC_TYPE last;
/** The amount of elements stored in the Set */
protected int size = 0; protected int size = 0;
/** The Sorter of the Tree */
protected transient COMPARATOR KEY_GENERIC_TYPE comparator; protected transient COMPARATOR KEY_GENERIC_TYPE comparator;
#if !TYPE_OBJECT #if !TYPE_OBJECT
#if TYPE_BOOLEAN /** the default return value for max searches */
protected KEY_TYPE defaultMaxNotFound = CLASS_TYPE.FALSE;
protected KEY_TYPE defaultMinNotFound = CLASS_TYPE.TRUE;
#else
protected KEY_TYPE defaultMaxNotFound = CLASS_TYPE.MIN_VALUE; protected KEY_TYPE defaultMaxNotFound = CLASS_TYPE.MIN_VALUE;
/** the default return value for min searches */
protected KEY_TYPE defaultMinNotFound = CLASS_TYPE.MAX_VALUE; protected KEY_TYPE defaultMinNotFound = CLASS_TYPE.MAX_VALUE;
#endif
#endif #endif
/**
* Default Constructor
*/
public AVL_TREE_SET() { public AVL_TREE_SET() {
} }
/**
* Constructor that allows to define the sorter
* @param comp the function that decides how the tree is sorted, can be null
*/
public AVL_TREE_SET(COMPARATOR KEY_GENERIC_TYPE comp) { public AVL_TREE_SET(COMPARATOR KEY_GENERIC_TYPE comp) {
comparator = comp; comparator = comp;
} }
/**
* Helper constructor that allow to create a set from an array
* @param array the elements that should be used
*/
public AVL_TREE_SET(KEY_TYPE[] array) { public AVL_TREE_SET(KEY_TYPE[] array) {
this(array, 0, array.length); this(array, 0, array.length);
} }
/**
* Helper constructor that allow to create a set from an array
* @param array the elements that should be used
* @param offset the starting index within the array
* @param length the amount of elements that are within the array
* @throws IllegalStateException if offset and length causes to step outside of the arrays range
*/
public AVL_TREE_SET(KEY_TYPE[] array, int offset, int length) { public AVL_TREE_SET(KEY_TYPE[] array, int offset, int length) {
SanityChecks.checkArrayCapacity(array.length, offset, length); SanityChecks.checkArrayCapacity(array.length, offset, length);
for(int i = 0;i<length;i++) add(array[offset+i]); for(int i = 0;i<length;i++) add(array[offset+i]);
} }
/**
* Helper constructor that allow to create a set from an array
* @param array the elements that should be used
* @param comp the sorter of the tree, can be null
*/
public AVL_TREE_SET(KEY_TYPE[] array, COMPARATOR KEY_GENERIC_TYPE comp) { public AVL_TREE_SET(KEY_TYPE[] array, COMPARATOR KEY_GENERIC_TYPE comp) {
this(array, 0, array.length, comp); this(array, 0, array.length, comp);
} }
/**
* Helper constructor that allow to create a set from an array
* @param array the elements that should be used
* @param offset the starting index within the array
* @param length the amount of elements that are within the array
* @param comp the sorter of the tree, can be null
* @throws IllegalStateException if offset and length causes to step outside of the arrays range
*/
public AVL_TREE_SET(KEY_TYPE[] array, int offset, int length, COMPARATOR KEY_GENERIC_TYPE comp) { public AVL_TREE_SET(KEY_TYPE[] array, int offset, int length, COMPARATOR KEY_GENERIC_TYPE comp) {
comparator = comp; comparator = comp;
SanityChecks.checkArrayCapacity(array.length, offset, length); SanityChecks.checkArrayCapacity(array.length, offset, length);
for(int i = 0;i<length;i++) add(array[offset+i]); for(int i = 0;i<length;i++) add(array[offset+i]);
} }
/**
* A Helper constructor that allows to create a Set with exactly the same values as the provided SortedSet.
* @param sortedSet the set the elements should be added to the TreeSet
* @note this also includes the Comparator if present
*/
public AVL_TREE_SET(SORTED_SET KEY_GENERIC_TYPE sortedSet) { public AVL_TREE_SET(SORTED_SET KEY_GENERIC_TYPE sortedSet) {
comparator = sortedSet.comparator(); comparator = sortedSet.comparator();
addAll(sortedSet); addAll(sortedSet);
} }
/**
* A Helper constructor that allows to create a Set with exactly the same values as the provided collection.
* @param collection the set the elements should be added to the TreeSet
*/
@Deprecated @Deprecated
public AVL_TREE_SET(Collection<? extends CLASS_TYPE> collection) { public AVL_TREE_SET(Collection<? extends CLASS_TYPE> collection) {
addAll(collection); addAll(collection);
} }
/**
* A Helper constructor that allows to create a Set with exactly the same values as the provided collection.
* @param collection the set the elements should be added to the TreeSet
* @param comp the sorter of the tree, can be null
*/
@Deprecated @Deprecated
public AVL_TREE_SET(Collection<? extends CLASS_TYPE> collection, COMPARATOR KEY_GENERIC_TYPE comp) { public AVL_TREE_SET(Collection<? extends CLASS_TYPE> collection, COMPARATOR KEY_GENERIC_TYPE comp) {
comparator = comp; comparator = comp;
addAll(collection); addAll(collection);
} }
/**
* A Helper constructor that allows to create a Set with exactly the same values as the provided collection.
* @param collection the set the elements should be added to the TreeSet
*/
public AVL_TREE_SET(COLLECTION KEY_GENERIC_TYPE collection) { public AVL_TREE_SET(COLLECTION KEY_GENERIC_TYPE collection) {
addAll(collection); addAll(collection);
} }
/**
* A Helper constructor that allows to create a Set with exactly the same values as the provided collection.
* @param collection the set the elements should be added to the TreeSet
* @param comp the sorter of the tree, can be null
*/
public AVL_TREE_SET(COLLECTION KEY_GENERIC_TYPE collection, COMPARATOR KEY_GENERIC_TYPE comp) { public AVL_TREE_SET(COLLECTION KEY_GENERIC_TYPE collection, COMPARATOR KEY_GENERIC_TYPE comp) {
comparator = comp; comparator = comp;
addAll(collection); addAll(collection);
} }
/**
* A Helper constructor that allows to create a set from a iterator of an unknown size
* @param iterator the elements that should be added to the set
*/
public AVL_TREE_SET(Iterator<CLASS_TYPE> iterator) { public AVL_TREE_SET(Iterator<CLASS_TYPE> iterator) {
#if !TYPE_OBJECT #if !TYPE_OBJECT
this(ITERATORS.wrap(iterator)); this(ITERATORS.wrap(iterator));
@ -94,6 +161,11 @@ public class AVL_TREE_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_TYPE
#endif #endif
} }
/**
* A Helper constructor that allows to create a set from a iterator of an unknown size
* @param iterator the elements that should be added to the set
* @param comp the sorter of the tree, can be null
*/
public AVL_TREE_SET(Iterator<CLASS_TYPE> iterator, COMPARATOR KEY_GENERIC_TYPE comp) { public AVL_TREE_SET(Iterator<CLASS_TYPE> iterator, COMPARATOR KEY_GENERIC_TYPE comp) {
#if !TYPE_OBJECT #if !TYPE_OBJECT
this(ITERATORS.wrap(iterator), comp); this(ITERATORS.wrap(iterator), comp);
@ -103,10 +175,19 @@ public class AVL_TREE_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_TYPE
#endif #endif
} }
/**
* A Helper constructor that allows to create a set from a iterator of an unknown size
* @param iterator the elements that should be added to the set
*/
public AVL_TREE_SET(ITERATOR KEY_GENERIC_TYPE iterator) { public AVL_TREE_SET(ITERATOR KEY_GENERIC_TYPE iterator) {
while(iterator.hasNext()) add(iterator.NEXT()); while(iterator.hasNext()) add(iterator.NEXT());
} }
/**
* A Helper constructor that allows to create a set from a iterator of an unknown size
* @param iterator the elements that should be added to the set
* @param comp the sorter of the tree, can be null
*/
public AVL_TREE_SET(ITERATOR KEY_GENERIC_TYPE iterator, COMPARATOR KEY_GENERIC_TYPE comp) { public AVL_TREE_SET(ITERATOR KEY_GENERIC_TYPE iterator, COMPARATOR KEY_GENERIC_TYPE comp) {
comparator = comp; comparator = comp;
while(iterator.hasNext()) add(iterator.NEXT()); while(iterator.hasNext()) add(iterator.NEXT());

View File

@ -15,6 +15,7 @@ import java.util.function.JAVA_PREDICATE;
import speiger.src.collections.PACKAGE.collections.BI_ITERATOR; import speiger.src.collections.PACKAGE.collections.BI_ITERATOR;
import speiger.src.collections.PACKAGE.collections.COLLECTION; import speiger.src.collections.PACKAGE.collections.COLLECTION;
import speiger.src.collections.PACKAGE.collections.ITERATOR;
#if !TYPE_OBJECT #if !TYPE_OBJECT
import speiger.src.collections.PACKAGE.functions.COMPARATOR; import speiger.src.collections.PACKAGE.functions.COMPARATOR;
import speiger.src.collections.PACKAGE.functions.CONSUMER; import speiger.src.collections.PACKAGE.functions.CONSUMER;
@ -22,39 +23,81 @@ import speiger.src.collections.PACKAGE.functions.CONSUMER;
import speiger.src.collections.PACKAGE.lists.LIST_ITERATOR; import speiger.src.collections.PACKAGE.lists.LIST_ITERATOR;
import speiger.src.collections.PACKAGE.utils.ARRAYS; import speiger.src.collections.PACKAGE.utils.ARRAYS;
/**
* A Type Specific ArraySet implementation.
* That is based around the idea of {@link java.util.List#indexOf(Object)} for no duplication.
* Unless a array constructor is used the ArraySet does not allow for duplication.
* This implementation does not shrink the backing array
* @Type(T)
*/
public class ARRAY_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_TYPE implements SORTED_SET KEY_GENERIC_TYPE public class ARRAY_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_TYPE implements SORTED_SET KEY_GENERIC_TYPE
{ {
/** The Backing Array */
protected transient KEY_TYPE[] data; protected transient KEY_TYPE[] data;
/** The amount of elements stored in the array*/
protected int size = 0; protected int size = 0;
/**
* Default Constructor
*/
public ARRAY_SET() { public ARRAY_SET() {
data = EMPTY_KEY_ARRAY; data = EMPTY_KEY_ARRAY;
} }
/**
* Minimum Capacity Constructor
* @param capacity the minimum capacity of the internal array
* @throws NegativeArraySizeException if the capacity is negative
*/
public ARRAY_SET(int capacity) { public ARRAY_SET(int capacity) {
data = NEW_KEY_ARRAY(capacity); data = NEW_KEY_ARRAY(capacity);
} }
/**
* Constructur using initial Array
* @param array the array that should be used for set.
*/
public ARRAY_SET(KEY_TYPE[] array) { public ARRAY_SET(KEY_TYPE[] array) {
this(array, array.length); this(array, array.length);
} }
/**
* Constructur using initial Array
* @param array the array that should be used for set.
* @param length the amount of elements present within the array
* @throws NegativeArraySizeException if the length is negative
*/
public ARRAY_SET(KEY_TYPE[] array, int length) { public ARRAY_SET(KEY_TYPE[] array, int length) {
data = Arrays.copyOf(array, length); data = Arrays.copyOf(array, length);
size = length; size = length;
} }
/**
* A Helper constructor that allows to create a Set with exactly the same values as the provided collection.
* @param c the elements that should be added to the set.
* @note this slowly checks every element to remove duplicates
*/
@Deprecated @Deprecated
public ARRAY_SET(Collection<? extends CLASS_TYPE> c) { public ARRAY_SET(Collection<? extends CLASS_TYPE> c) {
this(c.size()); this(c.size());
addAll(c); addAll(c);
} }
/**
* A Helper constructor that allows to create a Set with exactly the same values as the provided collection.
* @param c the elements that should be added to the set.
* @note this slowly checks every element to remove duplicates
*/
public ARRAY_SET(COLLECTION KEY_GENERIC_TYPE c) { public ARRAY_SET(COLLECTION KEY_GENERIC_TYPE c) {
this(c.size()); this(c.size());
addAll(c); addAll(c);
} }
/**
* A Helper constructor that fast copies the element out of a set into the ArraySet.
* Since it is assumed that there is no duplication in the first place
* @param s the set the element should be taken from
*/
@Deprecated @Deprecated
public ARRAY_SET(Set<? extends CLASS_TYPE> s) { public ARRAY_SET(Set<? extends CLASS_TYPE> s) {
this(s.size()); this(s.size());
@ -62,10 +105,14 @@ public class ARRAY_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_TYPE im
data[size++] = OBJ_TO_KEY(e); data[size++] = OBJ_TO_KEY(e);
} }
/**
* A Helper constructor that fast copies the element out of a set into the ArraySet.
* Since it is assumed that there is no duplication in the first place
* @param s the set the element should be taken from
*/
public ARRAY_SET(SET KEY_GENERIC_TYPE s) { public ARRAY_SET(SET KEY_GENERIC_TYPE s) {
this(s.size()); this(s.size());
for(KEY_TYPE e : s) for(ITERATOR KEY_GENERIC_TYPE iter = s.iterator();iter.hasNext();data[size++] = iter.NEXT());
data[size++] = e;
} }
@Override @Override

View File

@ -23,67 +23,173 @@ import speiger.src.collections.PACKAGE.utils.STRATEGY;
import speiger.src.collections.utils.HashUtil; import speiger.src.collections.utils.HashUtil;
import speiger.src.collections.utils.SanityChecks; import speiger.src.collections.utils.SanityChecks;
/**
* A Type Specific LinkedHashSet that allows for custom HashControl. That uses arrays to create links between nodes.
* For cases where Objects/primitive do not allow hashcoding this can be really useful and provide a lot of control.
* This implementation of SortedSet does not support SubSet of any kind. It implements the interface due to sortability and first/last access
* @Type(T)
*/
public class LINKED_CUSTOM_HASH_SET KEY_GENERIC_TYPE extends CUSTOM_HASH_SET KEY_GENERIC_TYPE implements SORTED_SET KEY_GENERIC_TYPE 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; /** The Backing array for links between nodes. Left 32 Bits => Previous Entry, Right 32 Bits => Next Entry */
protected transient long[] links;
/** The First Index in the Map */
protected int firstIndex = -1; protected int firstIndex = -1;
/** The Last Index in the Map */
protected int lastIndex = -1; protected int lastIndex = -1;
/**
* Default Contstructor
* @param strategy the strategy that allows hash control.
* @throws NullPointerException if Strategy is null
*/
public LINKED_CUSTOM_HASH_SET(STRATEGY KEY_SUPER_GENERIC_TYPE strategy) { public LINKED_CUSTOM_HASH_SET(STRATEGY KEY_SUPER_GENERIC_TYPE strategy) {
this(HashUtil.DEFAULT_MIN_CAPACITY, HashUtil.DEFAULT_LOAD_FACTOR, strategy); this(HashUtil.DEFAULT_MIN_CAPACITY, HashUtil.DEFAULT_LOAD_FACTOR, strategy);
} }
/**
* Constructor that defines the minimum capacity
* @param minCapacity the minimum capacity the HashSet is allowed to be.
* @param strategy the strategy that allows hash control.
* @throws NullPointerException if Strategy is null
* @throws IllegalStateException if the minimum capacity is negative
*/
public LINKED_CUSTOM_HASH_SET(int minCapacity, STRATEGY KEY_SUPER_GENERIC_TYPE strategy) { public LINKED_CUSTOM_HASH_SET(int minCapacity, STRATEGY KEY_SUPER_GENERIC_TYPE strategy) {
this(minCapacity, HashUtil.DEFAULT_LOAD_FACTOR, strategy); this(minCapacity, HashUtil.DEFAULT_LOAD_FACTOR, strategy);
} }
/**
* Constructor that defines the minimum capacity and load factor
* @param minCapacity the minimum capacity the HashSet is allowed to be.
* @param loadFactor the percentage of how full the backing array can be before they resize
* @param strategy the strategy that allows hash control.
* @throws NullPointerException if Strategy is null
* @throws IllegalStateException if the minimum capacity is negative
* @throws IllegalStateException if the loadfactor is either below/equal to 0 or above/equal to 1
*/
public LINKED_CUSTOM_HASH_SET(int minCapacity, float loadFactor, STRATEGY KEY_SUPER_GENERIC_TYPE strategy) { public LINKED_CUSTOM_HASH_SET(int minCapacity, float loadFactor, STRATEGY KEY_SUPER_GENERIC_TYPE strategy) {
super(minCapacity, loadFactor, strategy); super(minCapacity, loadFactor, strategy);
links = new long[nullIndex + 1]; links = new long[nullIndex + 1];
} }
/**
* Helper constructor that allow to create a set from unboxed values
* @param array the elements that should be put into the set
* @param strategy the strategy that allows hash control.
* @throws NullPointerException if Strategy is null
*/
public LINKED_CUSTOM_HASH_SET(KEY_TYPE[] array, STRATEGY KEY_SUPER_GENERIC_TYPE strategy) { public LINKED_CUSTOM_HASH_SET(KEY_TYPE[] array, STRATEGY KEY_SUPER_GENERIC_TYPE strategy) {
this(array, 0, array.length, HashUtil.DEFAULT_LOAD_FACTOR, strategy); this(array, 0, array.length, HashUtil.DEFAULT_LOAD_FACTOR, strategy);
} }
/**
* Helper constructor that allow to create a set from unboxed values
* @param array the elements that should be put into the set
* @param loadFactor the percentage of how full the backing array can be before they resize
* @param strategy the strategy that allows hash control.
* @throws NullPointerException if Strategy is null
* @throws IllegalStateException if the loadfactor is either below/equal to 0 or above/equal to 1
*/
public LINKED_CUSTOM_HASH_SET(KEY_TYPE[] array, float loadFactor, STRATEGY KEY_SUPER_GENERIC_TYPE strategy) { public LINKED_CUSTOM_HASH_SET(KEY_TYPE[] array, float loadFactor, STRATEGY KEY_SUPER_GENERIC_TYPE strategy) {
this(array, 0, array.length, loadFactor, strategy); this(array, 0, array.length, loadFactor, strategy);
} }
/**
* Helper constructor that allow to create a set from unboxed values
* @param array the elements that should be put into the set
* @param offset the starting index within the array that should be used
* @param length the amount of elements used from the array
* @param strategy the strategy that allows hash control.
* @throws NullPointerException if Strategy is null
* @throws IllegalStateException if offset and length causes to step outside of the arrays range
*/
public LINKED_CUSTOM_HASH_SET(KEY_TYPE[] array, int offset, int length, STRATEGY KEY_SUPER_GENERIC_TYPE 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); this(array, offset, length, HashUtil.DEFAULT_LOAD_FACTOR, strategy);
} }
/**
* Helper constructor that allow to create a set from unboxed values
* @param array the elements that should be put into the set
* @param offset the starting index within the array that should be used
* @param length the amount of elements used from the array
* @param loadFactor the percentage of how full the backing array can be before they resize
* @param strategy the strategy that allows hash control.
* @throws NullPointerException if Strategy is null
* @throws IllegalStateException if the loadfactor is either below/equal to 0 or above/equal to 1
* @throws IllegalStateException if offset and length causes to step outside of the arrays range
*/
public LINKED_CUSTOM_HASH_SET(KEY_TYPE[] array, int offset, int length, float loadFactor, STRATEGY KEY_SUPER_GENERIC_TYPE 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); this(length < 0 ? 0 : length, strategy);
SanityChecks.checkArrayCapacity(array.length, offset, length); SanityChecks.checkArrayCapacity(array.length, offset, length);
for(int i = 0;i<length;i++) add(array[offset+i]); for(int i = 0;i<length;i++) add(array[offset+i]);
} }
/**
* A Helper constructor that allows to create a Set with exactly the same values as the provided collection.
* @param collection the set the elements should be added to the Set
* @param strategy the strategy that allows hash control.
* @throws NullPointerException if Strategy is null
*/
@Deprecated @Deprecated
public LINKED_CUSTOM_HASH_SET(Collection<? extends CLASS_TYPE> collection, STRATEGY KEY_SUPER_GENERIC_TYPE strategy) { public LINKED_CUSTOM_HASH_SET(Collection<? extends CLASS_TYPE> collection, STRATEGY KEY_SUPER_GENERIC_TYPE strategy) {
this(collection, HashUtil.DEFAULT_LOAD_FACTOR, strategy); this(collection, HashUtil.DEFAULT_LOAD_FACTOR, strategy);
} }
/**
* A Helper constructor that allows to create a Set with exactly the same values as the provided collection.
* @param collection the set the elements should be added to the Set
* @param loadFactor the percentage of how full the backing array can be before they resize
* @param strategy the strategy that allows hash control.
* @throws NullPointerException if Strategy is null
* @throws IllegalStateException if the loadfactor is either below/equal to 0 or above/equal to 1
*/
@Deprecated @Deprecated
public LINKED_CUSTOM_HASH_SET(Collection<? extends CLASS_TYPE> collection, float loadFactor, STRATEGY KEY_SUPER_GENERIC_TYPE strategy) { public LINKED_CUSTOM_HASH_SET(Collection<? extends CLASS_TYPE> collection, float loadFactor, STRATEGY KEY_SUPER_GENERIC_TYPE strategy) {
this(collection.size(), loadFactor, strategy); this(collection.size(), loadFactor, strategy);
addAll(collection); addAll(collection);
} }
/**
* A Helper constructor that allows to create a Set with exactly the same values as the provided collection.
* @param collection the set the elements should be added to the Set
* @param strategy the strategy that allows hash control.
* @throws NullPointerException if Strategy is null
*/
public LINKED_CUSTOM_HASH_SET(COLLECTION KEY_GENERIC_TYPE collection, STRATEGY KEY_SUPER_GENERIC_TYPE strategy) { public LINKED_CUSTOM_HASH_SET(COLLECTION KEY_GENERIC_TYPE collection, STRATEGY KEY_SUPER_GENERIC_TYPE strategy) {
this(collection, HashUtil.DEFAULT_LOAD_FACTOR, strategy); this(collection, HashUtil.DEFAULT_LOAD_FACTOR, strategy);
} }
/**
* A Helper constructor that allows to create a Set with exactly the same values as the provided collection.
* @param collection the set the elements should be added to the Set
* @param loadFactor the percentage of how full the backing array can be before they resize
* @param strategy the strategy that allows hash control.
* @throws NullPointerException if Strategy is null
* @throws IllegalStateException if the loadfactor is either below/equal to 0 or above/equal to 1
*/
public LINKED_CUSTOM_HASH_SET(COLLECTION KEY_GENERIC_TYPE collection, float loadFactor, STRATEGY KEY_SUPER_GENERIC_TYPE strategy) { public LINKED_CUSTOM_HASH_SET(COLLECTION KEY_GENERIC_TYPE collection, float loadFactor, STRATEGY KEY_SUPER_GENERIC_TYPE strategy) {
this(collection.size(), strategy); this(collection.size(), strategy);
addAll(collection); addAll(collection);
} }
/**
* A Helper constructor that allows to create a set from a iterator of an unknown size
* @param iterator the elements that should be added to the set
* @param strategy the strategy that allows hash control.
* @throws NullPointerException if Strategy is null
*/
public LINKED_CUSTOM_HASH_SET(Iterator<CLASS_TYPE> iterator, STRATEGY KEY_SUPER_GENERIC_TYPE strategy) { public LINKED_CUSTOM_HASH_SET(Iterator<CLASS_TYPE> iterator, STRATEGY KEY_SUPER_GENERIC_TYPE strategy) {
this(iterator, HashUtil.DEFAULT_LOAD_FACTOR, strategy); this(iterator, HashUtil.DEFAULT_LOAD_FACTOR, strategy);
} }
/**
* A Helper constructor that allows to create a set from a iterator of an unknown size
* @param iterator the elements that should be added to the set
* @param loadFactor the percentage of how full the backing array can be before they resize
* @param strategy the strategy that allows hash control.
* @throws NullPointerException if Strategy is null
* @throws IllegalStateException if the loadfactor is either below/equal to 0 or above/equal to 1
*/
public LINKED_CUSTOM_HASH_SET(Iterator<CLASS_TYPE> iterator, float loadFactor, STRATEGY KEY_SUPER_GENERIC_TYPE strategy) { public LINKED_CUSTOM_HASH_SET(Iterator<CLASS_TYPE> iterator, float loadFactor, STRATEGY KEY_SUPER_GENERIC_TYPE strategy) {
#if !TYPE_OBJECT #if !TYPE_OBJECT
this(ITERATORS.wrap(iterator), loadFactor, strategy); this(ITERATORS.wrap(iterator), loadFactor, strategy);
@ -94,10 +200,24 @@ public class LINKED_CUSTOM_HASH_SET KEY_GENERIC_TYPE extends CUSTOM_HASH_SET KEY
} }
#if !TYPE_OBJECT #if !TYPE_OBJECT
/**
* A Helper constructor that allows to create a set from a iterator of an unknown size
* @param iterator the elements that should be added to the set
* @param strategy the strategy that allows hash control.
* @throws NullPointerException if Strategy is null
*/
public LINKED_CUSTOM_HASH_SET(ITERATOR KEY_GENERIC_TYPE iterator, STRATEGY KEY_SUPER_GENERIC_TYPE strategy) { public LINKED_CUSTOM_HASH_SET(ITERATOR KEY_GENERIC_TYPE iterator, STRATEGY KEY_SUPER_GENERIC_TYPE strategy) {
this(iterator, HashUtil.DEFAULT_LOAD_FACTOR, strategy); this(iterator, HashUtil.DEFAULT_LOAD_FACTOR, strategy);
} }
/**
* A Helper constructor that allows to create a set from a iterator of an unknown size
* @param iterator the elements that should be added to the set
* @param loadFactor the percentage of how full the backing array can be before they resize
* @param strategy the strategy that allows hash control.
* @throws NullPointerException if Strategy is null
* @throws IllegalStateException if the loadfactor is either below/equal to 0 or above/equal to 1
*/
public LINKED_CUSTOM_HASH_SET(ITERATOR KEY_GENERIC_TYPE iterator, float loadFactor, STRATEGY KEY_SUPER_GENERIC_TYPE 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); this(HashUtil.DEFAULT_MIN_CAPACITY, loadFactor, strategy);
while(iterator.hasNext()) add(iterator.NEXT()); while(iterator.hasNext()) add(iterator.NEXT());

View File

@ -25,67 +25,147 @@ import speiger.src.collections.PACKAGE.utils.ITERATORS;
import speiger.src.collections.utils.HashUtil; import speiger.src.collections.utils.HashUtil;
import speiger.src.collections.utils.SanityChecks; import speiger.src.collections.utils.SanityChecks;
/**
* A Type Specific LinkedHashMap implementation that uses specific arrays to create links between nodes to remove the wrapping of elements
* to greatly reduce memory usage. In Addition adding some helper methods to move around elements.
* This implementation of SortedSet does not support SubSet of any kind. It implements the interface due to sortability and first/last access
* @Type(T)
*/
public class LINKED_HASH_SET KEY_GENERIC_TYPE extends HASH_SET KEY_GENERIC_TYPE implements SORTED_SET KEY_GENERIC_TYPE public class LINKED_HASH_SET KEY_GENERIC_TYPE extends HASH_SET KEY_GENERIC_TYPE implements SORTED_SET KEY_GENERIC_TYPE
{ {
protected long[] links; /** The Backing array for links between nodes. Left 32 Bits => Previous Entry, Right 32 Bits => Next Entry */
protected transient long[] links;
/** The First Index in the Map */
protected int firstIndex = -1; protected int firstIndex = -1;
/** The Last Index in the Map */
protected int lastIndex = -1; protected int lastIndex = -1;
/**
* Default Constructor
*/
public LINKED_HASH_SET() { public LINKED_HASH_SET() {
this(HashUtil.DEFAULT_MIN_CAPACITY, HashUtil.DEFAULT_LOAD_FACTOR); this(HashUtil.DEFAULT_MIN_CAPACITY, HashUtil.DEFAULT_LOAD_FACTOR);
} }
/**
* Constructor that defines the minimum capacity
* @param minCapacity the minimum capacity the HashSet is allowed to be.
* @throws IllegalStateException if the minimum capacity is negative
*/
public LINKED_HASH_SET(int minCapacity) { public LINKED_HASH_SET(int minCapacity) {
this(minCapacity, HashUtil.DEFAULT_LOAD_FACTOR); this(minCapacity, HashUtil.DEFAULT_LOAD_FACTOR);
} }
/**
* Constructor that defines the minimum capacity and load factor
* @param minCapacity the minimum capacity the HashSet is allowed to be.
* @param loadFactor the percentage of how full the backing array can be before they resize
* @throws IllegalStateException if the minimum capacity is negative
* @throws IllegalStateException if the loadfactor is either below/equal to 0 or above/equal to 1
*/
public LINKED_HASH_SET(int minCapacity, float loadFactor) { public LINKED_HASH_SET(int minCapacity, float loadFactor) {
super(minCapacity, loadFactor); super(minCapacity, loadFactor);
links = new long[nullIndex + 1]; links = new long[nullIndex + 1];
} }
/**
* Helper constructor that allow to create a set from unboxed values
* @param array the elements that should be put into the set
*/
public LINKED_HASH_SET(KEY_TYPE[] array) { public LINKED_HASH_SET(KEY_TYPE[] array) {
this(array, 0, array.length, HashUtil.DEFAULT_LOAD_FACTOR); this(array, 0, array.length, HashUtil.DEFAULT_LOAD_FACTOR);
} }
/**
* Helper constructor that allow to create a set from unboxed values
* @param array the elements that should be put into the set
* @param loadFactor the percentage of how full the backing array can be before they resize
* @throws IllegalStateException if the loadfactor is either below/equal to 0 or above/equal to 1
*/
public LINKED_HASH_SET(KEY_TYPE[] array, float loadFactor) { public LINKED_HASH_SET(KEY_TYPE[] array, float loadFactor) {
this(array, 0, array.length, loadFactor); this(array, 0, array.length, loadFactor);
} }
/**
* Helper constructor that allow to create a set from unboxed values
* @param array the elements that should be put into the set
* @param offset the starting index within the array that should be used
* @param length the amount of elements used from the array
* @throws IllegalStateException if offset and length causes to step outside of the arrays range
*/
public LINKED_HASH_SET(KEY_TYPE[] array, int offset, int length) { public LINKED_HASH_SET(KEY_TYPE[] array, int offset, int length) {
this(array, offset, length, HashUtil.DEFAULT_LOAD_FACTOR); this(array, offset, length, HashUtil.DEFAULT_LOAD_FACTOR);
} }
/**
* Helper constructor that allow to create a set from unboxed values
* @param array the elements that should be put into the set
* @param offset the starting index within the array that should be used
* @param length the amount of elements used from the array
* @param loadFactor the percentage of how full the backing array can be before they resize
* @throws IllegalStateException if the loadfactor is either below/equal to 0 or above/equal to 1
* @throws IllegalStateException if offset and length causes to step outside of the arrays range
*/
public LINKED_HASH_SET(KEY_TYPE[] array, int offset, int length, float loadFactor) { public LINKED_HASH_SET(KEY_TYPE[] array, int offset, int length, float loadFactor) {
this(length < 0 ? 0 : length); this(length < 0 ? 0 : length);
SanityChecks.checkArrayCapacity(array.length, offset, length); SanityChecks.checkArrayCapacity(array.length, offset, length);
for(int i = 0;i<length;i++) add(array[offset+i]); for(int i = 0;i<length;i++) add(array[offset+i]);
} }
/**
* A Helper constructor that allows to create a Set with exactly the same values as the provided collection.
* @param collection the set the elements should be added to the Set
*/
@Deprecated @Deprecated
public LINKED_HASH_SET(Collection<? extends CLASS_TYPE> collection) { public LINKED_HASH_SET(Collection<? extends CLASS_TYPE> collection) {
this(collection, HashUtil.DEFAULT_LOAD_FACTOR); this(collection, HashUtil.DEFAULT_LOAD_FACTOR);
} }
/**
* A Helper constructor that allows to create a Set with exactly the same values as the provided collection.
* @param collection the set the elements should be added to the Set
* @param loadFactor the percentage of how full the backing array can be before they resize
* @throws IllegalStateException if the loadfactor is either below/equal to 0 or above/equal to 1
*/
@Deprecated @Deprecated
public LINKED_HASH_SET(Collection<? extends CLASS_TYPE> collection, float loadFactor) { public LINKED_HASH_SET(Collection<? extends CLASS_TYPE> collection, float loadFactor) {
this(collection.size(), loadFactor); this(collection.size(), loadFactor);
addAll(collection); addAll(collection);
} }
/**
* A Helper constructor that allows to create a Set with exactly the same values as the provided collection.
* @param collection the set the elements should be added to the Set
*/
public LINKED_HASH_SET(COLLECTION KEY_GENERIC_TYPE collection) { public LINKED_HASH_SET(COLLECTION KEY_GENERIC_TYPE collection) {
this(collection, HashUtil.DEFAULT_LOAD_FACTOR); this(collection, HashUtil.DEFAULT_LOAD_FACTOR);
} }
/**
* A Helper constructor that allows to create a Set with exactly the same values as the provided collection.
* @param collection the set the elements should be added to the Set
* @param loadFactor the percentage of how full the backing array can be before they resize
* @throws IllegalStateException if the loadfactor is either below/equal to 0 or above/equal to 1
*/
public LINKED_HASH_SET(COLLECTION KEY_GENERIC_TYPE collection, float loadFactor) { public LINKED_HASH_SET(COLLECTION KEY_GENERIC_TYPE collection, float loadFactor) {
this(collection.size()); this(collection.size());
addAll(collection); addAll(collection);
} }
/**
* A Helper constructor that allows to create a set from a iterator of an unknown size
* @param iterator the elements that should be added to the set
*/
public LINKED_HASH_SET(Iterator<CLASS_TYPE> iterator) { public LINKED_HASH_SET(Iterator<CLASS_TYPE> iterator) {
this(iterator, HashUtil.DEFAULT_LOAD_FACTOR); this(iterator, HashUtil.DEFAULT_LOAD_FACTOR);
} }
/**
* A Helper constructor that allows to create a set from a iterator of an unknown size
* @param iterator the elements that should be added to the set
* @param loadFactor the percentage of how full the backing array can be before they resize
* @throws IllegalStateException if the loadfactor is either below/equal to 0 or above/equal to 1
*/
public LINKED_HASH_SET(Iterator<CLASS_TYPE> iterator, float loadFactor) { public LINKED_HASH_SET(Iterator<CLASS_TYPE> iterator, float loadFactor) {
#if !TYPE_OBJECT #if !TYPE_OBJECT
this(ITERATORS.wrap(iterator), loadFactor); this(ITERATORS.wrap(iterator), loadFactor);
@ -96,10 +176,20 @@ public class LINKED_HASH_SET KEY_GENERIC_TYPE extends HASH_SET KEY_GENERIC_TYPE
} }
#if !TYPE_OBJECT #if !TYPE_OBJECT
/**
* A Helper constructor that allows to create a set from a iterator of an unknown size
* @param iterator the elements that should be added to the set
*/
public LINKED_HASH_SET(ITERATOR KEY_GENERIC_TYPE iterator) { public LINKED_HASH_SET(ITERATOR KEY_GENERIC_TYPE iterator) {
this(iterator, HashUtil.DEFAULT_LOAD_FACTOR); this(iterator, HashUtil.DEFAULT_LOAD_FACTOR);
} }
/**
* A Helper constructor that allows to create a set from a iterator of an unknown size
* @param iterator the elements that should be added to the set
* @param loadFactor the percentage of how full the backing array can be before they resize
* @throws IllegalStateException if the loadfactor is either below/equal to 0 or above/equal to 1
*/
public LINKED_HASH_SET(ITERATOR KEY_GENERIC_TYPE iterator, float loadFactor) { public LINKED_HASH_SET(ITERATOR KEY_GENERIC_TYPE iterator, float loadFactor) {
this(HashUtil.DEFAULT_MIN_CAPACITY, loadFactor); this(HashUtil.DEFAULT_MIN_CAPACITY, loadFactor);
while(iterator.hasNext()) add(iterator.NEXT()); while(iterator.hasNext()) add(iterator.NEXT());

View File

@ -4,66 +4,113 @@ import java.util.NavigableSet;
import speiger.src.collections.PACKAGE.collections.BI_ITERATOR; import speiger.src.collections.PACKAGE.collections.BI_ITERATOR;
/**
* A Type Specific Navigable Set interface with a couple helper methods
* @Type(T)
*/
public interface NAVIGABLE_SET KEY_GENERIC_TYPE extends NavigableSet<CLASS_TYPE>, SORTED_SET KEY_GENERIC_TYPE public interface NAVIGABLE_SET KEY_GENERIC_TYPE extends NavigableSet<CLASS_TYPE>, SORTED_SET KEY_GENERIC_TYPE
{ {
#if !TYPE_OBJECT #if !TYPE_OBJECT
public KEY_TYPE lower(KEY_TYPE e); /**
* A Type Specific lower method to reduce boxing/unboxing.
public KEY_TYPE floor(KEY_TYPE e); * @param key that should be compared with.
* @return the greatest lower key that can be found
public KEY_TYPE ceiling(KEY_TYPE e); */
public KEY_TYPE lower(KEY_TYPE key);
public KEY_TYPE higher(KEY_TYPE e); /**
* A Type Specific higher method to reduce boxing/unboxing.
* @param key that should be compared with.
* @return the lowest higher key that can be found
*/
public KEY_TYPE higher(KEY_TYPE key);
/**
* A Type Specific floor method to reduce boxing/unboxing.
* @param key that should be compared with.
* @return the greatest lower or equal key that can be found
*/
public KEY_TYPE floor(KEY_TYPE key);
/**
* A Type Specific ceiling method to reduce boxing/unboxing.
* @param key that should be compared with.
* @return the lowest higher or equal key that can be found
*/
public KEY_TYPE ceiling(KEY_TYPE key);
/**
* A Helper method to set the max value for SubSets. (Default: KEY_TYPE.MIN_VALUE)
* @param e the new max value
*/
public void setDefaultMaxValue(KEY_TYPE e); public void setDefaultMaxValue(KEY_TYPE e);
/**
* A Helper method to get the max value for SubSets.
* @return the default max value.
*/
public KEY_TYPE getDefaultMaxValue(); public KEY_TYPE getDefaultMaxValue();
/**
* A Helper method to set the min value for SubSets. (Default: KEY_TYPE.MAX_VALUE)
* @param e the new min value
*/
public void setDefaultMinValue(KEY_TYPE e); public void setDefaultMinValue(KEY_TYPE e);
/**
* A Helper method to get the min value for SubSets.
* @return the default min value.
*/
public KEY_TYPE getDefaultMinValue(); public KEY_TYPE getDefaultMinValue();
@Override @Override
public default NAVIGABLE_SET KEY_GENERIC_TYPE subSet(KEY_TYPE fromElement, KEY_TYPE toElement) { return subSet(fromElement, true, toElement, false); } public default NAVIGABLE_SET KEY_GENERIC_TYPE subSet(KEY_TYPE fromElement, KEY_TYPE toElement) { return subSet(fromElement, true, toElement, false); }
@Override @Override
public default NAVIGABLE_SET KEY_GENERIC_TYPE headSet(KEY_TYPE toElement) { return headSet(toElement, false); } public default NAVIGABLE_SET KEY_GENERIC_TYPE headSet(KEY_TYPE toElement) { return headSet(toElement, false); }
@Override @Override
public default NAVIGABLE_SET KEY_GENERIC_TYPE tailSet(KEY_TYPE fromElement) { return tailSet(fromElement, true); } public default NAVIGABLE_SET KEY_GENERIC_TYPE tailSet(KEY_TYPE fromElement) { return tailSet(fromElement, true); }
/**
* A Type Specific SubSet method to reduce boxing/unboxing
* @param fromElement where the SubSet should start
* @param fromInclusive if the fromElement is inclusive or not
* @param toElement where the SubSet should end
* @param toInclusive if the toElement is inclusive or not
* @return a SubSet that is within the range of the desired range
*/
public NAVIGABLE_SET KEY_GENERIC_TYPE subSet(KEY_TYPE fromElement, boolean fromInclusive, KEY_TYPE toElement, boolean toInclusive); public NAVIGABLE_SET KEY_GENERIC_TYPE subSet(KEY_TYPE fromElement, boolean fromInclusive, KEY_TYPE toElement, boolean toInclusive);
/**
* A Type Specific HeadSet method to reduce boxing/unboxing
* @param toElement where the HeadSet should end
* @param inclusive if the toElement is inclusive or not
* @return a HeadSet that is within the range of the desired range
*/
public NAVIGABLE_SET KEY_GENERIC_TYPE headSet(KEY_TYPE toElement, boolean inclusive); public NAVIGABLE_SET KEY_GENERIC_TYPE headSet(KEY_TYPE toElement, boolean inclusive);
/**
* A Type Specific TailSet method to reduce boxing/unboxing
* @param fromElement where the TailSet should start
* @param inclusive if the fromElement is inclusive or not
* @return a TailSet that is within the range of the desired range
*/
public NAVIGABLE_SET KEY_GENERIC_TYPE tailSet(KEY_TYPE fromElement, boolean inclusive); public NAVIGABLE_SET KEY_GENERIC_TYPE tailSet(KEY_TYPE fromElement, boolean inclusive);
#else #else
@Override @Override
public default NAVIGABLE_SET KEY_GENERIC_TYPE subSet(KEY_TYPE fromElement, KEY_TYPE toElement) { return subSet(fromElement, true, toElement, false); } public default NAVIGABLE_SET KEY_GENERIC_TYPE subSet(KEY_TYPE fromElement, KEY_TYPE toElement) { return subSet(fromElement, true, toElement, false); }
@Override @Override
public default NAVIGABLE_SET KEY_GENERIC_TYPE headSet(KEY_TYPE toElement) { return headSet(toElement, false); } public default NAVIGABLE_SET KEY_GENERIC_TYPE headSet(KEY_TYPE toElement) { return headSet(toElement, false); }
@Override @Override
public default NAVIGABLE_SET KEY_GENERIC_TYPE tailSet(KEY_TYPE fromElement) { return tailSet(fromElement, true); } public default NAVIGABLE_SET KEY_GENERIC_TYPE tailSet(KEY_TYPE fromElement) { return tailSet(fromElement, true); }
@Override @Override
public NAVIGABLE_SET KEY_GENERIC_TYPE subSet(KEY_TYPE fromElement, boolean fromInclusive, KEY_TYPE toElement, boolean toInclusive); public NAVIGABLE_SET KEY_GENERIC_TYPE subSet(KEY_TYPE fromElement, boolean fromInclusive, KEY_TYPE toElement, boolean toInclusive);
@Override @Override
public NAVIGABLE_SET KEY_GENERIC_TYPE headSet(KEY_TYPE toElement, boolean inclusive); public NAVIGABLE_SET KEY_GENERIC_TYPE headSet(KEY_TYPE toElement, boolean inclusive);
@Override @Override
public NAVIGABLE_SET KEY_GENERIC_TYPE tailSet(KEY_TYPE fromElement, boolean inclusive); public NAVIGABLE_SET KEY_GENERIC_TYPE tailSet(KEY_TYPE fromElement, boolean inclusive);
#endif #endif
/** @return a Type Specific iterator */
@Override @Override
public BI_ITERATOR KEY_GENERIC_TYPE iterator(); public BI_ITERATOR KEY_GENERIC_TYPE iterator();
/** @return a Type Specific desendingIterator */
@Override @Override
public BI_ITERATOR KEY_GENERIC_TYPE descendingIterator(); public BI_ITERATOR KEY_GENERIC_TYPE descendingIterator();
/** @return a Type Specific desendingSet */
@Override @Override
public NAVIGABLE_SET KEY_GENERIC_TYPE descendingSet(); public NAVIGABLE_SET KEY_GENERIC_TYPE descendingSet();
@ -71,31 +118,24 @@ public interface NAVIGABLE_SET KEY_GENERIC_TYPE extends NavigableSet<CLASS_TYPE>
@Override @Override
@Deprecated @Deprecated
public default CLASS_TYPE lower(CLASS_TYPE e) { return KEY_TO_OBJ(lower(OBJ_TO_KEY(e))); } public default CLASS_TYPE lower(CLASS_TYPE e) { return KEY_TO_OBJ(lower(OBJ_TO_KEY(e))); }
@Override @Override
@Deprecated @Deprecated
public default CLASS_TYPE floor(CLASS_TYPE e) { return KEY_TO_OBJ(floor(OBJ_TO_KEY(e))); } public default CLASS_TYPE floor(CLASS_TYPE e) { return KEY_TO_OBJ(floor(OBJ_TO_KEY(e))); }
@Override @Override
@Deprecated @Deprecated
public default CLASS_TYPE ceiling(CLASS_TYPE e) { return KEY_TO_OBJ(ceiling(OBJ_TO_KEY(e))); } public default CLASS_TYPE ceiling(CLASS_TYPE e) { return KEY_TO_OBJ(ceiling(OBJ_TO_KEY(e))); }
@Override @Override
@Deprecated @Deprecated
public default CLASS_TYPE higher(CLASS_TYPE e) { return KEY_TO_OBJ(higher(OBJ_TO_KEY(e))); } public default CLASS_TYPE higher(CLASS_TYPE e) { return KEY_TO_OBJ(higher(OBJ_TO_KEY(e))); }
@Override @Override
@Deprecated @Deprecated
default CLASS_TYPE first() { return SORTED_SET.super.first(); } default CLASS_TYPE first() { return SORTED_SET.super.first(); }
@Override @Override
@Deprecated @Deprecated
default CLASS_TYPE last() { return SORTED_SET.super.last(); } default CLASS_TYPE last() { return SORTED_SET.super.last(); }
@Override @Override
@Deprecated @Deprecated
public default CLASS_TYPE pollFirst() { return KEY_TO_OBJ(POLL_FIRST_KEY()); } public default CLASS_TYPE pollFirst() { return KEY_TO_OBJ(POLL_FIRST_KEY()); }
@Override @Override
@Deprecated @Deprecated
public default CLASS_TYPE pollLast() { return KEY_TO_OBJ(POLL_LAST_KEY()); } public default CLASS_TYPE pollLast() { return KEY_TO_OBJ(POLL_LAST_KEY()); }
@ -103,23 +143,18 @@ public interface NAVIGABLE_SET KEY_GENERIC_TYPE extends NavigableSet<CLASS_TYPE>
@Override @Override
@Deprecated @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); } 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 @Override
@Deprecated @Deprecated
public default NAVIGABLE_SET KEY_GENERIC_TYPE headSet(CLASS_TYPE toElement, boolean inclusive) { return headSet(OBJ_TO_KEY(toElement), inclusive); } public default NAVIGABLE_SET KEY_GENERIC_TYPE headSet(CLASS_TYPE toElement, boolean inclusive) { return headSet(OBJ_TO_KEY(toElement), inclusive); }
@Override @Override
@Deprecated @Deprecated
public default NAVIGABLE_SET KEY_GENERIC_TYPE tailSet(CLASS_TYPE fromElement, boolean inclusive) { return tailSet(OBJ_TO_KEY(fromElement), inclusive); } public default NAVIGABLE_SET KEY_GENERIC_TYPE tailSet(CLASS_TYPE fromElement, boolean inclusive) { return tailSet(OBJ_TO_KEY(fromElement), inclusive); }
@Override @Override
@Deprecated @Deprecated
public default SORTED_SET KEY_GENERIC_TYPE subSet(CLASS_TYPE fromElement, CLASS_TYPE toElement) { return SORTED_SET.super.subSet(fromElement, toElement); } public default SORTED_SET KEY_GENERIC_TYPE subSet(CLASS_TYPE fromElement, CLASS_TYPE toElement) { return SORTED_SET.super.subSet(fromElement, toElement); }
@Override @Override
@Deprecated @Deprecated
public default SORTED_SET KEY_GENERIC_TYPE headSet(CLASS_TYPE toElement) { return SORTED_SET.super.headSet(toElement); } public default SORTED_SET KEY_GENERIC_TYPE headSet(CLASS_TYPE toElement) { return SORTED_SET.super.headSet(toElement); }
@Override @Override
@Deprecated @Deprecated
public default SORTED_SET KEY_GENERIC_TYPE tailSet(CLASS_TYPE fromElement) { return SORTED_SET.super.tailSet(fromElement); } public default SORTED_SET KEY_GENERIC_TYPE tailSet(CLASS_TYPE fromElement) { return SORTED_SET.super.tailSet(fromElement); }

View File

@ -18,27 +18,62 @@ import speiger.src.collections.utils.HashUtil;
import speiger.src.collections.utils.ITrimmable; import speiger.src.collections.utils.ITrimmable;
import speiger.src.collections.utils.SanityChecks; import speiger.src.collections.utils.SanityChecks;
/**
* A Type Specific HashSet that allows for custom HashControl.
* For cases where Objects/primitive do not allow hashcoding this can be really useful and provide a lot of control.
* @Type(T)
*/
public class CUSTOM_HASH_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_TYPE implements ITrimmable public class CUSTOM_HASH_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_TYPE implements ITrimmable
{ {
/** The Backing keys array */
protected transient KEY_TYPE[] keys; protected transient KEY_TYPE[] keys;
/** If a null value is present */
protected transient boolean containsNull; protected transient boolean containsNull;
/** Minimum array size the HashSet will be */
protected transient int minCapacity; protected transient int minCapacity;
/** Index of the Null Value */
protected transient int nullIndex; protected transient int nullIndex;
/** Maximum amount of Values that can be stored before the array gets expanded usually 75% */
protected transient int maxFill; protected transient int maxFill;
/** Max Index that is allowed to be searched through nullIndex - 1 */
protected transient int mask; protected transient int mask;
/** Amount of Elements stored in the HashSet */
protected int size; protected int size;
/** How full the Array is allowed to get before resize */
protected final float loadFactor; protected final float loadFactor;
/** Strategy that allows to control the Hash Generation and equals comparason */
protected final STRATEGY KEY_SUPER_GENERIC_TYPE strategy; protected final STRATEGY KEY_SUPER_GENERIC_TYPE strategy;
/**
* Default Contstructor
* @param strategy the strategy that allows hash control.
* @throws NullPointerException if Strategy is null
*/
public CUSTOM_HASH_SET(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); this(HashUtil.DEFAULT_MIN_CAPACITY, HashUtil.DEFAULT_LOAD_FACTOR, strategy);
} }
/**
* Constructor that defines the minimum capacity
* @param minCapacity the minimum capacity the HashSet is allowed to be.
* @param strategy the strategy that allows hash control.
* @throws NullPointerException if Strategy is null
* @throws IllegalStateException if the minimum capacity is negative
*/
public CUSTOM_HASH_SET(int minCapacity, STRATEGY KEY_SUPER_GENERIC_TYPE strategy) { public CUSTOM_HASH_SET(int minCapacity, STRATEGY KEY_SUPER_GENERIC_TYPE strategy) {
this(minCapacity, HashUtil.DEFAULT_LOAD_FACTOR, strategy); this(minCapacity, HashUtil.DEFAULT_LOAD_FACTOR, strategy);
} }
/**
* Constructor that defines the minimum capacity and load factor
* @param minCapacity the minimum capacity the HashSet is allowed to be.
* @param loadFactor the percentage of how full the backing array can be before they resize
* @param strategy the strategy that allows hash control.
* @throws NullPointerException if Strategy is null
* @throws IllegalStateException if the minimum capacity is negative
* @throws IllegalStateException if the loadfactor is either below/equal to 0 or above/equal to 1
*/
public CUSTOM_HASH_SET(int minCapacity, float loadFactor, STRATEGY KEY_SUPER_GENERIC_TYPE 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(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"); if(loadFactor <= 0 || loadFactor >= 1F) throw new IllegalStateException("Load Factor is not between 0 and 1");
@ -50,48 +85,124 @@ public class CUSTOM_HASH_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_T
this.strategy = strategy; this.strategy = strategy;
} }
/**
* Helper constructor that allow to create a set from unboxed values
* @param array the elements that should be put into the set
* @param strategy the strategy that allows hash control.
* @throws NullPointerException if Strategy is null
*/
public CUSTOM_HASH_SET(KEY_TYPE[] array, STRATEGY KEY_SUPER_GENERIC_TYPE strategy) { public CUSTOM_HASH_SET(KEY_TYPE[] array, STRATEGY KEY_SUPER_GENERIC_TYPE strategy) {
this(array, 0, array.length, HashUtil.DEFAULT_LOAD_FACTOR, strategy); this(array, 0, array.length, HashUtil.DEFAULT_LOAD_FACTOR, strategy);
} }
/**
* Helper constructor that allow to create a set from unboxed values
* @param array the elements that should be put into the set
* @param loadFactor the percentage of how full the backing array can be before they resize
* @param strategy the strategy that allows hash control.
* @throws NullPointerException if Strategy is null
* @throws IllegalStateException if the loadfactor is either below/equal to 0 or above/equal to 1
*/
public CUSTOM_HASH_SET(KEY_TYPE[] array, float loadFactor, STRATEGY KEY_SUPER_GENERIC_TYPE strategy) { public CUSTOM_HASH_SET(KEY_TYPE[] array, float loadFactor, STRATEGY KEY_SUPER_GENERIC_TYPE strategy) {
this(array, 0, array.length, loadFactor, strategy); this(array, 0, array.length, loadFactor, strategy);
} }
/**
* Helper constructor that allow to create a set from unboxed values
* @param array the elements that should be put into the set
* @param offset the starting index within the array that should be used
* @param length the amount of elements used from the array
* @param strategy the strategy that allows hash control.
* @throws NullPointerException if Strategy is null
* @throws IllegalStateException if offset and length causes to step outside of the arrays range
*/
public CUSTOM_HASH_SET(KEY_TYPE[] array, int offset, int length, STRATEGY KEY_SUPER_GENERIC_TYPE 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); this(array, offset, length, HashUtil.DEFAULT_LOAD_FACTOR, strategy);
} }
/**
* Helper constructor that allow to create a set from unboxed values
* @param array the elements that should be put into the set
* @param offset the starting index within the array that should be used
* @param length the amount of elements used from the array
* @param loadFactor the percentage of how full the backing array can be before they resize
* @param strategy the strategy that allows hash control.
* @throws NullPointerException if Strategy is null
* @throws IllegalStateException if the loadfactor is either below/equal to 0 or above/equal to 1
* @throws IllegalStateException if offset and length causes to step outside of the arrays range
*/
public CUSTOM_HASH_SET(KEY_TYPE[] array, int offset, int length, float loadFactor, STRATEGY KEY_SUPER_GENERIC_TYPE 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); this(length < 0 ? 0 : length, strategy);
SanityChecks.checkArrayCapacity(array.length, offset, length); SanityChecks.checkArrayCapacity(array.length, offset, length);
for(int i = 0;i<length;i++) add(array[offset+i]); for(int i = 0;i<length;i++) add(array[offset+i]);
} }
/**
* A Helper constructor that allows to create a Set with exactly the same values as the provided collection.
* @param collection the set the elements should be added to the Set
* @param strategy the strategy that allows hash control.
* @throws NullPointerException if Strategy is null
*/
@Deprecated @Deprecated
public CUSTOM_HASH_SET(Collection<? extends CLASS_TYPE> collection, STRATEGY KEY_SUPER_GENERIC_TYPE strategy) { public CUSTOM_HASH_SET(Collection<? extends CLASS_TYPE> collection, STRATEGY KEY_SUPER_GENERIC_TYPE strategy) {
this(collection, HashUtil.DEFAULT_LOAD_FACTOR, strategy); this(collection, HashUtil.DEFAULT_LOAD_FACTOR, strategy);
} }
/**
* A Helper constructor that allows to create a Set with exactly the same values as the provided collection.
* @param collection the set the elements should be added to the Set
* @param loadFactor the percentage of how full the backing array can be before they resize
* @param strategy the strategy that allows hash control.
* @throws NullPointerException if Strategy is null
* @throws IllegalStateException if the loadfactor is either below/equal to 0 or above/equal to 1
*/
@Deprecated @Deprecated
public CUSTOM_HASH_SET(Collection<? extends CLASS_TYPE> collection, float loadFactor, STRATEGY KEY_SUPER_GENERIC_TYPE strategy) { public CUSTOM_HASH_SET(Collection<? extends CLASS_TYPE> collection, float loadFactor, STRATEGY KEY_SUPER_GENERIC_TYPE strategy) {
this(collection.size(), loadFactor, strategy); this(collection.size(), loadFactor, strategy);
addAll(collection); addAll(collection);
} }
/**
* A Helper constructor that allows to create a Set with exactly the same values as the provided collection.
* @param collection the set the elements should be added to the Set
* @param strategy the strategy that allows hash control.
* @throws NullPointerException if Strategy is null
*/
public CUSTOM_HASH_SET(COLLECTION KEY_GENERIC_TYPE collection, STRATEGY KEY_SUPER_GENERIC_TYPE strategy) { public CUSTOM_HASH_SET(COLLECTION KEY_GENERIC_TYPE collection, STRATEGY KEY_SUPER_GENERIC_TYPE strategy) {
this(collection, HashUtil.DEFAULT_LOAD_FACTOR, strategy); this(collection, HashUtil.DEFAULT_LOAD_FACTOR, strategy);
} }
/**
* A Helper constructor that allows to create a Set with exactly the same values as the provided collection.
* @param collection the set the elements should be added to the Set
* @param loadFactor the percentage of how full the backing array can be before they resize
* @param strategy the strategy that allows hash control.
* @throws NullPointerException if Strategy is null
* @throws IllegalStateException if the loadfactor is either below/equal to 0 or above/equal to 1
*/
public CUSTOM_HASH_SET(COLLECTION KEY_GENERIC_TYPE collection, float loadFactor, STRATEGY KEY_SUPER_GENERIC_TYPE strategy) { public CUSTOM_HASH_SET(COLLECTION KEY_GENERIC_TYPE collection, float loadFactor, STRATEGY KEY_SUPER_GENERIC_TYPE strategy) {
this(collection.size(), strategy); this(collection.size(), strategy);
addAll(collection); addAll(collection);
} }
/**
* A Helper constructor that allows to create a set from a iterator of an unknown size
* @param iterator the elements that should be added to the set
* @param strategy the strategy that allows hash control.
* @throws NullPointerException if Strategy is null
*/
public CUSTOM_HASH_SET(Iterator<CLASS_TYPE> iterator, STRATEGY KEY_SUPER_GENERIC_TYPE strategy) { public CUSTOM_HASH_SET(Iterator<CLASS_TYPE> iterator, STRATEGY KEY_SUPER_GENERIC_TYPE strategy) {
this(iterator, HashUtil.DEFAULT_LOAD_FACTOR, strategy); this(iterator, HashUtil.DEFAULT_LOAD_FACTOR, strategy);
} }
/**
* A Helper constructor that allows to create a set from a iterator of an unknown size
* @param iterator the elements that should be added to the set
* @param loadFactor the percentage of how full the backing array can be before they resize
* @param strategy the strategy that allows hash control.
* @throws NullPointerException if Strategy is null
* @throws IllegalStateException if the loadfactor is either below/equal to 0 or above/equal to 1
*/
public CUSTOM_HASH_SET(Iterator<CLASS_TYPE> iterator, float loadFactor, STRATEGY KEY_SUPER_GENERIC_TYPE strategy) { public CUSTOM_HASH_SET(Iterator<CLASS_TYPE> iterator, float loadFactor, STRATEGY KEY_SUPER_GENERIC_TYPE strategy) {
#if !TYPE_OBJECT #if !TYPE_OBJECT
this(ITERATORS.wrap(iterator), loadFactor, strategy); this(ITERATORS.wrap(iterator), loadFactor, strategy);
@ -102,16 +213,34 @@ public class CUSTOM_HASH_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_T
} }
#if !TYPE_OBJECT #if !TYPE_OBJECT
/**
* A Helper constructor that allows to create a set from a iterator of an unknown size
* @param iterator the elements that should be added to the set
* @param strategy the strategy that allows hash control.
* @throws NullPointerException if Strategy is null
*/
public CUSTOM_HASH_SET(ITERATOR KEY_GENERIC_TYPE iterator, STRATEGY KEY_SUPER_GENERIC_TYPE strategy) { public CUSTOM_HASH_SET(ITERATOR KEY_GENERIC_TYPE iterator, STRATEGY KEY_SUPER_GENERIC_TYPE strategy) {
this(iterator, HashUtil.DEFAULT_LOAD_FACTOR, strategy); this(iterator, HashUtil.DEFAULT_LOAD_FACTOR, strategy);
} }
/**
* A Helper constructor that allows to create a set from a iterator of an unknown size
* @param iterator the elements that should be added to the set
* @param loadFactor the percentage of how full the backing array can be before they resize
* @param strategy the strategy that allows hash control.
* @throws NullPointerException if Strategy is null
* @throws IllegalStateException if the loadfactor is either below/equal to 0 or above/equal to 1
*/
public CUSTOM_HASH_SET(ITERATOR KEY_GENERIC_TYPE iterator, float loadFactor, STRATEGY KEY_SUPER_GENERIC_TYPE 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); this(HashUtil.DEFAULT_MIN_CAPACITY, loadFactor, strategy);
while(iterator.hasNext()) add(iterator.NEXT()); while(iterator.hasNext()) add(iterator.NEXT());
} }
#endif #endif
/**
* Helper getter function to get the current strategy
* @return the current strategy
*/
public STRATEGY KEY_SUPER_GENERIC_TYPE getStrategy() { public STRATEGY KEY_SUPER_GENERIC_TYPE getStrategy() {
return strategy; return strategy;
} }

View File

@ -17,26 +17,55 @@ import speiger.src.collections.utils.HashUtil;
import speiger.src.collections.utils.ITrimmable; import speiger.src.collections.utils.ITrimmable;
import speiger.src.collections.utils.SanityChecks; import speiger.src.collections.utils.SanityChecks;
/**
* A Type Specific Custom implementation of the HashSet
* Instead of using Wrapper Object Arrays for storing keys and values there is dedicated arrays for storing keys.
* Extra to that there is a couple quality of life functions provided
* @Type(T)
*/
public class HASH_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_TYPE implements ITrimmable public class HASH_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_TYPE implements ITrimmable
{ {
/** The Backing keys array */
protected transient KEY_TYPE[] keys; protected transient KEY_TYPE[] keys;
/** If a null value is present */
protected transient boolean containsNull; protected transient boolean containsNull;
/** Minimum array size the HashSet will be */
protected transient int minCapacity; protected transient int minCapacity;
/** Index of the Null Value */
protected transient int nullIndex; protected transient int nullIndex;
/** Maximum amount of Values that can be stored before the array gets expanded usually 75% */
protected transient int maxFill; protected transient int maxFill;
/** Max Index that is allowed to be searched through nullIndex - 1 */
protected transient int mask; protected transient int mask;
/** Amount of Elements stored in the HashSet */
protected int size; protected int size;
/** How full the Array is allowed to get before resize */
protected final float loadFactor; protected final float loadFactor;
/**
* Default Constructor
*/
public HASH_SET() { public HASH_SET() {
this(HashUtil.DEFAULT_MIN_CAPACITY, HashUtil.DEFAULT_LOAD_FACTOR); this(HashUtil.DEFAULT_MIN_CAPACITY, HashUtil.DEFAULT_LOAD_FACTOR);
} }
/**
* Constructor that defines the minimum capacity
* @param minCapacity the minimum capacity the HashSet is allowed to be.
* @throws IllegalStateException if the minimum capacity is negative
*/
public HASH_SET(int minCapacity) { public HASH_SET(int minCapacity) {
this(minCapacity, HashUtil.DEFAULT_LOAD_FACTOR); this(minCapacity, HashUtil.DEFAULT_LOAD_FACTOR);
} }
/**
* Constructor that defines the minimum capacity and load factor
* @param minCapacity the minimum capacity the HashSet is allowed to be.
* @param loadFactor the percentage of how full the backing array can be before they resize
* @throws IllegalStateException if the minimum capacity is negative
* @throws IllegalStateException if the loadfactor is either below/equal to 0 or above/equal to 1
*/
public HASH_SET(int minCapacity, float loadFactor) { public HASH_SET(int minCapacity, float loadFactor) {
if(minCapacity < 0) throw new IllegalStateException("Minimum Capacity is negative. This is not allowed"); 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"); if(loadFactor <= 0 || loadFactor >= 1F) throw new IllegalStateException("Load Factor is not between 0 and 1");
@ -47,48 +76,104 @@ public class HASH_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_TYPE imp
keys = NEW_KEY_ARRAY(nullIndex + 1); keys = NEW_KEY_ARRAY(nullIndex + 1);
} }
/**
* Helper constructor that allow to create a set from unboxed values
* @param array the elements that should be put into the set
*/
public HASH_SET(KEY_TYPE[] array) { public HASH_SET(KEY_TYPE[] array) {
this(array, 0, array.length, HashUtil.DEFAULT_LOAD_FACTOR); this(array, 0, array.length, HashUtil.DEFAULT_LOAD_FACTOR);
} }
/**
* Helper constructor that allow to create a set from unboxed values
* @param array the elements that should be put into the set
* @param loadFactor the percentage of how full the backing array can be before they resize
* @throws IllegalStateException if the loadfactor is either below/equal to 0 or above/equal to 1
*/
public HASH_SET(KEY_TYPE[] array, float loadFactor) { public HASH_SET(KEY_TYPE[] array, float loadFactor) {
this(array, 0, array.length, loadFactor); this(array, 0, array.length, loadFactor);
} }
/**
* Helper constructor that allow to create a set from unboxed values
* @param array the elements that should be put into the set
* @param offset the starting index within the array that should be used
* @param length the amount of elements used from the array
* @throws IllegalStateException if offset and length causes to step outside of the arrays range
*/
public HASH_SET(KEY_TYPE[] array, int offset, int length) { public HASH_SET(KEY_TYPE[] array, int offset, int length) {
this(array, offset, length, HashUtil.DEFAULT_LOAD_FACTOR); this(array, offset, length, HashUtil.DEFAULT_LOAD_FACTOR);
} }
/**
* Helper constructor that allow to create a set from unboxed values
* @param array the elements that should be put into the set
* @param offset the starting index within the array that should be used
* @param length the amount of elements used from the array
* @param loadFactor the percentage of how full the backing array can be before they resize
* @throws IllegalStateException if the loadfactor is either below/equal to 0 or above/equal to 1
* @throws IllegalStateException if offset and length causes to step outside of the arrays range
*/
public HASH_SET(KEY_TYPE[] array, int offset, int length, float loadFactor) { public HASH_SET(KEY_TYPE[] array, int offset, int length, float loadFactor) {
this(length < 0 ? 0 : length); this(length < 0 ? 0 : length);
SanityChecks.checkArrayCapacity(array.length, offset, length); SanityChecks.checkArrayCapacity(array.length, offset, length);
for(int i = 0;i<length;i++) add(array[offset+i]); for(int i = 0;i<length;i++) add(array[offset+i]);
} }
/**
* A Helper constructor that allows to create a Set with exactly the same values as the provided collection.
* @param collection the set the elements should be added to the Set
*/
@Deprecated @Deprecated
public HASH_SET(Collection<? extends CLASS_TYPE> collection) { public HASH_SET(Collection<? extends CLASS_TYPE> collection) {
this(collection, HashUtil.DEFAULT_LOAD_FACTOR); this(collection, HashUtil.DEFAULT_LOAD_FACTOR);
} }
/**
* A Helper constructor that allows to create a Set with exactly the same values as the provided collection.
* @param collection the set the elements should be added to the Set
* @param loadFactor the percentage of how full the backing array can be before they resize
* @throws IllegalStateException if the loadfactor is either below/equal to 0 or above/equal to 1
*/
@Deprecated @Deprecated
public HASH_SET(Collection<? extends CLASS_TYPE> collection, float loadFactor) { public HASH_SET(Collection<? extends CLASS_TYPE> collection, float loadFactor) {
this(collection.size(), loadFactor); this(collection.size(), loadFactor);
addAll(collection); addAll(collection);
} }
/**
* A Helper constructor that allows to create a Set with exactly the same values as the provided collection.
* @param collection the set the elements should be added to the Set
*/
public HASH_SET(COLLECTION KEY_GENERIC_TYPE collection) { public HASH_SET(COLLECTION KEY_GENERIC_TYPE collection) {
this(collection, HashUtil.DEFAULT_LOAD_FACTOR); this(collection, HashUtil.DEFAULT_LOAD_FACTOR);
} }
/**
* A Helper constructor that allows to create a Set with exactly the same values as the provided collection.
* @param collection the set the elements should be added to the Set
* @param loadFactor the percentage of how full the backing array can be before they resize
* @throws IllegalStateException if the loadfactor is either below/equal to 0 or above/equal to 1
*/
public HASH_SET(COLLECTION KEY_GENERIC_TYPE collection, float loadFactor) { public HASH_SET(COLLECTION KEY_GENERIC_TYPE collection, float loadFactor) {
this(collection.size()); this(collection.size());
addAll(collection); addAll(collection);
} }
/**
* A Helper constructor that allows to create a set from a iterator of an unknown size
* @param iterator the elements that should be added to the set
*/
public HASH_SET(Iterator<CLASS_TYPE> iterator) { public HASH_SET(Iterator<CLASS_TYPE> iterator) {
this(iterator, HashUtil.DEFAULT_LOAD_FACTOR); this(iterator, HashUtil.DEFAULT_LOAD_FACTOR);
} }
/**
* A Helper constructor that allows to create a set from a iterator of an unknown size
* @param iterator the elements that should be added to the set
* @param loadFactor the percentage of how full the backing array can be before they resize
* @throws IllegalStateException if the loadfactor is either below/equal to 0 or above/equal to 1
*/
public HASH_SET(Iterator<CLASS_TYPE> iterator, float loadFactor) { public HASH_SET(Iterator<CLASS_TYPE> iterator, float loadFactor) {
#if !TYPE_OBJECT #if !TYPE_OBJECT
this(ITERATORS.wrap(iterator), loadFactor); this(ITERATORS.wrap(iterator), loadFactor);
@ -99,10 +184,20 @@ public class HASH_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_TYPE imp
} }
#if !TYPE_OBJECT #if !TYPE_OBJECT
/**
* A Helper constructor that allows to create a set from a iterator of an unknown size
* @param iterator the elements that should be added to the set
*/
public HASH_SET(ITERATOR KEY_GENERIC_TYPE iterator) { public HASH_SET(ITERATOR KEY_GENERIC_TYPE iterator) {
this(iterator, HashUtil.DEFAULT_LOAD_FACTOR); this(iterator, HashUtil.DEFAULT_LOAD_FACTOR);
} }
/**
* A Helper constructor that allows to create a set from a iterator of an unknown size
* @param iterator the elements that should be added to the set
* @param loadFactor the percentage of how full the backing array can be before they resize
* @throws IllegalStateException if the loadfactor is either below/equal to 0 or above/equal to 1
*/
public HASH_SET(ITERATOR KEY_GENERIC_TYPE iterator, float loadFactor) { public HASH_SET(ITERATOR KEY_GENERIC_TYPE iterator, float loadFactor) {
this(HashUtil.DEFAULT_MIN_CAPACITY, loadFactor); this(HashUtil.DEFAULT_MIN_CAPACITY, loadFactor);
while(iterator.hasNext()) add(iterator.NEXT()); while(iterator.hasNext()) add(iterator.NEXT());

View File

@ -18,74 +18,141 @@ import speiger.src.collections.PACKAGE.utils.ITERATORS;
#endif #endif
import speiger.src.collections.utils.SanityChecks; import speiger.src.collections.utils.SanityChecks;
/**
* A Simple Type Specific RB TreeSet implementation that reduces boxing/unboxing.
* It is using a bit more memory then <a href="https://github.com/vigna/fastutil">FastUtil</a>,
* but it saves a lot of Performance on the Optimized removal and iteration logic.
* Which makes the implementation actually useable and does not get outperformed by Javas default implementation.
* @Type(T)
*/
public class RB_TREE_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_TYPE implements NAVIGABLE_SET KEY_GENERIC_TYPE public class RB_TREE_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_TYPE implements NAVIGABLE_SET KEY_GENERIC_TYPE
{ {
/** The center of the Tree */
protected transient Entry KEY_GENERIC_TYPE tree; protected transient Entry KEY_GENERIC_TYPE tree;
/** The Lowest possible Node */
protected transient Entry KEY_GENERIC_TYPE first; protected transient Entry KEY_GENERIC_TYPE first;
/** The Highest possible Node */
protected transient Entry KEY_GENERIC_TYPE last; protected transient Entry KEY_GENERIC_TYPE last;
/** The amount of elements stored in the Set */
protected int size = 0; protected int size = 0;
/** The Sorter of the Tree */
protected transient COMPARATOR KEY_GENERIC_TYPE comparator; protected transient COMPARATOR KEY_GENERIC_TYPE comparator;
#if !TYPE_OBJECT #if !TYPE_OBJECT
#if TYPE_BOOLEAN /** the default return value for max searches */
protected KEY_TYPE defaultMaxNotFound = CLASS_TYPE.FALSE;
protected KEY_TYPE defaultMinNotFound = CLASS_TYPE.TRUE;
#else
protected KEY_TYPE defaultMaxNotFound = CLASS_TYPE.MIN_VALUE; protected KEY_TYPE defaultMaxNotFound = CLASS_TYPE.MIN_VALUE;
/** the default return value for min searches */
protected KEY_TYPE defaultMinNotFound = CLASS_TYPE.MAX_VALUE; protected KEY_TYPE defaultMinNotFound = CLASS_TYPE.MAX_VALUE;
#endif
#endif #endif
/**
* Default Constructor
*/
public RB_TREE_SET() { public RB_TREE_SET() {
} }
/**
* Constructor that allows to define the sorter
* @param comp the function that decides how the tree is sorted, can be null
*/
public RB_TREE_SET(COMPARATOR KEY_GENERIC_TYPE comp) { public RB_TREE_SET(COMPARATOR KEY_GENERIC_TYPE comp) {
comparator = comp; comparator = comp;
} }
/**
* Helper constructor that allow to create a set from an array
* @param array the elements that should be used
*/
public RB_TREE_SET(KEY_TYPE[] array) { public RB_TREE_SET(KEY_TYPE[] array) {
this(array, 0, array.length); this(array, 0, array.length);
} }
/**
* Helper constructor that allow to create a set from an array
* @param array the elements that should be used
* @param offset the starting index within the array
* @param length the amount of elements that are within the array
* @throws IllegalStateException if offset and length causes to step outside of the arrays range
*/
public RB_TREE_SET(KEY_TYPE[] array, int offset, int length) { public RB_TREE_SET(KEY_TYPE[] array, int offset, int length) {
SanityChecks.checkArrayCapacity(array.length, offset, length); SanityChecks.checkArrayCapacity(array.length, offset, length);
for(int i = 0;i<length;i++) add(array[offset+i]); for(int i = 0;i<length;i++) add(array[offset+i]);
} }
/**
* Helper constructor that allow to create a set from an array
* @param array the elements that should be used
* @param comp the sorter of the tree, can be null
*/
public RB_TREE_SET(KEY_TYPE[] array, COMPARATOR KEY_GENERIC_TYPE comp) { public RB_TREE_SET(KEY_TYPE[] array, COMPARATOR KEY_GENERIC_TYPE comp) {
this(array, 0, array.length, comp); this(array, 0, array.length, comp);
} }
/**
* Helper constructor that allow to create a set from an array
* @param array the elements that should be used
* @param offset the starting index within the array
* @param length the amount of elements that are within the array
* @param comp the sorter of the tree, can be null
* @throws IllegalStateException if offset and length causes to step outside of the arrays range
*/
public RB_TREE_SET(KEY_TYPE[] array, int offset, int length, COMPARATOR KEY_GENERIC_TYPE comp) { public RB_TREE_SET(KEY_TYPE[] array, int offset, int length, COMPARATOR KEY_GENERIC_TYPE comp) {
comparator = comp; comparator = comp;
SanityChecks.checkArrayCapacity(array.length, offset, length); SanityChecks.checkArrayCapacity(array.length, offset, length);
for(int i = 0;i<length;i++) add(array[offset+i]); for(int i = 0;i<length;i++) add(array[offset+i]);
} }
/**
* A Helper constructor that allows to create a Set with exactly the same values as the provided SortedSet.
* @param sortedSet the set the elements should be added to the TreeSet
* @note this also includes the Comparator if present
*/
public RB_TREE_SET(SORTED_SET KEY_GENERIC_TYPE sortedSet) { public RB_TREE_SET(SORTED_SET KEY_GENERIC_TYPE sortedSet) {
comparator = sortedSet.comparator(); comparator = sortedSet.comparator();
addAll(sortedSet); addAll(sortedSet);
} }
/**
* A Helper constructor that allows to create a Set with exactly the same values as the provided collection.
* @param collection the set the elements should be added to the TreeSet
*/
@Deprecated @Deprecated
public RB_TREE_SET(Collection<? extends CLASS_TYPE> collection) { public RB_TREE_SET(Collection<? extends CLASS_TYPE> collection) {
addAll(collection); addAll(collection);
} }
/**
* A Helper constructor that allows to create a Set with exactly the same values as the provided collection.
* @param collection the set the elements should be added to the TreeSet
* @param comp the sorter of the tree, can be null
*/
@Deprecated @Deprecated
public RB_TREE_SET(Collection<? extends CLASS_TYPE> collection, COMPARATOR KEY_GENERIC_TYPE comp) { public RB_TREE_SET(Collection<? extends CLASS_TYPE> collection, COMPARATOR KEY_GENERIC_TYPE comp) {
comparator = comp; comparator = comp;
addAll(collection); addAll(collection);
} }
/**
* A Helper constructor that allows to create a Set with exactly the same values as the provided collection.
* @param collection the set the elements should be added to the TreeSet
*/
public RB_TREE_SET(COLLECTION KEY_GENERIC_TYPE collection) { public RB_TREE_SET(COLLECTION KEY_GENERIC_TYPE collection) {
addAll(collection); addAll(collection);
} }
/**
* A Helper constructor that allows to create a Set with exactly the same values as the provided collection.
* @param collection the set the elements should be added to the TreeSet
* @param comp the sorter of the tree, can be null
*/
public RB_TREE_SET(COLLECTION KEY_GENERIC_TYPE collection, COMPARATOR KEY_GENERIC_TYPE comp) { public RB_TREE_SET(COLLECTION KEY_GENERIC_TYPE collection, COMPARATOR KEY_GENERIC_TYPE comp) {
comparator = comp; comparator = comp;
addAll(collection); addAll(collection);
} }
/**
* A Helper constructor that allows to create a set from a iterator of an unknown size
* @param iterator the elements that should be added to the set
*/
public RB_TREE_SET(Iterator<CLASS_TYPE> iterator) { public RB_TREE_SET(Iterator<CLASS_TYPE> iterator) {
#if !TYPE_OBJECT #if !TYPE_OBJECT
this(ITERATORS.wrap(iterator)); this(ITERATORS.wrap(iterator));
@ -93,7 +160,12 @@ public class RB_TREE_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_TYPE
while(iterator.hasNext()) add(iterator.next()); while(iterator.hasNext()) add(iterator.next());
#endif #endif
} }
/**
* A Helper constructor that allows to create a set from a iterator of an unknown size
* @param iterator the elements that should be added to the set
* @param comp the sorter of the tree, can be null
*/
public RB_TREE_SET(Iterator<CLASS_TYPE> iterator, COMPARATOR KEY_GENERIC_TYPE comp) { public RB_TREE_SET(Iterator<CLASS_TYPE> iterator, COMPARATOR KEY_GENERIC_TYPE comp) {
#if !TYPE_OBJECT #if !TYPE_OBJECT
this(ITERATORS.wrap(iterator), comp); this(ITERATORS.wrap(iterator), comp);
@ -103,10 +175,19 @@ public class RB_TREE_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_TYPE
#endif #endif
} }
/**
* A Helper constructor that allows to create a set from a iterator of an unknown size
* @param iterator the elements that should be added to the set
*/
public RB_TREE_SET(ITERATOR KEY_GENERIC_TYPE iterator) { public RB_TREE_SET(ITERATOR KEY_GENERIC_TYPE iterator) {
while(iterator.hasNext()) add(iterator.NEXT()); while(iterator.hasNext()) add(iterator.NEXT());
} }
/**
* A Helper constructor that allows to create a set from a iterator of an unknown size
* @param iterator the elements that should be added to the set
* @param comp the sorter of the tree, can be null
*/
public RB_TREE_SET(ITERATOR KEY_GENERIC_TYPE iterator, COMPARATOR KEY_GENERIC_TYPE comp) { public RB_TREE_SET(ITERATOR KEY_GENERIC_TYPE iterator, COMPARATOR KEY_GENERIC_TYPE comp) {
comparator = comp; comparator = comp;
while(iterator.hasNext()) add(iterator.NEXT()); while(iterator.hasNext()) add(iterator.NEXT());

View File

@ -5,12 +5,21 @@ import java.util.Set;
import speiger.src.collections.PACKAGE.collections.COLLECTION; import speiger.src.collections.PACKAGE.collections.COLLECTION;
import speiger.src.collections.PACKAGE.collections.ITERATOR; import speiger.src.collections.PACKAGE.collections.ITERATOR;
/**
* A Type Specific Set class to reduce boxing/unboxing
* @Type(T)
*/
public interface SET KEY_GENERIC_TYPE extends Set<CLASS_TYPE>, COLLECTION KEY_GENERIC_TYPE public interface SET KEY_GENERIC_TYPE extends Set<CLASS_TYPE>, COLLECTION KEY_GENERIC_TYPE
{ {
@Override @Override
public ITERATOR KEY_GENERIC_TYPE iterator(); public ITERATOR KEY_GENERIC_TYPE iterator();
#if !TYPE_OBJECT #if !TYPE_OBJECT
/**
* A Type Specific remove function to reduce boxing/unboxing
* @param o the element that should be removed
* @return true if the element was removed
*/
public boolean remove(KEY_TYPE o); public boolean remove(KEY_TYPE o);
@Override @Override

View File

@ -9,29 +9,111 @@ import java.util.Comparator;
import speiger.src.collections.PACKAGE.functions.COMPARATOR; import speiger.src.collections.PACKAGE.functions.COMPARATOR;
#endif #endif
/**
* A Type Specific SortedSet implementation to reduce boxing/unboxing
* with a couple extra methods that allow greater control over sets.
* @Type(T)
*/
public interface SORTED_SET KEY_GENERIC_TYPE extends SET KEY_GENERIC_TYPE, SortedSet<CLASS_TYPE> public interface SORTED_SET KEY_GENERIC_TYPE extends SET KEY_GENERIC_TYPE, SortedSet<CLASS_TYPE>
{ {
/**
* A customized add method that allows you to insert into the first index.
* @param o the element that should be inserted
* @return true if it was added
* @see java.util.Set#add(Object)
* @note some implementations do not support this method
*/
public boolean addAndMoveToFirst(KEY_TYPE o); public boolean addAndMoveToFirst(KEY_TYPE o);
/**
* A customized add method that allows you to insert into the last index.
* @param o the element that should be inserted
* @return true if it was added
* @see java.util.Set#add(Object)
* @note some implementations do not support this method
*/
public boolean addAndMoveToLast(KEY_TYPE o); public boolean addAndMoveToLast(KEY_TYPE o);
/**
* A specific move method to move a given key to the first index.
* @param o that should be moved to the first index
* @return true if the value was moved.
* @note returns false if the value was not present in the first place
* @note some implementations do not support this method
*/
public boolean moveToFirst(KEY_TYPE o); public boolean moveToFirst(KEY_TYPE o);
/**
* A specific move method to move a given key to the last index.
* @param o that should be moved to the first last
* @return true if the value was moved.
* @note returns false if the value was not present in the first place
* @note some implementations do not support this method
*/
public boolean moveToLast(KEY_TYPE o); public boolean moveToLast(KEY_TYPE o);
/**
* A Type Specific Comparator method
* @return the type specific comparator
*/
@Override @Override
public COMPARATOR KEY_GENERIC_TYPE comparator(); public COMPARATOR KEY_GENERIC_TYPE comparator();
@Override @Override
public BI_ITERATOR KEY_GENERIC_TYPE iterator(); public BI_ITERATOR KEY_GENERIC_TYPE iterator();
/**
* A type Specific Iterator starting from a given key
* @param fromElement the element the iterator should start from
* @return a iterator starting from the given element
* @throws java.util.NoSuchElementException if fromElement isn't found
*/
public BI_ITERATOR KEY_GENERIC_TYPE iterator(KEY_TYPE fromElement); public BI_ITERATOR KEY_GENERIC_TYPE iterator(KEY_TYPE fromElement);
#if !TYPE_OBJECT #if !TYPE_OBJECT
/**
* A Type Specific SubSet method to reduce boxing/unboxing
* @param fromElement where the SubSet should start
* @param toElement where the SubSet should end
* @return a SubSet that is within the range of the desired range
* @note Some implementations may not support this method.
* @note Some implementations may not keep the desired range when the original is changed.
*/
public SORTED_SET KEY_GENERIC_TYPE subSet(KEY_TYPE fromElement, KEY_TYPE toElement); public SORTED_SET KEY_GENERIC_TYPE subSet(KEY_TYPE fromElement, KEY_TYPE toElement);
/**
* A Type Specific HeadSet method to reduce boxing/unboxing
* @param toElement where the HeadSet should end
* @return a HeadSet that is within the range of the desired range
* @note Some implementations may not support this method.
* @note Some implementations may not keep the desired range when the original is changed.
*/
public SORTED_SET KEY_GENERIC_TYPE headSet(KEY_TYPE toElement); public SORTED_SET KEY_GENERIC_TYPE headSet(KEY_TYPE toElement);
/**
* A Type Specific TailSet method to reduce boxing/unboxing
* @param fromElement where the TailSet should start
* @return a TailSet that is within the range of the desired range
* @note Some implementations may not support this method.
* @note Some implementations may not keep the desired range when the original is changed.
*/
public SORTED_SET KEY_GENERIC_TYPE tailSet(KEY_TYPE fromElement); public SORTED_SET KEY_GENERIC_TYPE tailSet(KEY_TYPE fromElement);
/**
* A method to get the first element in the set
* @return first element in the set
*/
public KEY_TYPE FIRST_KEY(); public KEY_TYPE FIRST_KEY();
/**
* A method to get and remove the first element in the set
* @return first element in the set
*/
public KEY_TYPE POLL_FIRST_KEY(); public KEY_TYPE POLL_FIRST_KEY();
/**
* A method to get the last element in the set
* @return last element in the set
*/
public KEY_TYPE LAST_KEY(); public KEY_TYPE LAST_KEY();
/**
* A method to get and remove the last element in the set
* @return last element in the set
*/
public KEY_TYPE POLL_LAST_KEY(); public KEY_TYPE POLL_LAST_KEY();
@Override @Override
@ -51,7 +133,15 @@ public interface SORTED_SET KEY_GENERIC_TYPE extends SET KEY_GENERIC_TYPE, Sorte
@Deprecated @Deprecated
default CLASS_TYPE last() { return KEY_TO_OBJ(LAST_KEY()); } default CLASS_TYPE last() { return KEY_TO_OBJ(LAST_KEY()); }
#else #else
/**
* A method to get and remove the first element in the set
* @return first element in the set
*/
public CLASS_TYPE pollFirst(); public CLASS_TYPE pollFirst();
/**
* A method to get and remove the last element in the set
* @return last element in the set
*/
public CLASS_TYPE pollLast(); public CLASS_TYPE pollLast();
@Override @Override

View File

@ -19,6 +19,9 @@ import speiger.src.collections.PACKAGE.utils.ARRAYS;
*/ */
public class COLLECTIONS public class COLLECTIONS
{ {
/**
* Empty Collection Reference
*/
public static final COLLECTION NO_GENERIC_TYPE EMPTY = new EmptyCollectionBRACES(); public static final COLLECTION NO_GENERIC_TYPE EMPTY = new EmptyCollectionBRACES();
/** /**
@ -65,6 +68,10 @@ public class COLLECTIONS
return c instanceof SynchronizedCollection ? c : new SynchronizedCollectionBRACES(c, mutex); return c instanceof SynchronizedCollection ? c : new SynchronizedCollectionBRACES(c, mutex);
} }
/**
* Synchronized Collection Wrapper for the synchronizedCollection function
* @Type(T)
*/
public static class SynchronizedCollection KEY_GENERIC_TYPE implements COLLECTION KEY_GENERIC_TYPE { public static class SynchronizedCollection KEY_GENERIC_TYPE implements COLLECTION KEY_GENERIC_TYPE {
COLLECTION KEY_GENERIC_TYPE c; COLLECTION KEY_GENERIC_TYPE c;
protected Object mutex; protected Object mutex;
@ -163,6 +170,10 @@ public class COLLECTIONS
#endif #endif
} }
/**
* Unmodifyable Collection Wrapper for the unmodifyableCollection method
* @Type(T)
*/
public static class UnmodifiableCollection KEY_GENERIC_TYPE implements COLLECTION KEY_GENERIC_TYPE { public static class UnmodifiableCollection KEY_GENERIC_TYPE implements COLLECTION KEY_GENERIC_TYPE {
COLLECTION KEY_GENERIC_TYPE c; COLLECTION KEY_GENERIC_TYPE c;
@ -284,6 +295,10 @@ public class COLLECTIONS
#endif #endif
} }
/**
* Empty Collection implementation for the empty collection function
* @Type(T)
*/
public static class EmptyCollection KEY_GENERIC_TYPE extends ABSTRACT_COLLECTION KEY_GENERIC_TYPE { public static class EmptyCollection KEY_GENERIC_TYPE extends ABSTRACT_COLLECTION KEY_GENERIC_TYPE {
@Override @Override
public boolean add(KEY_TYPE o) { throw new UnsupportedOperationException(); } public boolean add(KEY_TYPE o) { throw new UnsupportedOperationException(); }

View File

@ -10,6 +10,9 @@ import speiger.src.collections.PACKAGE.collections.BI_ITERATOR;
*/ */
public class ITERATORS public class ITERATORS
{ {
/**
* Empty Iterator Reference
*/
public static final EmptyIterator NO_GENERIC_TYPE EMPTY = new EmptyIteratorBRACES(); public static final EmptyIterator NO_GENERIC_TYPE EMPTY = new EmptyIteratorBRACES();
/** /**
@ -25,42 +28,24 @@ public class ITERATORS
#endif #endif
} }
/**
* Inverter function for Bidirectional Iterators
* @param it the iterator that should be inverted
* @Type(T)
* @return a Inverted Bidirectional Iterator. If it was inverted then it just gives back the original reference
*/
public static GENERIC_KEY_BRACES BI_ITERATOR KEY_GENERIC_TYPE invert(BI_ITERATOR KEY_GENERIC_TYPE it) { public static GENERIC_KEY_BRACES BI_ITERATOR KEY_GENERIC_TYPE invert(BI_ITERATOR KEY_GENERIC_TYPE it) {
return new BI_ITERATOR KEY_GENERIC_TYPE() { return it instanceof ReverseBiIterator ? ((ReverseBiIterator KEY_GENERIC_TYPE)it).it : new ReverseBiIteratorBRACES(it);
@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(); }
};
} }
/**
* Inverter function for List Iterators
* @param it the iterator that should be inverted
* @Type(T)
* @return a Inverted List Iterator. If it was inverted then it just gives back the original reference
*/
public static GENERIC_KEY_BRACES LIST_ITERATOR KEY_GENERIC_TYPE invert(LIST_ITERATOR KEY_GENERIC_TYPE it) { public static GENERIC_KEY_BRACES LIST_ITERATOR KEY_GENERIC_TYPE invert(LIST_ITERATOR KEY_GENERIC_TYPE it) {
return new LIST_ITERATOR KEY_GENERIC_TYPE() { return it instanceof ReverseListIterator ? ((ReverseListIterator KEY_GENERIC_TYPE)it).it : new ReverseListIteratorBRACES(it);
@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); }
};
} }
/** /**
@ -73,6 +58,12 @@ public class ITERATORS
return iterator instanceof UnmodifiableIterator ? iterator : new UnmodifiableIteratorBRACES(iterator); return iterator instanceof UnmodifiableIterator ? iterator : new UnmodifiableIteratorBRACES(iterator);
} }
/**
* Returns a Immutable Iterator instance based on the instance given.
* @param iterator that should be made immutable/unmodifyable
* @Type(T)
* @return a unmodifiable iterator wrapper. If the Iterator already a unmodifyable wrapper then it just returns itself.
*/
public static GENERIC_KEY_BRACES BI_ITERATOR KEY_GENERIC_TYPE unmodifiable(BI_ITERATOR KEY_GENERIC_TYPE 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); return iterator instanceof UnmodifiableBiIterator ? iterator : new UnmodifiableBiIteratorBRACES(iterator);
} }
@ -88,6 +79,11 @@ public class ITERATORS
} }
#if !TYPE_OBJECT #if !TYPE_OBJECT
/**
* Helper function to convert a Object Iterator into a Primitive Iterator
* @param iterator that should be converted to a unboxing iterator
* @return a primitive iterator
*/
public static ITERATOR wrap(Iterator<CLASS_TYPE> iterator) { public static ITERATOR wrap(Iterator<CLASS_TYPE> iterator) {
return iterator instanceof ITERATOR ? (ITERATOR)iterator : new IteratorWrapper(iterator); return iterator instanceof ITERATOR ? (ITERATOR)iterator : new IteratorWrapper(iterator);
} }
@ -271,6 +267,52 @@ public class ITERATORS
} }
#endif #endif
private static class ReverseBiIterator KEY_GENERIC_TYPE implements BI_ITERATOR KEY_GENERIC_TYPE {
BI_ITERATOR KEY_GENERIC_TYPE it;
ReverseBiIterator(BI_ITERATOR KEY_GENERIC_TYPE it) {
this.it = it;
}
@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(); }
}
private static class ReverseListIterator KEY_GENERIC_TYPE implements LIST_ITERATOR KEY_GENERIC_TYPE {
LIST_ITERATOR KEY_GENERIC_TYPE it;
ReverseListIterator(LIST_ITERATOR KEY_GENERIC_TYPE it) {
this.it = it;
}
@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); }
}
private static class UnmodifiableListIterator KEY_GENERIC_TYPE implements LIST_ITERATOR KEY_GENERIC_TYPE private static class UnmodifiableListIterator KEY_GENERIC_TYPE implements LIST_ITERATOR KEY_GENERIC_TYPE
{ {
LIST_ITERATOR KEY_GENERIC_TYPE iter; LIST_ITERATOR KEY_GENERIC_TYPE iter;

View File

@ -18,6 +18,9 @@ import speiger.src.collections.PACKAGE.lists.LIST_ITERATOR;
*/ */
public class LISTS public class LISTS
{ {
/**
* Empty List reference
*/
public static final EmptyList NO_GENERIC_TYPE EMPTY = new EmptyListBRACES(); public static final EmptyList NO_GENERIC_TYPE EMPTY = new EmptyListBRACES();
/** /**
@ -74,11 +77,11 @@ public class LISTS
return new SingletonListBRACES(element); return new SingletonListBRACES(element);
} }
public static class SingletonList KEY_GENERIC_TYPE extends ABSTRACT_LIST KEY_GENERIC_TYPE private static class SingletonList KEY_GENERIC_TYPE extends ABSTRACT_LIST KEY_GENERIC_TYPE
{ {
KEY_TYPE element; KEY_TYPE element;
public SingletonList(KEY_TYPE element) SingletonList(KEY_TYPE element)
{ {
this.element = element; this.element = element;
} }
@ -123,7 +126,7 @@ public class LISTS
public int size() { return 1; } public int size() { return 1; }
} }
public static class SynchronizedArrayList KEY_GENERIC_TYPE extends SynchronizedList KEY_GENERIC_TYPE implements IARRAY KEY_GENERIC_TYPE private static class SynchronizedArrayList KEY_GENERIC_TYPE extends SynchronizedList KEY_GENERIC_TYPE implements IARRAY KEY_GENERIC_TYPE
{ {
IARRAY KEY_GENERIC_TYPE l; IARRAY KEY_GENERIC_TYPE l;
@ -155,7 +158,7 @@ public class LISTS
} }
} }
public static class SynchronizedRandomAccessList KEY_GENERIC_TYPE extends SynchronizedList KEY_GENERIC_TYPE implements RandomAccess private static class SynchronizedRandomAccessList KEY_GENERIC_TYPE extends SynchronizedList KEY_GENERIC_TYPE implements RandomAccess
{ {
SynchronizedRandomAccessList(LIST KEY_GENERIC_TYPE l) { SynchronizedRandomAccessList(LIST KEY_GENERIC_TYPE l) {
super(l); super(l);
@ -166,7 +169,7 @@ public class LISTS
} }
} }
public static class SynchronizedList KEY_GENERIC_TYPE extends COLLECTIONS.SynchronizedCollection KEY_GENERIC_TYPE implements LIST KEY_GENERIC_TYPE private static class SynchronizedList KEY_GENERIC_TYPE extends COLLECTIONS.SynchronizedCollection KEY_GENERIC_TYPE implements LIST KEY_GENERIC_TYPE
{ {
LIST KEY_GENERIC_TYPE l; LIST KEY_GENERIC_TYPE l;
@ -271,14 +274,14 @@ public class LISTS
public void size(int size) { synchronized(mutex) { l.size(size); } } public void size(int size) { synchronized(mutex) { l.size(size); } }
} }
public static class UnmodifiableRandomList KEY_GENERIC_TYPE extends UnmodifiableList KEY_GENERIC_TYPE implements RandomAccess private static class UnmodifiableRandomList KEY_GENERIC_TYPE extends UnmodifiableList KEY_GENERIC_TYPE implements RandomAccess
{ {
UnmodifiableRandomList(LIST KEY_GENERIC_TYPE l) { UnmodifiableRandomList(LIST KEY_GENERIC_TYPE l) {
super(l); super(l);
} }
} }
public static class UnmodifiableList KEY_GENERIC_TYPE extends COLLECTIONS.UnmodifiableCollection KEY_GENERIC_TYPE implements LIST KEY_GENERIC_TYPE private static class UnmodifiableList KEY_GENERIC_TYPE extends COLLECTIONS.UnmodifiableCollection KEY_GENERIC_TYPE implements LIST KEY_GENERIC_TYPE
{ {
final LIST KEY_GENERIC_TYPE l; final LIST KEY_GENERIC_TYPE l;
@ -380,7 +383,7 @@ public class LISTS
public void size(int size) { throw new UnsupportedOperationException(); } 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 private static class EmptyList KEY_GENERIC_TYPE extends COLLECTIONS.EmptyCollection KEY_GENERIC_TYPE implements LIST KEY_GENERIC_TYPE
{ {
@Override @Override
public boolean addAll(int index, Collection<? extends CLASS_TYPE> c) { throw new UnsupportedOperationException(); } public boolean addAll(int index, Collection<? extends CLASS_TYPE> c) { throw new UnsupportedOperationException(); }

View File

@ -25,10 +25,21 @@ import speiger.src.collections.PACKAGE.utils.COLLECTIONS.UnmodifiableCollection;
import speiger.src.collections.utils.ITrimmable; import speiger.src.collections.utils.ITrimmable;
#endif #endif
/**
* A Helper class for sets
*/
public class SETS public class SETS
{ {
/**
* Empty Set Variable
*/
public static final SET NO_GENERIC_TYPE EMPTY = new EmptySetBRACES(); public static final SET NO_GENERIC_TYPE EMPTY = new EmptySetBRACES();
/**
* EmptySet getter
* @Type(T)
* @return a EmptySet
*/
public static GENERIC_KEY_BRACES SET KEY_GENERIC_TYPE empty() { public static GENERIC_KEY_BRACES SET KEY_GENERIC_TYPE empty() {
#if TYPE_OBJECT #if TYPE_OBJECT
return (SET<KEY_TYPE>)EMPTY; return (SET<KEY_TYPE>)EMPTY;
@ -38,52 +49,121 @@ public class SETS
} }
#if !TYPE_BOOLEAN #if !TYPE_BOOLEAN
/**
* Creates a Synchronized set while preserving the ITrimmable interface
* @param s the set that should be synchronized
* @Type(T)
* @return a set that is synchronized
* @note if the set is already synchronized then it will just self return it
*/
public static GENERIC_KEY_BRACES SET KEY_GENERIC_TYPE synchronizedSet(SET KEY_GENERIC_TYPE s) { 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)); return s instanceof SynchronizedSet ? s : (s instanceof ITrimmable ? new SynchronizedTrimSetBRACES(s) : new SynchronizedSetBRACES(s));
} }
/**
* Creates a Synchronized set while preserving the ITrimmable interface
* @param s the set that should be synchronized
* @param mutex controller for access
* @Type(T)
* @return a set that is synchronized
* @note if the set is already synchronized then it will just self return it
*/
public static GENERIC_KEY_BRACES SET KEY_GENERIC_TYPE synchronizedSet(SET KEY_GENERIC_TYPE s, Object mutex) { 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)); return s instanceof SynchronizedSet ? s : (s instanceof ITrimmable ? new SynchronizedTrimSetBRACES(s, mutex) : new SynchronizedSetBRACES(s, mutex));
} }
/**
* Creates a Synchronized SortedSet while preserving the ITrimmable interface
* @param s the set that should be synchronized
* @Type(T)
* @return a SortedSet that is synchronized
* @note if the set is already synchronized then it will just self return it
*/
public static GENERIC_KEY_BRACES SORTED_SET KEY_GENERIC_TYPE synchronizedSet(SORTED_SET KEY_GENERIC_TYPE s) { 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)); return s instanceof SynchronizedSortedSet ? s : (s instanceof ITrimmable ? new SynchronizedSortedTrimSetBRACES(s) : new SynchronizedSortedSetBRACES(s));
} }
/**
* Creates a Synchronized SortedSet while preserving the ITrimmable interface
* @param s the set that should be synchronized
* @param mutex controller for access
* @Type(T)
* @return a SortedSet that is synchronized
* @note if the set is already synchronized then it will just self return it
*/
public static GENERIC_KEY_BRACES SORTED_SET KEY_GENERIC_TYPE synchronizedSet(SORTED_SET KEY_GENERIC_TYPE s, Object mutex) { 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)); return s instanceof SynchronizedSortedSet ? s : (s instanceof ITrimmable ? new SynchronizedSortedTrimSetBRACES(s, mutex) : new SynchronizedSortedSetBRACES(s, mutex));
} }
/**
* Creates a Synchronized NavigableSet while preserving the ITrimmable interface
* @param s the set that should be synchronized
* @Type(T)
* @return a NavigableSet that is synchronized
* @note if the set is already synchronized then it will just self return it
*/
public static GENERIC_KEY_BRACES NAVIGABLE_SET KEY_GENERIC_TYPE synchronizedSet(NAVIGABLE_SET KEY_GENERIC_TYPE s) { 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)); return s instanceof SynchronizedNavigableSet ? s : (s instanceof ITrimmable ? new SynchronizedNavigableTrimSetBRACES(s) : new SynchronizedNavigableSetBRACES(s));
} }
/**
* Creates a Synchronized NavigableSet while preserving the ITrimmable interface
* @param s the set that should be synchronized
* @param mutex controller for access
* @Type(T)
* @return a NavigableSet that is synchronized
* @note if the set is already synchronized then it will just self return it
*/
public static GENERIC_KEY_BRACES NAVIGABLE_SET KEY_GENERIC_TYPE synchronizedSet(NAVIGABLE_SET KEY_GENERIC_TYPE s, Object mutex) { 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)); return s instanceof SynchronizedNavigableSet ? s : (s instanceof ITrimmable ? new SynchronizedNavigableTrimSetBRACES(s, mutex) : new SynchronizedNavigableSetBRACES(s, mutex));
} }
/**
* Creates Unmodifyable Set wrapper
* @param s set that should be made unmodifyable
* @Type(T)
* @return a UnmodifyableSet, if the set is already unmodifyable then it returns itself
*/
public static GENERIC_KEY_BRACES SET KEY_GENERIC_TYPE unmodifiable(SET KEY_GENERIC_TYPE s) { public static GENERIC_KEY_BRACES SET KEY_GENERIC_TYPE unmodifiable(SET KEY_GENERIC_TYPE s) {
return s instanceof SynchronizedSet ? s : new SynchronizedSetBRACES(s); return s instanceof UnmodifiableSet ? s : new UnmodifiableSetBRACES(s);
} }
/**
* Creates Unmodifyable SortedSet wrapper
* @param s sortedSet that should be made unmodifyable
* @Type(T)
* @return a UnmodifyableSortedSet, if the set is already unmodifyable then it returns itself
*/
public static GENERIC_KEY_BRACES SORTED_SET KEY_GENERIC_TYPE unmodifiable(SORTED_SET KEY_GENERIC_TYPE 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); return s instanceof UnmodifiableSortedSet ? s : new UnmodifiableSortedSetBRACES(s);
} }
/**
* Creates Unmodifyable NavigableSet wrapper
* @param s navigableSet that should be made unmodifyable
* @Type(T)
* @return a UnmodifyableNavigableSet, if the set is already unmodifyable then it returns itself
*/
public static GENERIC_KEY_BRACES NAVIGABLE_SET KEY_GENERIC_TYPE unmodifiable(NAVIGABLE_SET KEY_GENERIC_TYPE 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); return s instanceof UnmodifiableNavigableSet ? s : new UnmodifiableNavigableSetBRACES(s);
} }
#endif #endif
/**
* Creates a Singleton set of a given element
* @param element the element that should be converted into a singleton set
* @Type(T)
* @return a singletonset of the given element
*/
public static GENERIC_KEY_BRACES SET KEY_GENERIC_TYPE singletonSet(KEY_TYPE element) { public static GENERIC_KEY_BRACES SET KEY_GENERIC_TYPE singletonSet(KEY_TYPE element) {
return new SingletonSetBRACES(element); return new SingletonSetBRACES(element);
} }
public static class SingletonSet KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_TYPE private static class SingletonSet KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_TYPE
{ {
KEY_TYPE element; KEY_TYPE element;
public SingletonSet(KEY_TYPE element) { SingletonSet(KEY_TYPE element) {
this.element = element; this.element = element;
} }
@ -112,7 +192,7 @@ public class SETS
public int size() { return 1; } public int size() { return 1; }
} }
public static class EmptySet KEY_GENERIC_TYPE extends EmptyCollection KEY_GENERIC_TYPE implements SET KEY_GENERIC_TYPE private static class EmptySet KEY_GENERIC_TYPE extends EmptyCollection KEY_GENERIC_TYPE implements SET KEY_GENERIC_TYPE
{ {
#if !TYPE_OBJECT #if !TYPE_OBJECT
@Override @Override
@ -121,11 +201,11 @@ public class SETS
} }
#if !TYPE_BOOLEAN #if !TYPE_BOOLEAN
public static class UnmodifiableNavigableSet KEY_GENERIC_TYPE extends UnmodifiableSortedSet KEY_GENERIC_TYPE implements NAVIGABLE_SET KEY_GENERIC_TYPE private static class UnmodifiableNavigableSet KEY_GENERIC_TYPE extends UnmodifiableSortedSet KEY_GENERIC_TYPE implements NAVIGABLE_SET KEY_GENERIC_TYPE
{ {
NAVIGABLE_SET KEY_GENERIC_TYPE n; NAVIGABLE_SET KEY_GENERIC_TYPE n;
public UnmodifiableNavigableSet(NAVIGABLE_SET KEY_GENERIC_TYPE c) { UnmodifiableNavigableSet(NAVIGABLE_SET KEY_GENERIC_TYPE c) {
super(c); super(c);
n = c; n = c;
} }
@ -190,10 +270,10 @@ public class SETS
public NAVIGABLE_SET KEY_GENERIC_TYPE tailSet(KEY_TYPE fromElement) { return unmodifiable(n.tailSet(fromElement)); } 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 private static class UnmodifiableSortedSet KEY_GENERIC_TYPE extends UnmodifiableSet KEY_GENERIC_TYPE implements SORTED_SET KEY_GENERIC_TYPE
{ {
SORTED_SET KEY_GENERIC_TYPE s; SORTED_SET KEY_GENERIC_TYPE s;
public UnmodifiableSortedSet(SORTED_SET KEY_GENERIC_TYPE c) UnmodifiableSortedSet(SORTED_SET KEY_GENERIC_TYPE c)
{ {
super(c); super(c);
s = c; s = c;
@ -242,11 +322,15 @@ public class SETS
public KEY_TYPE POLL_LAST_KEY() { throw new UnsupportedOperationException(); } public KEY_TYPE POLL_LAST_KEY() { throw new UnsupportedOperationException(); }
} }
/**
* Unmodifyable Set wrapper that helps is used with unmodifyableSet function
* @Type(T)
*/
public static class UnmodifiableSet KEY_GENERIC_TYPE extends UnmodifiableCollection KEY_GENERIC_TYPE implements SET KEY_GENERIC_TYPE public static class UnmodifiableSet KEY_GENERIC_TYPE extends UnmodifiableCollection KEY_GENERIC_TYPE implements SET KEY_GENERIC_TYPE
{ {
SET KEY_GENERIC_TYPE s; SET KEY_GENERIC_TYPE s;
public UnmodifiableSet(SET KEY_GENERIC_TYPE c) protected UnmodifiableSet(SET KEY_GENERIC_TYPE c)
{ {
super(c); super(c);
s = c; s = c;
@ -258,16 +342,16 @@ public class SETS
#endif #endif
} }
public static class SynchronizedNavigableTrimSet KEY_GENERIC_TYPE extends SynchronizedNavigableSet KEY_GENERIC_TYPE implements ITrimmable private static class SynchronizedNavigableTrimSet KEY_GENERIC_TYPE extends SynchronizedNavigableSet KEY_GENERIC_TYPE implements ITrimmable
{ {
ITrimmable trim; ITrimmable trim;
public SynchronizedNavigableTrimSet(NAVIGABLE_SET KEY_GENERIC_TYPE c) { SynchronizedNavigableTrimSet(NAVIGABLE_SET KEY_GENERIC_TYPE c) {
super(c); super(c);
trim = (ITrimmable)c; trim = (ITrimmable)c;
} }
public SynchronizedNavigableTrimSet(NAVIGABLE_SET KEY_GENERIC_TYPE c, Object mutex) { SynchronizedNavigableTrimSet(NAVIGABLE_SET KEY_GENERIC_TYPE c, Object mutex) {
super(c, mutex); super(c, mutex);
trim = (ITrimmable)c; trim = (ITrimmable)c;
} }
@ -276,16 +360,16 @@ public class SETS
public boolean trim(int size) { synchronized(mutex) { return trim.trim(size); } } 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 private static class SynchronizedNavigableSet KEY_GENERIC_TYPE extends SynchronizedSortedSet KEY_GENERIC_TYPE implements NAVIGABLE_SET KEY_GENERIC_TYPE
{ {
NAVIGABLE_SET KEY_GENERIC_TYPE n; NAVIGABLE_SET KEY_GENERIC_TYPE n;
public SynchronizedNavigableSet(NAVIGABLE_SET KEY_GENERIC_TYPE c) { SynchronizedNavigableSet(NAVIGABLE_SET KEY_GENERIC_TYPE c) {
super(c); super(c);
n = c; n = c;
} }
public SynchronizedNavigableSet(NAVIGABLE_SET KEY_GENERIC_TYPE c, Object mutex) { SynchronizedNavigableSet(NAVIGABLE_SET KEY_GENERIC_TYPE c, Object mutex) {
super(c, mutex); super(c, mutex);
n = c; n = c;
} }
@ -350,16 +434,16 @@ public class SETS
public NAVIGABLE_SET KEY_GENERIC_TYPE tailSet(KEY_TYPE fromElement) { synchronized(mutex) { return synchronizedSet(n.tailSet(fromElement), mutex); } } 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 private static class SynchronizedSortedTrimSet KEY_GENERIC_TYPE extends SynchronizedSortedSet KEY_GENERIC_TYPE implements ITrimmable
{ {
ITrimmable trim; ITrimmable trim;
public SynchronizedSortedTrimSet(SORTED_SET KEY_GENERIC_TYPE c) { SynchronizedSortedTrimSet(SORTED_SET KEY_GENERIC_TYPE c) {
super(c); super(c);
trim = (ITrimmable)c; trim = (ITrimmable)c;
} }
public SynchronizedSortedTrimSet(SORTED_SET KEY_GENERIC_TYPE c, Object mutex) { SynchronizedSortedTrimSet(SORTED_SET KEY_GENERIC_TYPE c, Object mutex) {
super(c, mutex); super(c, mutex);
trim = (ITrimmable)c; trim = (ITrimmable)c;
} }
@ -368,16 +452,16 @@ public class SETS
public boolean trim(int size) { synchronized(mutex) { return trim.trim(size); } } 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 private static class SynchronizedSortedSet KEY_GENERIC_TYPE extends SynchronizedSet KEY_GENERIC_TYPE implements SORTED_SET KEY_GENERIC_TYPE
{ {
SORTED_SET KEY_GENERIC_TYPE s; SORTED_SET KEY_GENERIC_TYPE s;
public SynchronizedSortedSet(SORTED_SET KEY_GENERIC_TYPE c) { SynchronizedSortedSet(SORTED_SET KEY_GENERIC_TYPE c) {
super(c); super(c);
s = c; s = c;
} }
public SynchronizedSortedSet(SORTED_SET KEY_GENERIC_TYPE c, Object mutex) { SynchronizedSortedSet(SORTED_SET KEY_GENERIC_TYPE c, Object mutex) {
super(c, mutex); super(c, mutex);
s = c; s = c;
} }
@ -425,16 +509,16 @@ public class SETS
public KEY_TYPE POLL_LAST_KEY() { synchronized(mutex) { return s.POLL_LAST_KEY(); } } 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 private static class SynchronizedTrimSet KEY_GENERIC_TYPE extends SynchronizedSet KEY_GENERIC_TYPE implements ITrimmable
{ {
ITrimmable trim; ITrimmable trim;
public SynchronizedTrimSet(SET KEY_GENERIC_TYPE c) { SynchronizedTrimSet(SET KEY_GENERIC_TYPE c) {
super(c); super(c);
trim = (ITrimmable)c; trim = (ITrimmable)c;
} }
public SynchronizedTrimSet(SET KEY_GENERIC_TYPE c, Object mutex) { SynchronizedTrimSet(SET KEY_GENERIC_TYPE c, Object mutex) {
super(c, mutex); super(c, mutex);
trim = (ITrimmable)c; trim = (ITrimmable)c;
} }
@ -443,18 +527,24 @@ public class SETS
public boolean trim(int size) { synchronized(mutex) { return trim.trim(size); } } 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 private static class SynchronizedSet KEY_GENERIC_TYPE extends SynchronizedCollection KEY_GENERIC_TYPE implements SET KEY_GENERIC_TYPE
{ {
#if !TYPE_OBJECT
SET KEY_GENERIC_TYPE s; SET KEY_GENERIC_TYPE s;
#endif
public SynchronizedSet(SET KEY_GENERIC_TYPE c) { SynchronizedSet(SET KEY_GENERIC_TYPE c) {
super(c); super(c);
#if !TYPE_OBJECT
s = c; s = c;
#endif
} }
public SynchronizedSet(SET KEY_GENERIC_TYPE c, Object mutex) { SynchronizedSet(SET KEY_GENERIC_TYPE c, Object mutex) {
super(c, mutex); super(c, mutex);
#if !TYPE_OBJECT
s = c; s = c;
#endif
} }
#if !TYPE_OBJECT #if !TYPE_OBJECT

View File

@ -1,8 +1,23 @@
package speiger.src.collections.PACKAGE.utils; package speiger.src.collections.PACKAGE.utils;
/**
* A Type Specific Strategy class that allows to give control hashcode generation and equals comparason for maps
* @Type(T)
*/
public interface STRATEGY KEY_GENERIC_TYPE public interface STRATEGY KEY_GENERIC_TYPE
{ {
/**
* Type Specific HashCode function
* @param o the element that the hashcode is requested for (if object may be null)
* @return hashcode for the given entry
*/
public int hashCode(KEY_TYPE o); public int hashCode(KEY_TYPE o);
/**
* Type Specific Equals function
* @param key the first element that should be compared with
* @param value the second element that should be compared with (if object may be null)
* @return if the elements match
*/
public boolean equals(KEY_TYPE key, KEY_TYPE value); public boolean equals(KEY_TYPE key, KEY_TYPE value);
} }

View File

@ -62,8 +62,10 @@ public class MAPS
#endif #endif
/** /**
* Helper method that provides the fastIterator that recycles a single Entry to increase throughput. * Helper method that provides the fastIterator that recycles a single Entry to increase throughput.
* @param map the map the fastiterator should be accessed from * @param map the map the fastIterator should be accessed from
* @return either a normal iterator if it does not support this feature ot a fastiterator * @Type(T)
* @ValueType(V)
* @return either a normal iterator if it does not support this feature to a fastIterator
*/ */
public static GENERIC_KEY_VALUE_BRACES ObjectIterator<MAP.Entry KEY_VALUE_GENERIC_TYPE> fastIterator(MAP KEY_VALUE_GENERIC_TYPE map) { 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(); ObjectSet<MAP.Entry KEY_VALUE_GENERIC_TYPE> entries = map.ENTRY_SET();
@ -73,7 +75,9 @@ public class MAPS
/** /**
* Helper method that provides the fastIterable that recycles a single Entry to increase throughput. * Helper method that provides the fastIterable that recycles a single Entry to increase throughput.
* @param map the map the fastIterable should be accessed from * @param map the map the fastIterable should be accessed from
* @return either a normal iterable if it does not support this feature ot a fastIterable * @Type(T)
* @ValueType(V)
* @return either a normal iterable if it does not support this feature to a fastIterable
*/ */
public static GENERIC_KEY_VALUE_BRACES ObjectIterable<MAP.Entry KEY_VALUE_GENERIC_TYPE> fastIterable(MAP KEY_VALUE_GENERIC_TYPE map) { 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(); ObjectSet<MAP.Entry KEY_VALUE_GENERIC_TYPE> entries = map.ENTRY_SET();
@ -89,6 +93,8 @@ public class MAPS
* A Helper function that provides a faster forEach iterator implementation that recycles the entry to increase throughput * A Helper function that provides a faster forEach iterator implementation that recycles the entry to increase throughput
* @param map the map the fast forEach should be accessed from * @param map the map the fast forEach should be accessed from
* @param action the action that should be performed on each entry * @param action the action that should be performed on each entry
* @Type(T)
* @ValueType(V)
* @note if the fast forEach is not supported will default to a normal forEach * @note if the fast forEach is not supported will default to a normal forEach
*/ */
public static GENERIC_KEY_VALUE_BRACES void fastForEach(MAP KEY_VALUE_GENERIC_TYPE map, Consumer<MAP.Entry KEY_VALUE_GENERIC_TYPE> action) { public static GENERIC_KEY_VALUE_BRACES void fastForEach(MAP KEY_VALUE_GENERIC_TYPE map, Consumer<MAP.Entry KEY_VALUE_GENERIC_TYPE> action) {
@ -100,6 +106,8 @@ public class MAPS
#if !TYPE_BOOLEAN #if !TYPE_BOOLEAN
/** /**
* Empty Map getter function that autocasts to the desired Key and Value * Empty Map getter function that autocasts to the desired Key and Value
* @Type(T)
* @ValueType(V)
* @return empty map of desired type * @return empty map of desired type
*/ */
public static GENERIC_KEY_VALUE_BRACES MAP KEY_VALUE_GENERIC_TYPE emptyMap() { public static GENERIC_KEY_VALUE_BRACES MAP KEY_VALUE_GENERIC_TYPE emptyMap() {
@ -113,6 +121,8 @@ public class MAPS
/** /**
* Helper function that creates a Helper wrapper to synchronize access into the map. * Helper function that creates a Helper wrapper to synchronize access into the map.
* @param map the map that should be synchronized * @param map the map that should be synchronized
* @Type(T)
* @ValueType(V)
* @return a synchronized Map * @return a synchronized Map
* @note if the inputted map is already synchronized then it will just return it instead * @note if the inputted map is already synchronized then it will just return it instead
* @note iterators do not support synchronization * @note iterators do not support synchronization
@ -122,6 +132,8 @@ public class MAPS
* Helper function that creates a Helper wrapper to synchronize access with custom access control into the map. * Helper function that creates a Helper wrapper to synchronize access with custom access control into the map.
* @param map the map that should be synchronized * @param map the map that should be synchronized
* @param mutex the object that controls access * @param mutex the object that controls access
* @Type(T)
* @ValueType(V)
* @return a synchronized Map * @return a synchronized Map
* @note if the inputted map is already synchronized then it will just return it instead * @note if the inputted map is already synchronized then it will just return it instead
* @note iterators do not support synchronization * @note iterators do not support synchronization
@ -131,6 +143,8 @@ public class MAPS
/** /**
* Helper function that creates a Helper wrapper to synchronize access into the SortedMap. * Helper function that creates a Helper wrapper to synchronize access into the SortedMap.
* @param map the SortedMap that should be synchronized * @param map the SortedMap that should be synchronized
* @Type(T)
* @ValueType(V)
* @return a synchronized SortedMap * @return a synchronized SortedMap
* @note if the inputted map is already synchronized then it will just return it instead * @note if the inputted map is already synchronized then it will just return it instead
* @note iterators do not support synchronization * @note iterators do not support synchronization
@ -140,6 +154,8 @@ public class MAPS
* Helper function that creates a Helper wrapper to synchronize access with custom access control into the SortedMap. * Helper function that creates a Helper wrapper to synchronize access with custom access control into the SortedMap.
* @param map the SortedMap that should be synchronized * @param map the SortedMap that should be synchronized
* @param mutex the object that controls access * @param mutex the object that controls access
* @Type(T)
* @ValueType(V)
* @return a synchronized SortedMap * @return a synchronized SortedMap
* @note if the inputted map is already synchronized then it will just return it instead * @note if the inputted map is already synchronized then it will just return it instead
* @note iterators do not support synchronization * @note iterators do not support synchronization
@ -149,6 +165,8 @@ public class MAPS
/** /**
* Helper function that creates a Helper wrapper to synchronize access into the NavigableMap. * Helper function that creates a Helper wrapper to synchronize access into the NavigableMap.
* @param map the NavigableMap that should be synchronized * @param map the NavigableMap that should be synchronized
* @Type(T)
* @ValueType(V)
* @return a synchronized NavigableMap * @return a synchronized NavigableMap
* @note if the inputted map is already synchronized then it will just return it instead * @note if the inputted map is already synchronized then it will just return it instead
* @note iterators do not support synchronization * @note iterators do not support synchronization
@ -158,6 +176,8 @@ public class MAPS
* Helper function that creates a Helper wrapper to synchronize access with custom access control into the NavigableMap. * Helper function that creates a Helper wrapper to synchronize access with custom access control into the NavigableMap.
* @param map the NavigableMap that should be synchronized * @param map the NavigableMap that should be synchronized
* @param mutex the object that controls access * @param mutex the object that controls access
* @Type(T)
* @ValueType(V)
* @return a synchronized NavigableMap * @return a synchronized NavigableMap
* @note if the inputted map is already synchronized then it will just return it instead * @note if the inputted map is already synchronized then it will just return it instead
* @note iterators do not support synchronization * @note iterators do not support synchronization
@ -167,6 +187,8 @@ public class MAPS
/** /**
* A Helper function that creates a Helper wrapper to only allow Read Access into the Map * A Helper function that creates a Helper wrapper to only allow Read Access into the Map
* @param map the map that should be made Unmodifiable * @param map the map that should be made Unmodifiable
* @Type(T)
* @ValueType(V)
* @return a unmodifiable Map * @return a unmodifiable Map
* @note if the inputted map is already unmodifiable then it will just return it instead * @note if the inputted map is already unmodifiable then it will just return it instead
*/ */
@ -174,6 +196,8 @@ public class MAPS
/** /**
* A Helper function that creates a Helper wrapper to only allow Read Access into the SortedMap * A Helper function that creates a Helper wrapper to only allow Read Access into the SortedMap
* @param map the SortedMap that should be made Unmodifiable * @param map the SortedMap that should be made Unmodifiable
* @Type(T)
* @ValueType(V)
* @return a unmodifiable SortedMap * @return a unmodifiable SortedMap
* @note if the inputted SortedMap is already unmodifiable then it will just return it instead * @note if the inputted SortedMap is already unmodifiable then it will just return it instead
*/ */
@ -181,6 +205,8 @@ public class MAPS
/** /**
* A Helper function that creates a Helper wrapper to only allow Read Access into NavigableMap Map * A Helper function that creates a Helper wrapper to only allow Read Access into NavigableMap Map
* @param map the NavigableMap that should be made Unmodifiable * @param map the NavigableMap that should be made Unmodifiable
* @Type(T)
* @ValueType(V)
* @return a unmodifiable NavigableMap * @return a unmodifiable NavigableMap
* @note if the inputted NavigableMap is already unmodifiable then it will just return it instead * @note if the inputted NavigableMap is already unmodifiable then it will just return it instead
*/ */
@ -188,12 +214,16 @@ public class MAPS
/** /**
* A Helper function that creates a Unmodifyable Entry * A Helper function that creates a Unmodifyable Entry
* @param entry the Entry that should be made unmodifyable * @param entry the Entry that should be made unmodifyable
* @Type(T)
* @ValueType(V)
* @return a Unmodifyable Entry * @return a Unmodifyable Entry
*/ */
public static GENERIC_KEY_VALUE_BRACES MAP.Entry KEY_VALUE_GENERIC_TYPE unmodifyableEntry(MAP.Entry KEY_VALUE_GENERIC_TYPE entry) { return entry instanceof UnmodifyableEntry ? entry : new UnmodifyableEntryKV_BRACES(entry); } public static GENERIC_KEY_VALUE_BRACES MAP.Entry KEY_VALUE_GENERIC_TYPE unmodifyableEntry(MAP.Entry KEY_VALUE_GENERIC_TYPE entry) { return entry instanceof UnmodifyableEntry ? entry : new UnmodifyableEntryKV_BRACES(entry); }
/** /**
* A Helper function that creates a Unmodifyable Entry * A Helper function that creates a Unmodifyable Entry
* @param entry the Entry that should be made unmodifyable * @param entry the Entry that should be made unmodifyable
* @Type(T)
* @ValueType(V)
* @return a Unmodifyable Entry * @return a Unmodifyable Entry
*/ */
public static GENERIC_KEY_VALUE_BRACES MAP.Entry KEY_VALUE_GENERIC_TYPE unmodifyableEntry(Map.Entry<CLASS_TYPE, CLASS_VALUE_TYPE> entry) { return entry instanceof UnmodifyableEntry ? (UnmodifyableEntry KEY_VALUE_GENERIC_TYPE)entry : new UnmodifyableEntryKV_BRACES(entry); } public static GENERIC_KEY_VALUE_BRACES MAP.Entry KEY_VALUE_GENERIC_TYPE unmodifyableEntry(Map.Entry<CLASS_TYPE, CLASS_VALUE_TYPE> entry) { return entry instanceof UnmodifyableEntry ? (UnmodifyableEntry KEY_VALUE_GENERIC_TYPE)entry : new UnmodifyableEntryKV_BRACES(entry); }
@ -203,6 +233,8 @@ public class MAPS
* This reduces overhead that normal Map implementations have. * This reduces overhead that normal Map implementations have.
* @param key the key that should be turned into a singleton * @param key the key that should be turned into a singleton
* @param value the value that should be turned into a singleton * @param value the value that should be turned into a singleton
* @Type(T)
* @ValueType(V)
* @return a unmodifyable Singleton map. * @return a unmodifyable Singleton map.
*/ */
public static GENERIC_KEY_VALUE_BRACES MAP KEY_VALUE_GENERIC_TYPE singletonMap(KEY_TYPE key, VALUE_TYPE value) { return new SingletonMapKV_BRACES(key, value); } public static GENERIC_KEY_VALUE_BRACES MAP KEY_VALUE_GENERIC_TYPE singletonMap(KEY_TYPE key, VALUE_TYPE value) { return new SingletonMapKV_BRACES(key, value); }
@ -219,12 +251,7 @@ public class MAPS
VALUE_COLLECTION VALUE_GENERIC_TYPE values; VALUE_COLLECTION VALUE_GENERIC_TYPE values;
ObjectSet<MAP.Entry KEY_VALUE_GENERIC_TYPE> entrySet; ObjectSet<MAP.Entry KEY_VALUE_GENERIC_TYPE> entrySet;
/** SingletonMap(KEY_TYPE key, VALUE_TYPE value) {
* Default constructor
* @param key the key that should be used
* @param value the value that should be used
*/
public SingletonMap(KEY_TYPE key, VALUE_TYPE value) {
this.key = key; this.key = key;
this.value = value; this.value = value;
} }
@ -308,19 +335,11 @@ public class MAPS
*/ */
public static class UnmodifyableEntry KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP.BasicEntry KEY_VALUE_GENERIC_TYPE { public static class UnmodifyableEntry KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP.BasicEntry KEY_VALUE_GENERIC_TYPE {
/** UnmodifyableEntry(Map.Entry<CLASS_TYPE, CLASS_VALUE_TYPE> entry) {
* The boxed constructor that will automatically unbox the values
* @param entry the entry that should be used
*/
public UnmodifyableEntry(Map.Entry<CLASS_TYPE, CLASS_VALUE_TYPE> entry) {
super(entry.getKey(), entry.getValue()); super(entry.getKey(), entry.getValue());
} }
/** UnmodifyableEntry(MAP.Entry KEY_VALUE_GENERIC_TYPE entry) {
* The Unboxed constructor that should be copied from
* @param entry the entry that should be used
*/
public UnmodifyableEntry(MAP.Entry KEY_VALUE_GENERIC_TYPE entry) {
super(entry.ENTRY_KEY(), entry.ENTRY_VALUE()); super(entry.ENTRY_KEY(), entry.ENTRY_VALUE());
} }
@ -336,11 +355,7 @@ public class MAPS
public static class UnmodifyableNavigableMap KEY_VALUE_GENERIC_TYPE extends UnmodifyableSortedMap KEY_VALUE_GENERIC_TYPE implements NAVIGABLE_MAP KEY_VALUE_GENERIC_TYPE { public static class UnmodifyableNavigableMap KEY_VALUE_GENERIC_TYPE extends UnmodifyableSortedMap KEY_VALUE_GENERIC_TYPE implements NAVIGABLE_MAP KEY_VALUE_GENERIC_TYPE {
NAVIGABLE_MAP KEY_VALUE_GENERIC_TYPE map; NAVIGABLE_MAP KEY_VALUE_GENERIC_TYPE map;
/** UnmodifyableNavigableMap(NAVIGABLE_MAP KEY_VALUE_GENERIC_TYPE map) {
* Default constructor
* @param map the NavigableMap that should be made unmodifyable
*/
public UnmodifyableNavigableMap(NAVIGABLE_MAP KEY_VALUE_GENERIC_TYPE map) {
super(map); super(map);
this.map = map; this.map = map;
} }
@ -407,11 +422,7 @@ public class MAPS
public static class UnmodifyableSortedMap KEY_VALUE_GENERIC_TYPE extends UnmodifyableMap KEY_VALUE_GENERIC_TYPE implements SORTED_MAP KEY_VALUE_GENERIC_TYPE { public static class UnmodifyableSortedMap KEY_VALUE_GENERIC_TYPE extends UnmodifyableMap KEY_VALUE_GENERIC_TYPE implements SORTED_MAP KEY_VALUE_GENERIC_TYPE {
SORTED_MAP KEY_VALUE_GENERIC_TYPE map; SORTED_MAP KEY_VALUE_GENERIC_TYPE map;
/** UnmodifyableSortedMap(SORTED_MAP KEY_VALUE_GENERIC_TYPE map) {
* Default constructor
* @param map the SortedMap that should be made unmodifyable
*/
public UnmodifyableSortedMap(SORTED_MAP KEY_VALUE_GENERIC_TYPE map) {
super(map); super(map);
this.map = map; this.map = map;
} }
@ -461,11 +472,7 @@ public class MAPS
SET KEY_GENERIC_TYPE keys; SET KEY_GENERIC_TYPE keys;
ObjectSet<MAP.Entry KEY_VALUE_GENERIC_TYPE> entrySet; ObjectSet<MAP.Entry KEY_VALUE_GENERIC_TYPE> entrySet;
/** UnmodifyableMap(MAP KEY_VALUE_GENERIC_TYPE map) {
* Default constructor
* @param map the Map that should be made unmodifyable
*/
public UnmodifyableMap(MAP KEY_VALUE_GENERIC_TYPE map) {
this.map = map; this.map = map;
} }
@ -518,11 +525,7 @@ public class MAPS
{ {
ObjectSet<MAP.Entry KEY_VALUE_GENERIC_TYPE> s; ObjectSet<MAP.Entry KEY_VALUE_GENERIC_TYPE> s;
/** UnmodifyableEntrySet(ObjectSet<MAP.Entry KEY_VALUE_GENERIC_TYPE> c)
* Default constructor
* @param c the EntrySet that should be made unmodifyable
*/
public UnmodifyableEntrySet(ObjectSet<MAP.Entry KEY_VALUE_GENERIC_TYPE> c)
{ {
super(c); super(c);
s = c; s = c;
@ -554,21 +557,12 @@ public class MAPS
public static class SynchronizedNavigableMap KEY_VALUE_GENERIC_TYPE extends SynchronizedSortedMap KEY_VALUE_GENERIC_TYPE implements NAVIGABLE_MAP KEY_VALUE_GENERIC_TYPE { public static class SynchronizedNavigableMap KEY_VALUE_GENERIC_TYPE extends SynchronizedSortedMap KEY_VALUE_GENERIC_TYPE implements NAVIGABLE_MAP KEY_VALUE_GENERIC_TYPE {
NAVIGABLE_MAP KEY_VALUE_GENERIC_TYPE map; NAVIGABLE_MAP KEY_VALUE_GENERIC_TYPE map;
/** SynchronizedNavigableMap(NAVIGABLE_MAP KEY_VALUE_GENERIC_TYPE map) {
* Default constructor
* @param map the map that should be synchronized
*/
public SynchronizedNavigableMap(NAVIGABLE_MAP KEY_VALUE_GENERIC_TYPE map) {
super(map); super(map);
this.map = map; this.map = map;
} }
/** SynchronizedNavigableMap(NAVIGABLE_MAP KEY_VALUE_GENERIC_TYPE map, Object mutex) {
* Constructor with Access Control
* @param map the map that should be synchronized
* @param mutex the access controller
*/
public SynchronizedNavigableMap(NAVIGABLE_MAP KEY_VALUE_GENERIC_TYPE map, Object mutex) {
super(map, mutex); super(map, mutex);
this.map = map; this.map = map;
} }
@ -677,21 +671,12 @@ public class MAPS
public static class SynchronizedSortedMap KEY_VALUE_GENERIC_TYPE extends SynchronizedMap KEY_VALUE_GENERIC_TYPE implements SORTED_MAP KEY_VALUE_GENERIC_TYPE { public static class SynchronizedSortedMap KEY_VALUE_GENERIC_TYPE extends SynchronizedMap KEY_VALUE_GENERIC_TYPE implements SORTED_MAP KEY_VALUE_GENERIC_TYPE {
SORTED_MAP KEY_VALUE_GENERIC_TYPE map; SORTED_MAP KEY_VALUE_GENERIC_TYPE map;
/** SynchronizedSortedMap(SORTED_MAP KEY_VALUE_GENERIC_TYPE map) {
* Default constructor
* @param map the map that should be synchronized
*/
public SynchronizedSortedMap(SORTED_MAP KEY_VALUE_GENERIC_TYPE map) {
super(map); super(map);
this.map = map; this.map = map;
} }
/** SynchronizedSortedMap(SORTED_MAP KEY_VALUE_GENERIC_TYPE map, Object mutex) {
* Constructor with Access Control
* @param map the map that should be synchronized
* @param mutex the access controller
*/
public SynchronizedSortedMap(SORTED_MAP KEY_VALUE_GENERIC_TYPE map, Object mutex) {
super(map, mutex); super(map, mutex);
this.map = map; this.map = map;
} }
@ -760,21 +745,12 @@ public class MAPS
protected Object mutex; protected Object mutex;
/** SynchronizedMap(MAP KEY_VALUE_GENERIC_TYPE map) {
* Default constructor
* @param map the map that should be synchronized
*/
public SynchronizedMap(MAP KEY_VALUE_GENERIC_TYPE map) {
this.map = map; this.map = map;
mutex = this; mutex = this;
} }
/** SynchronizedMap(MAP KEY_VALUE_GENERIC_TYPE map, Object mutex) {
* Constructor with Access Control
* @param map the map that should be synchronized
* @param mutex the access controller
*/
public SynchronizedMap(MAP KEY_VALUE_GENERIC_TYPE map, Object mutex) {
this.map = map; this.map = map;
this.mutex = mutex; this.mutex = mutex;
} }

View File

@ -1,45 +1,90 @@
package speiger.src.collections.utils; package speiger.src.collections.utils;
/**
* Helper class that is used for HashMap functions reduce duplicated code
*/
public class HashUtil public class HashUtil
{ {
/** Minimum HashMap Capacity */
public static final int DEFAULT_MIN_CAPACITY = 16; public static final int DEFAULT_MIN_CAPACITY = 16;
/** Default HashMap Load Factor */
public static final float DEFAULT_LOAD_FACTOR = 0.75F; public static final float DEFAULT_LOAD_FACTOR = 0.75F;
/** HashMap Load Factor with reduced hash collisions but more memory usage */
public static final float FAST_LOAD_FACTOR = 0.5F; public static final float FAST_LOAD_FACTOR = 0.5F;
/** HashMap Load Factor with minimal hash collisions but more memory usage */
public static final float FASTER_LOAD_FACTOR = 0.25F; public static final float FASTER_LOAD_FACTOR = 0.25F;
/** 2<sup>32</sup> &middot; &phi;, &phi; = (&#x221A;5 &minus; 1)/2. */
private static final int INT_PHI = 0x9E3779B9; private static final int INT_PHI = 0x9E3779B9;
/** The reciprocal of {@link #INT_PHI} modulo 2<sup>32</sup>. */
private static final int INV_INT_PHI = 0x144cbc89; private static final int INV_INT_PHI = 0x144cbc89;
/** Quickly mixes the bits of an integer.
*
* <p>This method mixes the bits of the argument by multiplying by the golden ratio and
* xorshifting the result. It is borrowed from <a href="https://github.com/leventov/Koloboke">Koloboke</a>,
*
* @param x an integer.
* @return a hash value obtained by mixing the bits of {@code x}.
* @see #invMix(int)
*/
public static int mix(final int x) { public static int mix(final int x) {
final int h = x * INT_PHI; final int h = x * INT_PHI;
return h ^ (h >>> 16); return h ^ (h >>> 16);
} }
/** The inverse of {@link #mix(int)}. This method is mainly useful to create unit tests.
*
* @param x an integer.
* @return a value that passed through {@link #mix(int)} would give {@code x}.
*/
public static int invMix(final int x) { public static int invMix(final int x) {
return (x ^ x >>> 16) * INV_INT_PHI; return (x ^ x >>> 16) * INV_INT_PHI;
} }
/**
* Function that rounds up to the closest power of 2
* A modified version of https://stackoverflow.com/a/466242
* @param x that should be converted to the next power of two
* @return the input number rounded up to the next power of two
*/
public static int nextPowerOfTwo(int x) { public static int nextPowerOfTwo(int x) {
if(x == 0) return 1; if(x != 0) {
x--; x--;
x |= x >> 1; x |= x >> 1;
x |= x >> 2; x |= x >> 2;
x |= x >> 4; x |= x >> 4;
x |= x >> 8; x |= x >> 8;
return (x | x >> 16) + 1; x |= x >> 16;
}
return x + 1;
} }
/**
* Function that rounds up to the closest power of 2
* A modified version of https://stackoverflow.com/a/466242
* @param x that should be converted to the next power of two
* @return the input number rounded up to the next power of two
*/
public static long nextPowerOfTwo(long x) { public static long nextPowerOfTwo(long x) {
if(x == 0) return 1L; if(x != 0) {
x--; x--;
x |= x >> 1; x |= x >> 1;
x |= x >> 2; x |= x >> 2;
x |= x >> 4; x |= x >> 4;
x |= x >> 8; x |= x >> 8;
x |= x >> 16; x |= x >> 16;
return (x | x >> 32) + 1L; x |= x >> 32;
}
return x + 1L;
} }
/**
* Helper function that creates the ideal array size for HashMap
* @param size the original array size
* @param loadFactor the load factor
* @return the new array size
*/
public static int arraySize(int size, float loadFactor) { public static int arraySize(int size, float loadFactor) {
return (int)Math.min(1 << 30, Math.max(2, nextPowerOfTwo((long)Math.ceil(size / loadFactor)))); return (int)Math.min(1 << 30, Math.max(2, nextPowerOfTwo((long)Math.ceil(size / loadFactor))));
} }

View File

@ -10,6 +10,7 @@ import java.util.concurrent.ForkJoinTask;
*/ */
public class SanityChecks public class SanityChecks
{ {
/** Max Possible ArraySize without the JVM Crashing */
public static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8; public static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
private static ForkJoinPool WORK_POOL = ForkJoinPool.commonPool(); private static ForkJoinPool WORK_POOL = ForkJoinPool.commonPool();
private static boolean FORCE_IGNORE_PARALLELISM = false; private static boolean FORCE_IGNORE_PARALLELISM = false;

View File

@ -1,10 +1,7 @@
package speiger.src.collections.ints.utils; package speiger.src.collections.ints.utils;
import java.util.Arrays; import java.util.Arrays;
import java.util.Spliterators;
import java.util.stream.IntStream; import java.util.stream.IntStream;
import java.util.stream.Stream;
import java.util.stream.StreamSupport;
import org.junit.Assert; import org.junit.Assert;
import org.junit.Test; import org.junit.Test;