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:
2022-06-12 14:31:45 +02:00
parent 8b5e5a75c1
commit ddc58ee221
28 changed files with 642 additions and 539 deletions
@@ -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
@@ -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)) {
@@ -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;
}
@@ -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)) {
@@ -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;
}
@@ -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)) {
@@ -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)) {
@@ -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
@@ -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();
@@ -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() {
@@ -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
@@ -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
@@ -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);
}