Version 0.7.0 Release
- Added: Coverage Badge - Updated: Changelog. - Changed: Changelog now has info how to obtain the sourcecode. - Added: Over 11 Million Unit Tests to this library to ensure quality. - Added: ArrayList size constructor now throws IllegalStateException if the size parameter is negative - Added: EnumMap specialized forEach implementation. - Added: AbstractMap.remove now delegates to its primitive counterpart. - Added: ConcurrentHashMap now implements ITrimmable - Refactor: Removed a lot of disabled code from ArraySet. - Removed: LinkedList.addAll(index, List) now delegates to LinkedList.addAll(index, Collection) due to no special optimization required. - Fixed: AbstractList.SubList.get/set/swapRemove didn't calculate their List index Properly - Fixed: AbstractList.SubList chains now properly if you create SubLists within SubLists. - Fixed: AbstractList.Iterator.add now respects Immutable/UnmodifiableLists. - Fixed: AbstractList.Iterator.skip/back now keep track of the last returned value for remove function to work properly. - Fixed: CopyOnWriteArrayList.extract/removeElements(int, int) does now proper range checks and remove elements properly. - Fixed: CopyOnWriteArrayList.SubList now works properly. (Reimplemented entirely) - Fixed: CopyOnWriteArrayList.Iterator.previous() was returning the wrong values. - Fixed: CopyOnWriteArrayList.Iterator.skip now skips the right amount of elements and stops where it should. - Fixed: LinkedList.first/last/dequeue/dequeueLast now throws NoSuchElementException when empty instead of IllegalStateException. - Fixed: LinkedList had an edge case where the entire reverse iterator would break if the wrong element was removed. - Fixed: LinkedList.extractElement now returns the correct values. - Fixed: AbstractMap.entrySet().remove(Object) now returns true if defaultReturnValue elements were removed. - Fixed: ConcurrentHashMap.remove(Object, Object) checks if the type matches before comparing against null Values. - Fixed: LinkedHashMap.clearAndTrim() was checking the wrong value for determining the full reset or clearing of a Map. - Fixed: HashMap.trim/clearToTrim() was using the wrong value to determin if something should be done. - Fixed: HashMap now compares empty values (0) against nullKeys when Object Variants of the type are used. - Fixed: ImmutableMap now compares empty values (0) against nullKeys when Object Variants of the type are used. - Fixed: ArrayMap.iterator(key) now throws NoSuchElementException when the element wasn't found. - Fixed: Linked/EnumMap array constructor was creating the wrong size values array. - Fixed: LinkedEnumMap.getAndMoveToFirst/Last was moving elements even if the element wasn't present. - Fixed: AVL/RBTreeMap.getFirst/LastKey was not throwing a NoSuchElementException if the map was empty. - Fixed: Map.Builder wasn't throwing a IllegalStateException when creating a negative size builder. - Fixed: AVL/RBTreeSet.DecendingSet.subSet(from, fromInclusive, to, toInclusive) was creating a corrupt asending subset. - Fixed: ArraySet throws now a IllegalStateException when trying to create it with a negative size. - Fixed: ArraySet.addMoveToLast(key) was crashing when a key was already present. - Fixed: Immutable/LinkedHashSet now keep track of their iteration index properly. - Fixed: LinkedHashSet.moveToFirst/Last(key) would crash if the Set was empty. - Fixed: LinkedHashSet.clearAndTrim() was checking the wrong value for determining the full reset or clearing of a Map. - Fixed: HashSet.trim/clearToTrim() was using the wrong value to determin if something should be done.
This commit is contained in:
+15
-1
@@ -285,6 +285,16 @@ public abstract class ABSTRACT_MAP KEY_VALUE_GENERIC_TYPE extends AbstractMap<CL
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@Override
|
||||
public CLASS_VALUE_TYPE remove(Object key) {
|
||||
#if TYPE_OBJECT
|
||||
return VALUE_TO_OBJ(REMOVE_VALUE((CLASS_TYPE)key));
|
||||
#else
|
||||
return key instanceof CLASS_TYPE ? VALUE_TO_OBJ(REMOVE_VALUE(CLASS_TO_KEY(key))) : VALUE_TO_OBJ(getDefaultReturnValue());
|
||||
#endif
|
||||
}
|
||||
|
||||
@Override
|
||||
public void forEach(BI_CONSUMER KEY_VALUE_GENERIC_TYPE action) {
|
||||
Objects.requireNonNull(action);
|
||||
@@ -306,7 +316,11 @@ public abstract class ABSTRACT_MAP KEY_VALUE_GENERIC_TYPE extends AbstractMap<CL
|
||||
#else
|
||||
@Override
|
||||
public boolean remove(Object o) {
|
||||
return VALUE_EQUALS_NOT(ABSTRACT_MAP.this.remove(o), getDefaultReturnValue());
|
||||
if(ABSTRACT_MAP.this.containsKey(o)) {
|
||||
ABSTRACT_MAP.this.remove(o);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
+35
-3
@@ -73,6 +73,7 @@ import speiger.src.collections.objects.collections.ObjectBidirectionalIterator;
|
||||
import speiger.src.collections.objects.sets.AbstractObjectSet;
|
||||
import speiger.src.collections.objects.sets.ObjectSet;
|
||||
import speiger.src.collections.utils.HashUtil;
|
||||
import speiger.src.collections.utils.ITrimmable;
|
||||
|
||||
/**
|
||||
* A TypeSpecific ConcurrentHashMap implementation that is based on <a href="https://github.com/google/guava">Guavas</a> approach and backing array implementations.
|
||||
@@ -84,7 +85,7 @@ import speiger.src.collections.utils.HashUtil;
|
||||
* @Type(T)
|
||||
* @ValueType(V)
|
||||
*/
|
||||
public class CONCURRENT_HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_GENERIC_TYPE implements CONCURRENT_MAP KEY_VALUE_GENERIC_TYPE
|
||||
public class CONCURRENT_HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_GENERIC_TYPE implements CONCURRENT_MAP KEY_VALUE_GENERIC_TYPE, ITrimmable
|
||||
{
|
||||
/** Segment Limit */
|
||||
private static final int MAX_SEGMENTS = 1 << 16;
|
||||
@@ -538,6 +539,30 @@ public class CONCURRENT_HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean trim(int size) {
|
||||
int segmentCapacity = size / segments.length;
|
||||
if(segmentCapacity * segments.length < size) {
|
||||
segmentCapacity++;
|
||||
}
|
||||
boolean result = false;
|
||||
for(int i = 0, m=segments.length;i<m;i++) {
|
||||
result |= segments[i].trim(segmentCapacity);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clearAndTrim(int size) {
|
||||
int segmentCapacity = size / segments.length;
|
||||
if(segmentCapacity * segments.length < size) {
|
||||
segmentCapacity++;
|
||||
}
|
||||
for(int i = 0, m=segments.length;i<m;i++) {
|
||||
segments[i].clearAndTrim(segmentCapacity);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEmpty() {
|
||||
for(int i = 0,m=segments.length;i<m;i++) {
|
||||
@@ -2025,7 +2050,11 @@ public class CONCURRENT_HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY
|
||||
long stamp = writeLock();
|
||||
try
|
||||
{
|
||||
#if TYPE_OBJECT
|
||||
if(key == null) {
|
||||
#else
|
||||
if(key == null || (key instanceof CLASS_TYPE && KEY_EQUALS_NULL(CLASS_TO_KEY(key)))) {
|
||||
#endif
|
||||
if(containsNull && EQUALS_VALUE_TYPE(values[nullIndex], value)) {
|
||||
removeNullIndex();
|
||||
return true;
|
||||
@@ -2202,7 +2231,7 @@ public class CONCURRENT_HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY
|
||||
|
||||
protected boolean trim(int size) {
|
||||
int request = Math.max(minCapacity, HashUtil.nextPowerOfTwo((int)Math.ceil(size / loadFactor)));
|
||||
if(request >= size || this.size > Math.min((int)Math.ceil(request * loadFactor), request - 1)) return false;
|
||||
if(request >= mask+1 || this.size > Math.min((int)Math.ceil(request * loadFactor), request - 1)) return false;
|
||||
long stamp = writeLock();
|
||||
try {
|
||||
try {
|
||||
@@ -2218,7 +2247,7 @@ public class CONCURRENT_HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY
|
||||
|
||||
protected void clearAndTrim(int size) {
|
||||
int request = Math.max(minCapacity, HashUtil.nextPowerOfTwo((int)Math.ceil(size / loadFactor)));
|
||||
if(request >= size) {
|
||||
if(request >= mask+1) {
|
||||
clear();
|
||||
return;
|
||||
}
|
||||
@@ -2298,6 +2327,9 @@ public class CONCURRENT_HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY
|
||||
#endif
|
||||
protected int findIndex(int hash, Object key) {
|
||||
if(key == null) return containsNull ? nullIndex : -(nullIndex + 1);
|
||||
#if !TYPE_OBJECT
|
||||
if(KEY_EQUALS_NULL(CLASS_TO_KEY(key))) return containsNull ? nullIndex : -(nullIndex + 1);
|
||||
#endif
|
||||
int pos = hash & mask;
|
||||
KEY_TYPE current = keys[pos];
|
||||
if(KEY_EQUALS_NOT_NULL(current)) {
|
||||
|
||||
+3
-5
@@ -369,8 +369,7 @@ public class LINKED_CUSTOM_HASH_MAP KEY_VALUE_GENERIC_TYPE extends CUSTOM_HASH_M
|
||||
public KEY_TYPE POLL_FIRST_ENTRY_KEY() {
|
||||
if(size == 0) throw new NoSuchElementException();
|
||||
int pos = firstIndex;
|
||||
firstIndex = (int)links[pos];
|
||||
if(0 <= firstIndex) links[firstIndex] |= 0xFFFFFFFF00000000L;
|
||||
onNodeRemoved(pos);
|
||||
KEY_TYPE result = keys[pos];
|
||||
size--;
|
||||
if(strategy.equals(result, EMPTY_KEY_VALUE)) {
|
||||
@@ -393,8 +392,7 @@ public class LINKED_CUSTOM_HASH_MAP KEY_VALUE_GENERIC_TYPE extends CUSTOM_HASH_M
|
||||
public KEY_TYPE POLL_LAST_ENTRY_KEY() {
|
||||
if(size == 0) throw new NoSuchElementException();
|
||||
int pos = lastIndex;
|
||||
lastIndex = (int)(links[pos] >>> 32);
|
||||
if(0 <= lastIndex) links[lastIndex] |= 0xFFFFFFFFL;
|
||||
onNodeRemoved(pos);
|
||||
KEY_TYPE result = keys[pos];
|
||||
size--;
|
||||
if(strategy.equals(result, EMPTY_KEY_VALUE)) {
|
||||
@@ -455,7 +453,7 @@ public class LINKED_CUSTOM_HASH_MAP KEY_VALUE_GENERIC_TYPE extends CUSTOM_HASH_M
|
||||
@Override
|
||||
public void clearAndTrim(int size) {
|
||||
int request = Math.max(minCapacity, HashUtil.nextPowerOfTwo((int)Math.ceil(size / loadFactor)));
|
||||
if(request >= size) {
|
||||
if(request >= nullIndex) {
|
||||
clear();
|
||||
return;
|
||||
}
|
||||
|
||||
+9
-2
@@ -394,7 +394,11 @@ public class CUSTOM_HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VAL
|
||||
@Override
|
||||
public boolean remove(Object key, Object value) {
|
||||
Objects.requireNonNull(value);
|
||||
#if TYPE_OBJECT
|
||||
if(key == null) {
|
||||
#else
|
||||
if(key == null || (key instanceof CLASS_TYPE && strategy.equals(CLASS_TO_KEY(key), EMPTY_KEY_VALUE))) {
|
||||
#endif
|
||||
if(containsNull && EQUALS_VALUE_TYPE(values[nullIndex], value)) {
|
||||
removeNullIndex();
|
||||
return true;
|
||||
@@ -628,7 +632,7 @@ public class CUSTOM_HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VAL
|
||||
@Override
|
||||
public boolean trim(int size) {
|
||||
int request = Math.max(minCapacity, HashUtil.nextPowerOfTwo((int)Math.ceil(size / loadFactor)));
|
||||
if(request >= size || this.size > Math.min((int)Math.ceil(request * loadFactor), request - 1)) return false;
|
||||
if(request >= nullIndex || this.size > Math.min((int)Math.ceil(request * loadFactor), request - 1)) return false;
|
||||
try {
|
||||
rehash(request);
|
||||
}
|
||||
@@ -639,7 +643,7 @@ public class CUSTOM_HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VAL
|
||||
@Override
|
||||
public void clearAndTrim(int size) {
|
||||
int request = Math.max(minCapacity, HashUtil.nextPowerOfTwo((int)Math.ceil(size / loadFactor)));
|
||||
if(request >= size) {
|
||||
if(request >= nullIndex) {
|
||||
clear();
|
||||
return;
|
||||
}
|
||||
@@ -669,6 +673,9 @@ public class CUSTOM_HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VAL
|
||||
protected int findIndex(CLASS_TYPE key) {
|
||||
if(key == null) return containsNull ? nullIndex : -(nullIndex + 1);
|
||||
KEY_TYPE keyType = CLASS_TO_KEY(key);
|
||||
#if !TYPE_OBJECT
|
||||
if(strategy.equals(keyType, EMPTY_KEY_VALUE)) return containsNull ? nullIndex : -(nullIndex + 1);
|
||||
#endif
|
||||
int pos = HashUtil.mix(strategy.hashCode(keyType)) & mask;
|
||||
KEY_TYPE current = keys[pos];
|
||||
if(!strategy.equals(current, EMPTY_KEY_VALUE)) {
|
||||
|
||||
+3
-5
@@ -373,8 +373,7 @@ public class LINKED_HASH_MAP KEY_VALUE_GENERIC_TYPE extends HASH_MAP KEY_VALUE_G
|
||||
public KEY_TYPE POLL_FIRST_ENTRY_KEY() {
|
||||
if(size == 0) throw new NoSuchElementException();
|
||||
int pos = firstIndex;
|
||||
firstIndex = (int)links[pos];
|
||||
if(0 <= firstIndex) links[firstIndex] |= 0xFFFFFFFF00000000L;
|
||||
onNodeRemoved(pos);
|
||||
KEY_TYPE result = keys[pos];
|
||||
size--;
|
||||
if(KEY_EQUALS_NULL(result)) {
|
||||
@@ -397,8 +396,7 @@ public class LINKED_HASH_MAP KEY_VALUE_GENERIC_TYPE extends HASH_MAP KEY_VALUE_G
|
||||
public KEY_TYPE POLL_LAST_ENTRY_KEY() {
|
||||
if(size == 0) throw new NoSuchElementException();
|
||||
int pos = lastIndex;
|
||||
lastIndex = (int)(links[pos] >>> 32);
|
||||
if(0 <= lastIndex) links[lastIndex] |= 0xFFFFFFFFL;
|
||||
onNodeRemoved(pos);
|
||||
KEY_TYPE result = keys[pos];
|
||||
size--;
|
||||
if(KEY_EQUALS_NULL(result)) {
|
||||
@@ -459,7 +457,7 @@ public class LINKED_HASH_MAP KEY_VALUE_GENERIC_TYPE extends HASH_MAP KEY_VALUE_G
|
||||
@Override
|
||||
public void clearAndTrim(int size) {
|
||||
int request = Math.max(minCapacity, HashUtil.nextPowerOfTwo((int)Math.ceil(size / loadFactor)));
|
||||
if(request >= size) {
|
||||
if(request >= nullIndex) {
|
||||
clear();
|
||||
return;
|
||||
}
|
||||
|
||||
+9
-2
@@ -362,7 +362,11 @@ public class HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_GENE
|
||||
@Override
|
||||
public boolean remove(Object key, Object value) {
|
||||
Objects.requireNonNull(value);
|
||||
#if TYPE_OBJECT
|
||||
if(key == null) {
|
||||
#else
|
||||
if(key == null || (key instanceof CLASS_TYPE && KEY_EQUALS_NULL(CLASS_TO_KEY(key)))) {
|
||||
#endif
|
||||
if(containsNull && EQUALS_VALUE_TYPE(values[nullIndex], value)) {
|
||||
removeNullIndex();
|
||||
return true;
|
||||
@@ -589,7 +593,7 @@ public class HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_GENE
|
||||
@Override
|
||||
public boolean trim(int size) {
|
||||
int request = Math.max(minCapacity, HashUtil.nextPowerOfTwo((int)Math.ceil(size / loadFactor)));
|
||||
if(request >= size || this.size > Math.min((int)Math.ceil(request * loadFactor), request - 1)) return false;
|
||||
if(request >= nullIndex || this.size >= Math.min((int)Math.ceil(request * loadFactor), request - 1)) return false;
|
||||
try {
|
||||
rehash(request);
|
||||
}
|
||||
@@ -600,7 +604,7 @@ public class HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_GENE
|
||||
@Override
|
||||
public void clearAndTrim(int size) {
|
||||
int request = Math.max(minCapacity, HashUtil.nextPowerOfTwo((int)Math.ceil(size / loadFactor)));
|
||||
if(request >= size) {
|
||||
if(request >= nullIndex) {
|
||||
clear();
|
||||
return;
|
||||
}
|
||||
@@ -629,6 +633,9 @@ public class HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_GENE
|
||||
#endif
|
||||
protected int findIndex(Object key) {
|
||||
if(key == null) return containsNull ? nullIndex : -(nullIndex + 1);
|
||||
#if !TYPE_OBJECT
|
||||
if(key instanceof CLASS_TYPE && KEY_EQUALS_NULL(CLASS_TO_KEY(key))) return containsNull ? nullIndex : -(nullIndex + 1);
|
||||
#endif
|
||||
int pos = HashUtil.mix(key.hashCode()) & mask;
|
||||
KEY_TYPE current = keys[pos];
|
||||
if(KEY_EQUALS_NOT_NULL(current)) {
|
||||
|
||||
+3
@@ -517,6 +517,9 @@ public class IMMUTABLE_HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_
|
||||
#endif
|
||||
protected int findIndex(Object key) {
|
||||
if(key == null) return containsNull ? nullIndex : -(nullIndex + 1);
|
||||
#if !TYPE_OBJECT
|
||||
if(KEY_EQUALS_NULL(CLASS_TO_KEY(key))) return containsNull ? nullIndex : -(nullIndex + 1);
|
||||
#endif
|
||||
int pos = HashUtil.mix(key.hashCode()) & mask;
|
||||
KEY_TYPE current = keys[pos];
|
||||
if(KEY_EQUALS_NOT_NULL(current)) {
|
||||
|
||||
+2
@@ -1233,6 +1233,7 @@ public class ARRAY_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_GEN
|
||||
public EntryIterator() {}
|
||||
public EntryIterator(KEY_TYPE from) {
|
||||
index = findIndex(from);
|
||||
if(index == -1) throw new NoSuchElementException();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -1263,6 +1264,7 @@ public class ARRAY_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_GEN
|
||||
public KeyIterator() {}
|
||||
public KeyIterator(KEY_TYPE element) {
|
||||
index = findIndex(element);
|
||||
if(index == -1) throw new NoSuchElementException();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+13
-4
@@ -4,6 +4,7 @@ import java.util.Arrays;
|
||||
import java.util.Map;
|
||||
import java.util.NoSuchElementException;
|
||||
import java.util.Objects;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import speiger.src.collections.VALUE_PACKAGE.collections.VALUE_ABSTRACT_COLLECTION;
|
||||
import speiger.src.collections.VALUE_PACKAGE.collections.VALUE_COLLECTION;
|
||||
@@ -76,8 +77,8 @@ public class ENUM_MAP KEY_ENUM_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE
|
||||
if(keys.length != values.length) throw new IllegalArgumentException("Keys and Values have to be the same size");
|
||||
keyType = keys[0].getDeclaringClass();
|
||||
this.keys = getKeyUniverse(keyType);
|
||||
this.values = NEW_VALUE_ARRAY(keys.length);
|
||||
present = new long[((keys.length - 1) >> 6) + 1];
|
||||
this.values = NEW_VALUE_ARRAY(this.keys.length);
|
||||
present = new long[((this.keys.length - 1) >> 6) + 1];
|
||||
putAll(keys, values);
|
||||
}
|
||||
|
||||
@@ -93,8 +94,8 @@ public class ENUM_MAP KEY_ENUM_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE
|
||||
if(keys.length != values.length) throw new IllegalArgumentException("Keys and Values have to be the same size");
|
||||
keyType = keys[0].getDeclaringClass();
|
||||
this.keys = getKeyUniverse(keyType);
|
||||
this.values = NEW_VALUE_ARRAY(keys.length);
|
||||
present = new long[((keys.length - 1) >> 6) + 1];
|
||||
this.values = NEW_VALUE_ARRAY(this.keys.length);
|
||||
present = new long[((this.keys.length - 1) >> 6) + 1];
|
||||
putAll(keys, values);
|
||||
}
|
||||
|
||||
@@ -530,6 +531,14 @@ public class ENUM_MAP KEY_ENUM_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void forEach(Consumer<? super MAP.Entry KEY_VALUE_GENERIC_TYPE> action) {
|
||||
if(size() <= 0) return;
|
||||
for(int i = 0,m=keys.length;i<m;i++) {
|
||||
if(isSet(i)) action.accept(new BasicEntryKV_BRACES(keys[i], values[i]));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public ObjectIterator<MAP.Entry KEY_VALUE_GENERIC_TYPE> iterator() {
|
||||
return new EntryIterator();
|
||||
|
||||
+9
-8
@@ -66,9 +66,9 @@ public class LINKED_ENUM_MAP KEY_ENUM_VALUE_GENERIC_TYPE extends ENUM_MAP KEY_VA
|
||||
if(keys.length != values.length) throw new IllegalArgumentException("Keys and Values have to be the same size");
|
||||
keyType = keys[0].getDeclaringClass();
|
||||
this.keys = getKeyUniverse(keyType);
|
||||
this.values = NEW_VALUE_ARRAY(keys.length);
|
||||
present = new long[((keys.length - 1) >> 6) + 1];
|
||||
links = new long[keys.length];
|
||||
this.values = NEW_VALUE_ARRAY(this.keys.length);
|
||||
present = new long[((this.keys.length - 1) >> 6) + 1];
|
||||
links = new long[this.keys.length];
|
||||
putAll(keys, values);
|
||||
}
|
||||
|
||||
@@ -84,9 +84,9 @@ public class LINKED_ENUM_MAP KEY_ENUM_VALUE_GENERIC_TYPE extends ENUM_MAP KEY_VA
|
||||
if(keys.length != values.length) throw new IllegalArgumentException("Keys and Values have to be the same size");
|
||||
keyType = keys[0].getDeclaringClass();
|
||||
this.keys = getKeyUniverse(keyType);
|
||||
this.values = NEW_VALUE_ARRAY(keys.length);
|
||||
present = new long[((keys.length - 1) >> 6) + 1];
|
||||
links = new long[keys.length];
|
||||
this.values = NEW_VALUE_ARRAY(this.keys.length);
|
||||
present = new long[((this.keys.length - 1) >> 6) + 1];
|
||||
links = new long[this.keys.length];
|
||||
putAll(keys, values);
|
||||
}
|
||||
|
||||
@@ -239,7 +239,7 @@ public class LINKED_ENUM_MAP KEY_ENUM_VALUE_GENERIC_TYPE extends ENUM_MAP KEY_VA
|
||||
@Override
|
||||
public VALUE_TYPE getAndMoveToFirst(T key) {
|
||||
int index = key.ordinal();
|
||||
if(index < 0) return getDefaultReturnValue();
|
||||
if(!isSet(index)) return getDefaultReturnValue();
|
||||
moveToFirstIndex(index);
|
||||
return values[index];
|
||||
}
|
||||
@@ -247,7 +247,7 @@ public class LINKED_ENUM_MAP KEY_ENUM_VALUE_GENERIC_TYPE extends ENUM_MAP KEY_VA
|
||||
@Override
|
||||
public VALUE_TYPE getAndMoveToLast(T key) {
|
||||
int index = key.ordinal();
|
||||
if(index < 0) return getDefaultReturnValue();
|
||||
if(!isSet(index)) return getDefaultReturnValue();
|
||||
moveToLastIndex(index);
|
||||
return values[index];
|
||||
}
|
||||
@@ -828,6 +828,7 @@ public class LINKED_ENUM_MAP KEY_ENUM_VALUE_GENERIC_TYPE extends ENUM_MAP KEY_VA
|
||||
previous = from.ordinal() - 1;
|
||||
index = from.ordinal();
|
||||
next = from.ordinal();
|
||||
if(!isSet(index)) throw new NoSuchElementException();
|
||||
}
|
||||
|
||||
public boolean hasNext() {
|
||||
|
||||
+4
-2
@@ -1578,13 +1578,15 @@ public class AVL_TREE_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_
|
||||
@Override
|
||||
public VALUE_TYPE FIRST_ENTRY_VALUE() {
|
||||
Node KEY_VALUE_GENERIC_TYPE entry = subLowest();
|
||||
return entry == null ? map.getDefaultReturnValue() : entry.value;
|
||||
if(entry == null) throw new NoSuchElementException();
|
||||
return entry.value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public VALUE_TYPE LAST_ENTRY_VALUE() {
|
||||
Node KEY_VALUE_GENERIC_TYPE entry = subHighest();
|
||||
return entry == null ? map.getDefaultReturnValue() : entry.value;
|
||||
if(entry == null) throw new NoSuchElementException();
|
||||
return entry.value;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+4
-2
@@ -1645,13 +1645,15 @@ public class RB_TREE_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_G
|
||||
@Override
|
||||
public VALUE_TYPE FIRST_ENTRY_VALUE() {
|
||||
Node KEY_VALUE_GENERIC_TYPE entry = subLowest();
|
||||
return entry == null ? map.getDefaultReturnValue() : entry.value;
|
||||
if(entry == null) throw new NoSuchElementException();
|
||||
return entry.value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public VALUE_TYPE LAST_ENTRY_VALUE() {
|
||||
Node KEY_VALUE_GENERIC_TYPE entry = subHighest();
|
||||
return entry == null ? map.getDefaultReturnValue() : entry.value;
|
||||
if(entry == null) throw new NoSuchElementException();
|
||||
return entry.value;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+2
-1
@@ -557,8 +557,8 @@ public interface MAP KEY_VALUE_GENERIC_TYPE extends Map<CLASS_TYPE, CLASS_VALUE_
|
||||
*/
|
||||
public KEY_TYPE ENTRY_KEY();
|
||||
public default CLASS_TYPE getKey() { return KEY_TO_OBJ(ENTRY_KEY()); }
|
||||
#endif
|
||||
|
||||
#endif
|
||||
#if !VALUE_OBJECT
|
||||
/**
|
||||
* Type Specific getValue method that reduces boxing/unboxing
|
||||
@@ -1381,6 +1381,7 @@ public interface MAP KEY_VALUE_GENERIC_TYPE extends Map<CLASS_TYPE, CLASS_VALUE_
|
||||
* @param initialSize the requested start capacity
|
||||
*/
|
||||
public BuilderCache(int initialSize) {
|
||||
if(initialSize < 0) throw new IllegalStateException("Minimum Capacity is negative. This is not allowed");
|
||||
keys = NEW_KEY_ARRAY(initialSize);
|
||||
values = NEW_VALUE_ARRAY(initialSize);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user