Loads of new features & fixes.
- Added: pour function directly into Iterable which allows to collect all elements in the Iterable directly. - Added: The new ToArray method from Java9 and newer into the library. Using a functional interface. (Just a backport) - Changed: Reworked how the Map Builder functions are created. They are now in a SubClass that moves them out of the way. Less Clutter. (This might break things if that was used before) - Added: Map Builder that allows now to Build Maps like Guava ImmutableMaps can be build. Note: This has a slight performance overhead. - Added: Unmodifiable and Synchronize wrapper functions direclty into Collection Interfaces. This is mostly a quality of life thing. - Added: Unmodifiable and Synchronized Wrapper Collections can now be cloned. They clone the underlying map which doesn't break functionality. (Had a usecase for it) - Added: A boxed putAll array variant. - Fixed: EnumMaps didn't keep track of their size and now got proper care and implementations as needed. There might be more work required but at least the core functionality is now up to date.
This commit is contained in:
+9
@@ -90,6 +90,15 @@ public abstract class ABSTRACT_MAP KEY_VALUE_GENERIC_TYPE extends AbstractMap<CL
|
||||
for(int i = 0;i<size;i++) put(keys[i], values[i]);
|
||||
}
|
||||
|
||||
#if !TYPE_OBJECT || !VALUE_OBJECT
|
||||
@Override
|
||||
public void putAll(CLASS_TYPE[] keys, CLASS_VALUE_TYPE[] values, int offset, int size) {
|
||||
SanityChecks.checkArrayCapacity(keys.length, offset, size);
|
||||
SanityChecks.checkArrayCapacity(values.length, offset, size);
|
||||
for(int i = 0;i<size;i++) put(keys[i], values[i]);
|
||||
}
|
||||
|
||||
#endif
|
||||
@Override
|
||||
public void putAllIfAbsent(MAP KEY_VALUE_GENERIC_TYPE m) {
|
||||
for(MAP.Entry KEY_VALUE_GENERIC_TYPE entry : MAPS.fastIterable(m))
|
||||
|
||||
+2
-8
@@ -138,11 +138,7 @@ public class ARRAY_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_GEN
|
||||
public ARRAY_MAP(CLASS_TYPE[] keys, CLASS_VALUE_TYPE[] values, int length) {
|
||||
this(length);
|
||||
if(keys.length != values.length) throw new IllegalStateException("Input Arrays are not equal size");
|
||||
size = length;
|
||||
for(int i = 0,m=length;i<m;i++) {
|
||||
this.keys[i] = OBJ_TO_KEY(keys[i]);
|
||||
this.values[i] = OBJ_TO_VALUE(values[i]);
|
||||
}
|
||||
putAll(keys, values, 0, length);
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -165,9 +161,7 @@ public class ARRAY_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_GEN
|
||||
*/
|
||||
public ARRAY_MAP(KEY_TYPE[] keys, VALUE_TYPE[] values, int length) {
|
||||
if(keys.length != values.length) throw new IllegalStateException("Input Arrays are not equal size");
|
||||
this.keys = Arrays.copyOf(keys, length);
|
||||
this.values = Arrays.copyOf(values, length);
|
||||
this.size = length;
|
||||
putAll(keys, values, 0, length);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
+223
-8
@@ -3,9 +3,7 @@ package speiger.src.collections.PACKAGE.maps.impl.misc;
|
||||
import java.util.Arrays;
|
||||
import java.util.Map;
|
||||
import java.util.NoSuchElementException;
|
||||
#if VALUE_OBJECT
|
||||
import java.util.Objects;
|
||||
#endif
|
||||
|
||||
import speiger.src.collections.VALUE_PACKAGE.collections.VALUE_ABSTRACT_COLLECTION;
|
||||
import speiger.src.collections.VALUE_PACKAGE.collections.VALUE_COLLECTION;
|
||||
@@ -13,6 +11,14 @@ import speiger.src.collections.VALUE_PACKAGE.collections.VALUE_ITERATOR;
|
||||
#if !VALUE_OBJECT
|
||||
import speiger.src.collections.objects.collections.ObjectIterator;
|
||||
#endif
|
||||
import speiger.src.collections.VALUE_PACKAGE.functions.VALUE_SUPPLIER;
|
||||
import speiger.src.collections.VALUE_PACKAGE.functions.function.VALUE_UNARY_OPERATOR;
|
||||
import speiger.src.collections.PACKAGE.functions.consumer.BI_CONSUMER;
|
||||
#if !VALUE_OBJECT
|
||||
import speiger.src.collections.PACKAGE.functions.function.UNARY_OPERATOR;
|
||||
#endif
|
||||
import speiger.src.collections.PACKAGE.functions.function.FUNCTION;
|
||||
import speiger.src.collections.PACKAGE.utils.maps.MAPS;
|
||||
import speiger.src.collections.objects.maps.abstracts.ABSTRACT_MAP;
|
||||
import speiger.src.collections.objects.maps.interfaces.MAP;
|
||||
import speiger.src.collections.objects.sets.AbstractObjectSet;
|
||||
@@ -28,13 +34,13 @@ import speiger.src.collections.objects.sets.ObjectSet;
|
||||
public class ENUM_MAP KEY_ENUM_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_GENERIC_TYPE
|
||||
{
|
||||
/** Enum Type that is being used */
|
||||
protected final Class<T> keyType;
|
||||
protected Class<T> keyType;
|
||||
/** The Backing keys array. */
|
||||
protected transient final T[] keys;
|
||||
protected transient T[] keys;
|
||||
/** The Backing values array */
|
||||
protected transient final VALUE_TYPE[] values;
|
||||
protected transient VALUE_TYPE[] values;
|
||||
/** The Backing array that indicates which index is present or not */
|
||||
protected transient final long[] present;
|
||||
protected transient long[] present;
|
||||
/** Amount of Elements stored in the ArrayMap */
|
||||
protected int size = 0;
|
||||
/** EntrySet cache */
|
||||
@@ -44,6 +50,9 @@ public class ENUM_MAP KEY_ENUM_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE
|
||||
/** Values cache */
|
||||
protected transient VALUE_COLLECTION VALUE_GENERIC_TYPE valuesC;
|
||||
|
||||
protected ENUM_MAP() {
|
||||
|
||||
}
|
||||
/**
|
||||
* Default Constructor
|
||||
* @param keyType the type of Enum that should be used
|
||||
@@ -55,6 +64,86 @@ public class ENUM_MAP KEY_ENUM_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE
|
||||
present = new long[((keys.length - 1) >> 6) + 1];
|
||||
}
|
||||
|
||||
#if !VALUE_OBJECT
|
||||
/**
|
||||
* Helper constructor that allow to create a EnumMap from boxed values (it will unbox them)
|
||||
* @param keys the keys that should be put into the EnumMap
|
||||
* @param values the values that should be put into the EnumMap.
|
||||
* @throws IllegalStateException if the keys and values do not match in lenght
|
||||
*/
|
||||
public ENUM_MAP(T[] keys, CLASS_VALUE_TYPE[] values) {
|
||||
if(keys.length <= 0) throw new IllegalArgumentException("Empty Array are not allowed");
|
||||
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];
|
||||
putAll(keys, values);
|
||||
}
|
||||
|
||||
#endif
|
||||
/**
|
||||
* Helper constructor that allow to create a EnumMap from unboxed values
|
||||
* @param keys the keys that should be put into the map
|
||||
* @param values the values that should be put into the map.
|
||||
* @throws IllegalStateException if the keys and values do not match in lenght
|
||||
*/
|
||||
public ENUM_MAP(T[] keys, VALUE_TYPE[] values) {
|
||||
if(keys.length <= 0) throw new IllegalArgumentException("Empty Array are not allowed");
|
||||
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];
|
||||
putAll(keys, values);
|
||||
}
|
||||
|
||||
/**
|
||||
* A Helper constructor that allows to create a EnumMap with exactly the same values as the provided map.
|
||||
* @param map the values that should be present in the map
|
||||
*/
|
||||
public ENUM_MAP(Map<? extends CLASS_TYPE, ? extends CLASS_VALUE_TYPE> map) {
|
||||
if(map instanceof ENUM_MAP) {
|
||||
ENUM_MAP KEY_VALUE_GENERIC_TYPE enumMap = (ENUM_MAP KEY_VALUE_GENERIC_TYPE)map;
|
||||
keyType = enumMap.keyType;
|
||||
keys = enumMap.keys;
|
||||
values = enumMap.values.clone();
|
||||
present = enumMap.present.clone();
|
||||
size = enumMap.size;
|
||||
}
|
||||
else if(map.isEmpty()) throw new IllegalArgumentException("Empty Maps are not allowed");
|
||||
else {
|
||||
keyType = map.keySet().iterator().next().getDeclaringClass();
|
||||
this.keys = getKeyUniverse(keyType);
|
||||
this.values = NEW_VALUE_ARRAY(keys.length);
|
||||
present = new long[((keys.length - 1) >> 6) + 1];
|
||||
putAll(map);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A Type Specific Helper function that allows to create a new EnumMap with exactly the same values as the provided map.
|
||||
* @param map the values that should be present in the map
|
||||
*/
|
||||
public ENUM_MAP(MAP KEY_VALUE_GENERIC_TYPE map) {
|
||||
if(map instanceof ENUM_MAP) {
|
||||
ENUM_MAP KEY_VALUE_GENERIC_TYPE enumMap = (ENUM_MAP KEY_VALUE_GENERIC_TYPE)map;
|
||||
keyType = enumMap.keyType;
|
||||
keys = enumMap.keys;
|
||||
values = enumMap.values.clone();
|
||||
present = enumMap.present.clone();
|
||||
size = enumMap.size;
|
||||
}
|
||||
else if(map.isEmpty()) throw new IllegalArgumentException("Empty Maps are not allowed");
|
||||
else {
|
||||
keyType = map.keySet().iterator().next().getDeclaringClass();
|
||||
this.keys = getKeyUniverse(keyType);
|
||||
this.values = NEW_VALUE_ARRAY(keys.length);
|
||||
present = new long[((keys.length - 1) >> 6) + 1];
|
||||
putAll(map);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public VALUE_TYPE put(T key, VALUE_TYPE value) {
|
||||
int index = key.ordinal();
|
||||
@@ -203,6 +292,130 @@ public class ENUM_MAP KEY_ENUM_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE
|
||||
return valuesC;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void forEach(BI_CONSUMER KEY_VALUE_GENERIC_TYPE action) {
|
||||
if(size() <= 0) return;
|
||||
for(int i = 0,m=keys.length;i<m;i++) {
|
||||
if(isSet(i)) action.accept(keys[i], values[i]);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean replace(T key, VALUE_TYPE oldValue, VALUE_TYPE newValue) {
|
||||
int index = key.ordinal();
|
||||
if(!isSet(index) || values[index] != oldValue) return false;
|
||||
values[index] = newValue;
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public VALUE_TYPE replace(T key, VALUE_TYPE value) {
|
||||
int index = key.ordinal();
|
||||
if(!isSet(index)) return getDefaultReturnValue();
|
||||
VALUE_TYPE oldValue = values[index];
|
||||
values[index] = value;
|
||||
return oldValue;
|
||||
}
|
||||
|
||||
@Override
|
||||
public VALUE_TYPE COMPUTE(T key, UNARY_OPERATOR KEY_VALUE_GENERIC_TYPE mappingFunction) {
|
||||
int index = key.ordinal();
|
||||
if(!isSet(index)) {
|
||||
VALUE_TYPE newValue = mappingFunction.APPLY_VALUE(key, getDefaultReturnValue());
|
||||
if(VALUE_EQUALS(newValue, getDefaultReturnValue())) return newValue;
|
||||
set(index);
|
||||
values[index] = newValue;
|
||||
return newValue;
|
||||
}
|
||||
VALUE_TYPE newValue = mappingFunction.APPLY_VALUE(key, values[index]);
|
||||
if(VALUE_EQUALS(newValue, getDefaultReturnValue())) {
|
||||
clear(index);
|
||||
values[index] = EMPTY_VALUE;
|
||||
return newValue;
|
||||
}
|
||||
values[index] = newValue;
|
||||
return newValue;
|
||||
}
|
||||
|
||||
@Override
|
||||
public VALUE_TYPE COMPUTE_IF_ABSENT(T key, FUNCTION KEY_VALUE_GENERIC_TYPE mappingFunction) {
|
||||
int index = key.ordinal();
|
||||
if(!isSet(index)) {
|
||||
VALUE_TYPE newValue = mappingFunction.GET_VALUE(key);
|
||||
if(VALUE_EQUALS(newValue, getDefaultReturnValue())) return newValue;
|
||||
set(index);
|
||||
values[index] = newValue;
|
||||
return newValue;
|
||||
}
|
||||
return values[index];
|
||||
}
|
||||
|
||||
@Override
|
||||
public VALUE_TYPE SUPPLY_IF_ABSENT(T key, VALUE_SUPPLIER VALUE_GENERIC_TYPE valueProvider) {
|
||||
int index = key.ordinal();
|
||||
if(!isSet(index)) {
|
||||
VALUE_TYPE newValue = valueProvider.VALUE_GET_KEY();
|
||||
if(VALUE_EQUALS(newValue, getDefaultReturnValue())) return newValue;
|
||||
set(index);
|
||||
values[index] = newValue;
|
||||
return newValue;
|
||||
}
|
||||
return values[index];
|
||||
}
|
||||
|
||||
@Override
|
||||
public VALUE_TYPE COMPUTE_IF_PRESENT(T key, UNARY_OPERATOR KEY_VALUE_GENERIC_TYPE mappingFunction) {
|
||||
int index = key.ordinal();
|
||||
if(!isSet(index)) return getDefaultReturnValue();
|
||||
VALUE_TYPE newValue = mappingFunction.APPLY_VALUE(key, values[index]);
|
||||
if(VALUE_EQUALS(newValue, getDefaultReturnValue())) {
|
||||
clear(index);
|
||||
values[index] = EMPTY_VALUE;
|
||||
return newValue;
|
||||
}
|
||||
values[index] = newValue;
|
||||
return newValue;
|
||||
}
|
||||
|
||||
@Override
|
||||
public VALUE_TYPE MERGE(T key, VALUE_TYPE value, VALUE_UNARY_OPERATOR VALUE_VALUE_GENERIC_TYPE mappingFunction) {
|
||||
int index = key.ordinal();
|
||||
VALUE_TYPE newValue = !isSet(index) ? value : mappingFunction.APPLY_VALUE(values[index], value);
|
||||
if(VALUE_EQUALS(newValue, getDefaultReturnValue())) {
|
||||
if(isSet(index)) {
|
||||
clear(index);
|
||||
values[index] = EMPTY_VALUE;
|
||||
}
|
||||
}
|
||||
else if(!isSet(index)) {
|
||||
set(index);
|
||||
values[index] = newValue;
|
||||
}
|
||||
else values[index] = newValue;
|
||||
return newValue;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void BULK_MERGE(MAP KEY_VALUE_GENERIC_TYPE m, VALUE_UNARY_OPERATOR VALUE_VALUE_GENERIC_TYPE mappingFunction) {
|
||||
Objects.requireNonNull(mappingFunction);
|
||||
for(MAP.Entry KEY_VALUE_GENERIC_TYPE entry : MAPS.fastIterable(m)) {
|
||||
T key = entry.ENTRY_KEY();
|
||||
int index = key.ordinal();
|
||||
VALUE_TYPE newValue = !isSet(index) ? entry.ENTRY_VALUE() : mappingFunction.APPLY_VALUE(values[index], entry.ENTRY_VALUE());
|
||||
if(VALUE_EQUALS(newValue, getDefaultReturnValue())) {
|
||||
if(isSet(index)) {
|
||||
clear(index);
|
||||
values[index] = EMPTY_VALUE;
|
||||
}
|
||||
}
|
||||
else if(!isSet(index)) {
|
||||
set(index);
|
||||
values[index] = newValue;
|
||||
}
|
||||
else values[index] = newValue;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clear() {
|
||||
if(size == 0) return;
|
||||
@@ -219,17 +432,19 @@ public class ENUM_MAP KEY_ENUM_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE
|
||||
|
||||
}
|
||||
|
||||
protected void set(int index) {
|
||||
protected void set(int index) {
|
||||
size++;
|
||||
present[index >> 6] |= (1L << index);
|
||||
onNodeAdded(index);
|
||||
}
|
||||
protected void clear(int index) {
|
||||
size--;
|
||||
present[index >> 6] &= ~(1L << index);
|
||||
onNodeRemoved(index);
|
||||
}
|
||||
protected boolean isSet(int index) { return (present[index >> 6] & (1L << index)) != 0; }
|
||||
|
||||
private static <K extends Enum<K>> K[] getKeyUniverse(Class<K> keyType) {
|
||||
protected static <K extends Enum<K>> K[] getKeyUniverse(Class<K> keyType) {
|
||||
return keyType.getEnumConstants();
|
||||
}
|
||||
|
||||
|
||||
+130
@@ -59,6 +59,136 @@ public class LINKED_ENUM_MAP KEY_ENUM_VALUE_GENERIC_TYPE extends ENUM_MAP KEY_VA
|
||||
links = new long[keys.length];
|
||||
}
|
||||
|
||||
#if !VALUE_OBJECT
|
||||
/**
|
||||
* Helper constructor that allow to create a EnumMap from boxed values (it will unbox them)
|
||||
* @param keys the keys that should be put into the EnumMap
|
||||
* @param values the values that should be put into the EnumMap.
|
||||
* @throws IllegalStateException if the keys and values do not match in lenght
|
||||
*/
|
||||
public LINKED_ENUM_MAP(T[] keys, CLASS_VALUE_TYPE[] values) {
|
||||
if(keys.length <= 0) throw new IllegalArgumentException("Empty Array are not allowed");
|
||||
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];
|
||||
putAll(keys, values);
|
||||
}
|
||||
|
||||
#endif
|
||||
/**
|
||||
* Helper constructor that allow to create a EnumMap from unboxed values
|
||||
* @param keys the keys that should be put into the map
|
||||
* @param values the values that should be put into the map.
|
||||
* @throws IllegalStateException if the keys and values do not match in lenght
|
||||
*/
|
||||
public LINKED_ENUM_MAP(T[] keys, VALUE_TYPE[] values) {
|
||||
if(keys.length <= 0) throw new IllegalArgumentException("Empty Array are not allowed");
|
||||
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];
|
||||
putAll(keys, values);
|
||||
}
|
||||
|
||||
/**
|
||||
* A Helper constructor that allows to create a EnumMap with exactly the same values as the provided map.
|
||||
* @param map the values that should be present in the map
|
||||
*/
|
||||
public LINKED_ENUM_MAP(Map<? extends CLASS_TYPE, ? extends CLASS_VALUE_TYPE> map) {
|
||||
if(map instanceof LINKED_ENUM_MAP) {
|
||||
LINKED_ENUM_MAP KEY_VALUE_GENERIC_TYPE enumMap = (LINKED_ENUM_MAP KEY_VALUE_GENERIC_TYPE)map;
|
||||
keyType = enumMap.keyType;
|
||||
keys = enumMap.keys;
|
||||
values = enumMap.values.clone();
|
||||
present = enumMap.present.clone();
|
||||
links = enumMap.links.clone();
|
||||
size = enumMap.size;
|
||||
}
|
||||
if(map instanceof ENUM_MAP) {
|
||||
ENUM_MAP KEY_VALUE_GENERIC_TYPE enumMap = (ENUM_MAP KEY_VALUE_GENERIC_TYPE)map;
|
||||
keyType = enumMap.keyType;
|
||||
keys = enumMap.keys;
|
||||
values = enumMap.values.clone();
|
||||
present = enumMap.present.clone();
|
||||
links = new long[keys.length];
|
||||
for(int i = 0,m=keys.length;i<m;i++) {
|
||||
if(isSet(i)) {
|
||||
if(size == 0) {
|
||||
firstIndex = lastIndex = i;
|
||||
links[i] = -1L;
|
||||
}
|
||||
else {
|
||||
links[lastIndex] ^= ((links[lastIndex] ^ (i & 0xFFFFFFFFL)) & 0xFFFFFFFFL);
|
||||
links[i] = ((lastIndex & 0xFFFFFFFFL) << 32) | 0xFFFFFFFFL;
|
||||
lastIndex = i;
|
||||
}
|
||||
size++;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(map.isEmpty()) throw new IllegalArgumentException("Empty Maps are not allowed");
|
||||
else {
|
||||
keyType = map.keySet().iterator().next().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];
|
||||
putAll(map);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A Type Specific Helper function that allows to create a new EnumMap with exactly the same values as the provided map.
|
||||
* @param map the values that should be present in the map
|
||||
*/
|
||||
public LINKED_ENUM_MAP(MAP KEY_VALUE_GENERIC_TYPE map) {
|
||||
if(map instanceof LINKED_ENUM_MAP) {
|
||||
LINKED_ENUM_MAP KEY_VALUE_GENERIC_TYPE enumMap = (LINKED_ENUM_MAP KEY_VALUE_GENERIC_TYPE)map;
|
||||
keyType = enumMap.keyType;
|
||||
keys = enumMap.keys;
|
||||
values = enumMap.values.clone();
|
||||
present = enumMap.present.clone();
|
||||
links = enumMap.links.clone();
|
||||
size = enumMap.size;
|
||||
}
|
||||
if(map instanceof ENUM_MAP) {
|
||||
ENUM_MAP KEY_VALUE_GENERIC_TYPE enumMap = (ENUM_MAP KEY_VALUE_GENERIC_TYPE)map;
|
||||
keyType = enumMap.keyType;
|
||||
keys = enumMap.keys;
|
||||
values = enumMap.values.clone();
|
||||
present = enumMap.present.clone();
|
||||
links = new long[keys.length];
|
||||
for(int i = 0,m=keys.length;i<m;i++) {
|
||||
if(isSet(i)) {
|
||||
if(size == 0) {
|
||||
firstIndex = lastIndex = i;
|
||||
links[i] = -1L;
|
||||
}
|
||||
else {
|
||||
links[lastIndex] ^= ((links[lastIndex] ^ (i & 0xFFFFFFFFL)) & 0xFFFFFFFFL);
|
||||
links[i] = ((lastIndex & 0xFFFFFFFFL) << 32) | 0xFFFFFFFFL;
|
||||
lastIndex = i;
|
||||
}
|
||||
size++;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(map.isEmpty()) throw new IllegalArgumentException("Empty Maps are not allowed");
|
||||
else {
|
||||
keyType = map.keySet().iterator().next().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];
|
||||
putAll(map);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public VALUE_TYPE putAndMoveToFirst(T key, VALUE_TYPE value) {
|
||||
int index = key.ordinal();
|
||||
|
||||
+1043
-505
File diff suppressed because it is too large
Load Diff
+23
@@ -2,6 +2,7 @@ package speiger.src.collections.PACKAGE.maps.interfaces;
|
||||
|
||||
import java.util.NavigableMap;
|
||||
import speiger.src.collections.PACKAGE.sets.NAVIGABLE_SET;
|
||||
import speiger.src.collections.PACKAGE.utils.maps.MAPS;
|
||||
|
||||
/**
|
||||
* A Type Specific Navigable Map interface with a couple helper methods
|
||||
@@ -34,6 +35,28 @@ public interface NAVIGABLE_MAP KEY_VALUE_GENERIC_TYPE extends SORTED_MAP KEY_VAL
|
||||
@Override
|
||||
public MAP.Entry KEY_VALUE_GENERIC_TYPE pollLastEntry();
|
||||
|
||||
/**
|
||||
* Creates a Wrapped NavigableMap that is Synchronized
|
||||
* @return a new NavigableMap that is synchronized
|
||||
* @see MAPS#synchronize
|
||||
*/
|
||||
public default NAVIGABLE_MAP KEY_VALUE_GENERIC_TYPE synchronize() { return MAPS.synchronize(this); }
|
||||
|
||||
/**
|
||||
* Creates a Wrapped NavigableMap that is Synchronized
|
||||
* @param mutex is the controller of the synchronization block
|
||||
* @return a new NavigableMap Wrapper that is synchronized
|
||||
* @see MAPS#synchronize
|
||||
*/
|
||||
public default NAVIGABLE_MAP KEY_VALUE_GENERIC_TYPE synchronize(Object mutex) { return MAPS.synchronize(this, mutex); }
|
||||
|
||||
/**
|
||||
* Creates a Wrapped NavigableMap that is unmodifiable
|
||||
* @return a new NavigableMap Wrapper that is unmodifiable
|
||||
* @see MAPS#unmodifiable
|
||||
*/
|
||||
public default NAVIGABLE_MAP KEY_VALUE_GENERIC_TYPE unmodifiable() { return MAPS.unmodifiable(this); }
|
||||
|
||||
#if !TYPE_OBJECT
|
||||
/**
|
||||
* A Type Specific SubMap method to reduce boxing/unboxing
|
||||
|
||||
+23
@@ -10,6 +10,7 @@ import speiger.src.collections.VALUE_PACKAGE.collections.VALUE_COLLECTION;
|
||||
import speiger.src.collections.PACKAGE.functions.COMPARATOR;
|
||||
#endif
|
||||
import speiger.src.collections.PACKAGE.sets.SET;
|
||||
import speiger.src.collections.PACKAGE.utils.maps.MAPS;
|
||||
import speiger.src.collections.objects.sets.ObjectSortedSet;
|
||||
import speiger.src.collections.objects.collections.ObjectBidirectionalIterator;
|
||||
|
||||
@@ -83,6 +84,28 @@ public interface SORTED_MAP KEY_VALUE_GENERIC_TYPE extends SortedMap<CLASS_TYPE,
|
||||
@Override
|
||||
public VALUE_COLLECTION VALUE_GENERIC_TYPE values();
|
||||
|
||||
/**
|
||||
* Creates a Wrapped SortedMap that is Synchronized
|
||||
* @return a new SortedMap that is synchronized
|
||||
* @see MAPS#synchronize
|
||||
*/
|
||||
public default SORTED_MAP KEY_VALUE_GENERIC_TYPE synchronize() { return MAPS.synchronize(this); }
|
||||
|
||||
/**
|
||||
* Creates a Wrapped SortedMap that is Synchronized
|
||||
* @param mutex is the controller of the synchronization block
|
||||
* @return a new SortedMap Wrapper that is synchronized
|
||||
* @see MAPS#synchronize
|
||||
*/
|
||||
public default SORTED_MAP KEY_VALUE_GENERIC_TYPE synchronize(Object mutex) { return MAPS.synchronize(this, mutex); }
|
||||
|
||||
/**
|
||||
* Creates a Wrapped SortedMap that is unmodifiable
|
||||
* @return a new SortedMap Wrapper that is unmodifiable
|
||||
* @see MAPS#unmodifiable
|
||||
*/
|
||||
public default SORTED_MAP KEY_VALUE_GENERIC_TYPE unmodifiable() { return MAPS.unmodifiable(this); }
|
||||
|
||||
#if !TYPE_OBJECT
|
||||
/**
|
||||
* A Type Specific SubMap method to reduce boxing/unboxing
|
||||
|
||||
Reference in New Issue
Block a user