From 06752fe30cd2c1ec6ca05584cd72615e4c9a44c8 Mon Sep 17 00:00:00 2001 From: Speiger Date: Sat, 24 Apr 2021 16:48:36 +0200 Subject: [PATCH] Added Singletons & Empty variants of Collections --- .../speiger/src/builder/GlobalVariables.java | 1 + .../builder/PrimitiveCollectionsBuilder.java | 2 +- .../templates/lists/ArrayList.template | 2 +- .../maps/interfaces/NavigableMap.template | 9 + .../maps/interfaces/SortedMap.template | 9 +- .../templates/queues/ArrayFIFOQueue.template | 3 +- .../templates/utils/Arrays.template | 10 +- .../templates/utils/Lists.template | 59 ++ .../collections/templates/utils/Sets.template | 51 +- .../templates/utils/maps/Maps.template | 669 +++++++++++++++++- 10 files changed, 804 insertions(+), 11 deletions(-) diff --git a/src/builder/java/speiger/src/builder/GlobalVariables.java b/src/builder/java/speiger/src/builder/GlobalVariables.java index b884464f..86498b70 100644 --- a/src/builder/java/speiger/src/builder/GlobalVariables.java +++ b/src/builder/java/speiger/src/builder/GlobalVariables.java @@ -46,6 +46,7 @@ public class GlobalVariables addSimpleMapper(" KEY_VALUE_GENERIC_TYPE", type.isObject() ? (valueType.isObject() ? "<"+type.getKeyType()+", "+valueType.getValueType()+">" : "<"+type.getKeyType()+">") : (valueType.isObject() ? "<"+valueType.getValueType()+">" : "")); addSimpleMapper(" KEY_VALUE_VALUE_GENERIC_TYPE", type.isObject() ? (valueType.isObject() ? "<"+type.getKeyType()+", "+valueType.getValueType()+", "+valueType.getValueType()+">" : "<"+type.getKeyType()+">") : (valueType.isObject() ? "<"+valueType.getValueType()+", "+valueType.getValueType()+">" : "")); addSimpleMapper(" NO_GENERIC_TYPE", type.isObject() ? "" : ""); + addSimpleMapper(" NO_KV_GENERIC_TYPE", type.isObject() ? (valueType.isObject() ? "" : "") : valueType.isObject() ? "" : ""); addSimpleMapper(" KEY_COMPAREABLE_TYPE", type.isObject() ? "<"+type.getKeyType()+" extends Comparable>" : ""); addSimpleMapper(" KEY_SUPER_GENERIC_TYPE", type.isObject() ? "" : ""); addSimpleMapper(" VALUE_SUPER_GENERIC_TYPE", valueType.isObject() ? "" : ""); diff --git a/src/builder/java/speiger/src/builder/PrimitiveCollectionsBuilder.java b/src/builder/java/speiger/src/builder/PrimitiveCollectionsBuilder.java index 74908f44..4df5fc6b 100644 --- a/src/builder/java/speiger/src/builder/PrimitiveCollectionsBuilder.java +++ b/src/builder/java/speiger/src/builder/PrimitiveCollectionsBuilder.java @@ -77,7 +77,7 @@ public class PrimitiveCollectionsBuilder extends TemplateProcessor nameRemapper.put("AbstractList", "Abstract%sList"); nameRemapper.put("EnumMap", "Enum2%sMap"); addBlockage(ClassType.OBJECT, "Consumer", "Comparator", "Stack"); - addBlockage(ClassType.BOOLEAN, "Sets", "ArraySet", "AVLTreeSet", "RBTreeSet", "SortedSet", "NavigableSet", "OpenHashSet", "OpenCustomHashSet", "LinkedOpenHashSet", "LinkedOpenCustomHashSet"); + addBlockage(ClassType.BOOLEAN, "ArraySet", "AVLTreeSet", "RBTreeSet", "SortedSet", "NavigableSet", "OpenHashSet", "OpenCustomHashSet", "LinkedOpenHashSet", "LinkedOpenCustomHashSet"); addBlockage(ClassType.BOOLEAN, "SortedMap", "NavigableMap", "OpenHashMap", "LinkedOpenHashMap", "OpenCustomHashMap", "LinkedOpenCustomHashMap", "ArrayMap", "RBTreeMap", "AVLTreeMap"); } diff --git a/src/builder/resources/speiger/assets/collections/templates/lists/ArrayList.template b/src/builder/resources/speiger/assets/collections/templates/lists/ArrayList.template index 35e09644..7d3f933f 100644 --- a/src/builder/resources/speiger/assets/collections/templates/lists/ArrayList.template +++ b/src/builder/resources/speiger/assets/collections/templates/lists/ArrayList.template @@ -611,7 +611,7 @@ public class ARRAY_LIST KEY_GENERIC_TYPE extends ABSTRACT_LIST KEY_GENERIC_TYPE #if TYPE_BYTE || TYPE_SHORT || TYPE_CHAR || TYPE_FLOAT data[i] = SanityChecks.SANITY_CAST(o.APPLY_CAST(data[i])); #else - data[i] = o.APPLY(data[i]); + data[i] = o.APPLY(data[i]); #endif } diff --git a/src/builder/resources/speiger/assets/collections/templates/maps/interfaces/NavigableMap.template b/src/builder/resources/speiger/assets/collections/templates/maps/interfaces/NavigableMap.template index 7b32e493..bde1704e 100644 --- a/src/builder/resources/speiger/assets/collections/templates/maps/interfaces/NavigableMap.template +++ b/src/builder/resources/speiger/assets/collections/templates/maps/interfaces/NavigableMap.template @@ -79,6 +79,15 @@ public interface NAVIGABLE_MAP KEY_VALUE_GENERIC_TYPE extends SORTED_MAP KEY_VAL @Override default NAVIGABLE_MAP KEY_VALUE_GENERIC_TYPE tailMap(CLASS_TYPE fromKey) { return tailMap(OBJ_TO_KEY(fromKey), true); } #else + @Override + default MAP.Entry KEY_VALUE_GENERIC_TYPE lowerEntry(CLASS_TYPE key) { return lowerEntry(OBJ_TO_KEY(key)); } + @Override + default MAP.Entry KEY_VALUE_GENERIC_TYPE floorEntry(CLASS_TYPE key) { return floorEntry(OBJ_TO_KEY(key)); } + @Override + default MAP.Entry KEY_VALUE_GENERIC_TYPE ceilingEntry(CLASS_TYPE key) { return ceilingEntry(OBJ_TO_KEY(key)); } + @Override + default MAP.Entry KEY_VALUE_GENERIC_TYPE higherEntry(CLASS_TYPE key) { return higherEntry(OBJ_TO_KEY(key)); } + @Override public NAVIGABLE_MAP KEY_VALUE_GENERIC_TYPE subMap(CLASS_TYPE fromKey, boolean fromInclusive, CLASS_TYPE toKey, boolean toInclusive); @Override diff --git a/src/builder/resources/speiger/assets/collections/templates/maps/interfaces/SortedMap.template b/src/builder/resources/speiger/assets/collections/templates/maps/interfaces/SortedMap.template index e5528a21..40457d41 100644 --- a/src/builder/resources/speiger/assets/collections/templates/maps/interfaces/SortedMap.template +++ b/src/builder/resources/speiger/assets/collections/templates/maps/interfaces/SortedMap.template @@ -62,7 +62,14 @@ public interface SORTED_MAP KEY_VALUE_GENERIC_TYPE extends SortedMap { diff --git a/src/builder/resources/speiger/assets/collections/templates/queues/ArrayFIFOQueue.template b/src/builder/resources/speiger/assets/collections/templates/queues/ArrayFIFOQueue.template index c7aa2c0b..5931f21a 100644 --- a/src/builder/resources/speiger/assets/collections/templates/queues/ArrayFIFOQueue.template +++ b/src/builder/resources/speiger/assets/collections/templates/queues/ArrayFIFOQueue.template @@ -268,7 +268,8 @@ public class ARRAY_FIFO_QUEUE KEY_GENERIC_TYPE implements PRIORITY_DEQUEUE KEY_G @Override public KEY_TYPE NEXT() { KEY_TYPE value = array[index]; - removeIndex(index++); + removeIndex(index); + index = ++index % array.length; return value; } } diff --git a/src/builder/resources/speiger/assets/collections/templates/utils/Arrays.template b/src/builder/resources/speiger/assets/collections/templates/utils/Arrays.template index 93e2139d..22578d13 100644 --- a/src/builder/resources/speiger/assets/collections/templates/utils/Arrays.template +++ b/src/builder/resources/speiger/assets/collections/templates/utils/Arrays.template @@ -345,11 +345,11 @@ public class ARRAYS public static GENERIC_KEY_BRACES void insertionSort(KEY_TYPE[] array, int from, int to, COMPARATOR KEY_GENERIC_TYPE comp) { for (int i = from+1;i= from && comp.compare(current, array[j]) < 0) { - array[j+1] = array[j--]; - } - array[j+1] = current; + int j = i - 1; + while(j >= from && comp.compare(current, array[j]) < 0) { + array[j+1] = array[j--]; + } + array[j+1] = current; } } diff --git a/src/builder/resources/speiger/assets/collections/templates/utils/Lists.template b/src/builder/resources/speiger/assets/collections/templates/utils/Lists.template index a0061c28..9f8f602d 100644 --- a/src/builder/resources/speiger/assets/collections/templates/utils/Lists.template +++ b/src/builder/resources/speiger/assets/collections/templates/utils/Lists.template @@ -9,6 +9,7 @@ import speiger.src.collections.PACKAGE.collections.COLLECTION; #if !TYPE_OBJECT import speiger.src.collections.PACKAGE.functions.CONSUMER; #endif +import speiger.src.collections.PACKAGE.lists.ABSTRACT_LIST; import speiger.src.collections.PACKAGE.lists.LIST; import speiger.src.collections.PACKAGE.lists.LIST_ITERATOR; @@ -59,6 +60,64 @@ public class LISTS return l instanceof SynchronizedList ? l : (l instanceof IARRAY ? new SynchronizedArrayListBRACES(l, mutex) : (l instanceof RandomAccess ? new SynchronizedRandomAccessListBRACES(l, mutex) : new SynchronizedListBRACES(l, mutex))); } + /** + * Creates a Unmodifiable Singleton list + * @param element that should be used in the Singleton + * @return a singleton list that is unmodifiable + */ + public static GENERIC_KEY_BRACES LIST KEY_GENERIC_TYPE singletonList(KEY_TYPE element) { + return new SingletonListBRACES(element); + } + + public static class SingletonList KEY_GENERIC_TYPE extends ABSTRACT_LIST KEY_GENERIC_TYPE + { + KEY_TYPE element; + + public SingletonList(KEY_TYPE element) + { + this.element = element; + } + @Override + public void add(int index, KEY_TYPE e) { throw new UnsupportedOperationException(); } + @Override + public boolean addAll(int index, Collection c) { throw new UnsupportedOperationException(); } + @Override + public boolean addAll(int index, COLLECTION KEY_GENERIC_TYPE c) { throw new UnsupportedOperationException(); } + @Override + public boolean addAll(int index, LIST KEY_GENERIC_TYPE c) { throw new UnsupportedOperationException(); } + + @Override + public KEY_TYPE GET_KEY(int index) { + if(index == 0) return element; + throw new IndexOutOfBoundsException(); + } + + @Override + public KEY_TYPE set(int index, KEY_TYPE e) { throw new UnsupportedOperationException(); } + @Override + public KEY_TYPE REMOVE(int index) { throw new UnsupportedOperationException(); } + @Override + public void addElements(int from, KEY_TYPE[] a, int offset, int length) { throw new UnsupportedOperationException(); } + @Override + public KEY_TYPE[] getElements(int from, KEY_TYPE[] a, int offset, int length) { + if(from != 0 || length != 1) throw new IndexOutOfBoundsException(); + a[offset] = element; + return a; + } + + @Override + public void removeElements(int from, int to) { throw new UnsupportedOperationException(); } +#if TYPE_OBJECT + @Override + public K[] extractElements(int from, int to, Class type) { throw new UnsupportedOperationException(); } +#else + @Override + public KEY_TYPE[] extractElements(int from, int to) { throw new UnsupportedOperationException(); } +#endif + @Override + public int size() { return 1; } + } + public static class SynchronizedArrayList KEY_GENERIC_TYPE extends SynchronizedList KEY_GENERIC_TYPE implements IARRAY KEY_GENERIC_TYPE { IARRAY KEY_GENERIC_TYPE l; diff --git a/src/builder/resources/speiger/assets/collections/templates/utils/Sets.template b/src/builder/resources/speiger/assets/collections/templates/utils/Sets.template index fa15ed85..5196afd4 100644 --- a/src/builder/resources/speiger/assets/collections/templates/utils/Sets.template +++ b/src/builder/resources/speiger/assets/collections/templates/utils/Sets.template @@ -1,5 +1,11 @@ package speiger.src.collections.PACKAGE.utils; +#if TYPE_BOOLEAN +import speiger.src.collections.booleans.collections.BooleanIterator; +import speiger.src.collections.booleans.sets.AbstractBooleanSet; +import speiger.src.collections.booleans.sets.BooleanSet; +import speiger.src.collections.booleans.utils.BooleanCollections.EmptyCollection; +#else #if TYPE_OBJECT import java.util.Comparator; @@ -8,13 +14,16 @@ import speiger.src.collections.PACKAGE.collections.BI_ITERATOR; #if !TYPE_OBJECT import speiger.src.collections.PACKAGE.functions.COMPARATOR; #endif +import speiger.src.collections.PACKAGE.collections.ITERATOR; import speiger.src.collections.PACKAGE.sets.NAVIGABLE_SET; +import speiger.src.collections.PACKAGE.sets.ABSTRACT_SET; import speiger.src.collections.PACKAGE.sets.SET; import speiger.src.collections.PACKAGE.sets.SORTED_SET; import speiger.src.collections.PACKAGE.utils.COLLECTIONS.EmptyCollection; import speiger.src.collections.PACKAGE.utils.COLLECTIONS.SynchronizedCollection; import speiger.src.collections.PACKAGE.utils.COLLECTIONS.UnmodifiableCollection; import speiger.src.collections.utils.ITrimmable; +#endif public class SETS { @@ -28,6 +37,7 @@ public class SETS #endif } +#if !TYPE_BOOLEAN 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)); } @@ -64,6 +74,44 @@ public class SETS return s instanceof UnmodifiableNavigableSet ? s : new UnmodifiableNavigableSetBRACES(s); } +#endif + public static GENERIC_KEY_BRACES SET KEY_GENERIC_TYPE singletonSet(KEY_TYPE element) { + return new SingletonSetBRACES(element); + } + + public static class SingletonSet KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_TYPE + { + KEY_TYPE element; + + public SingletonSet(KEY_TYPE element) { + this.element = element; + } + +#if !TYPE_OBJECT + @Override + public boolean remove(KEY_TYPE o) { throw new UnsupportedOperationException(); } +#endif + @Override + public boolean add(KEY_TYPE o) { throw new UnsupportedOperationException(); } + @Override + public ITERATOR KEY_GENERIC_TYPE iterator() + { + return new ITERATOR KEY_GENERIC_TYPE() { + boolean next = true; + @Override + public boolean hasNext() { return next = false; } + @Override + public KEY_TYPE NEXT() { + if(!next) throw new IllegalStateException(); + next = false; + return element; + } + }; + } + @Override + public int size() { return 1; } + } + public static class EmptySet KEY_GENERIC_TYPE extends EmptyCollection KEY_GENERIC_TYPE implements SET KEY_GENERIC_TYPE { #if !TYPE_OBJECT @@ -72,6 +120,7 @@ public class SETS #endif } +#if !TYPE_BOOLEAN public static class UnmodifiableNavigableSet KEY_GENERIC_TYPE extends UnmodifiableSortedSet KEY_GENERIC_TYPE implements NAVIGABLE_SET KEY_GENERIC_TYPE { NAVIGABLE_SET KEY_GENERIC_TYPE n; @@ -139,7 +188,6 @@ public class SETS @Override public NAVIGABLE_SET KEY_GENERIC_TYPE tailSet(KEY_TYPE fromElement) { return unmodifiable(n.tailSet(fromElement)); } - } public static class UnmodifiableSortedSet KEY_GENERIC_TYPE extends UnmodifiableSet KEY_GENERIC_TYPE implements SORTED_SET KEY_GENERIC_TYPE @@ -414,4 +462,5 @@ public class SETS public boolean remove(KEY_TYPE o) { synchronized(mutex) { return s.remove(o); } } #endif } +#endif } diff --git a/src/builder/resources/speiger/assets/collections/templates/utils/maps/Maps.template b/src/builder/resources/speiger/assets/collections/templates/utils/maps/Maps.template index fd6aeb61..0140bc0b 100644 --- a/src/builder/resources/speiger/assets/collections/templates/utils/maps/Maps.template +++ b/src/builder/resources/speiger/assets/collections/templates/utils/maps/Maps.template @@ -1,14 +1,59 @@ package speiger.src.collections.PACKAGE.utils.maps; +#if !TYPE_BOOLEAN +import java.util.Map; +import java.util.Objects; +#if TYPE_OBJECT +import java.util.Comparator; +#else +import java.util.function.BiConsumer; +import java.util.function.BiFunction; +#endif +#endif import java.util.function.Consumer; +#if !TYPE_OBJECT && !TYPE_BOOLEAN +import java.util.function.Function; +#endif import speiger.src.collections.objects.collections.ObjectIterable; import speiger.src.collections.objects.collections.ObjectIterator; -import speiger.src.collections.PACKAGE.maps.interfaces.MAP; import speiger.src.collections.objects.sets.ObjectSet; +#if !TYPE_BOOLEAN +import speiger.src.collections.objects.utils.ObjectSets; +#if !TYPE_OBJECT +import speiger.src.collections.PACKAGE.functions.COMPARATOR; +#endif +import speiger.src.collections.PACKAGE.functions.consumer.BI_CONSUMER; +import speiger.src.collections.PACKAGE.functions.function.FUNCTION; +import speiger.src.collections.PACKAGE.functions.function.UNARY_OPERATOR; +import speiger.src.collections.PACKAGE.maps.abstracts.ABSTRACT_MAP; +#endif +import speiger.src.collections.PACKAGE.maps.interfaces.MAP; +#if !TYPE_BOOLEAN +import speiger.src.collections.PACKAGE.maps.interfaces.NAVIGABLE_MAP; +import speiger.src.collections.PACKAGE.maps.interfaces.SORTED_MAP; +import speiger.src.collections.PACKAGE.sets.NAVIGABLE_SET; +#if !TYPE_OBJECT +import speiger.src.collections.PACKAGE.sets.SET; +import speiger.src.collections.PACKAGE.utils.SETS; +#endif +import speiger.src.collections.VALUE_PACKAGE.collections.VALUE_COLLECTION; +#if !SAME_TYPE +import speiger.src.collections.VALUE_PACKAGE.functions.function.VALUE_UNARY_OPERATOR; +#endif +import speiger.src.collections.VALUE_PACKAGE.utils.VALUE_COLLECTIONS; +#if !SAME_TYPE && !VALUE_OBJECT +import speiger.src.collections.VALUE_PACKAGE.utils.VALUE_SETS; +#endif + +#endif public class MAPS { +#if !TYPE_BOOLEAN + public static final MAP NO_KV_GENERIC_TYPE EMPTY = new EmptyMapKV_BRACES(); + +#endif public static GENERIC_KEY_VALUE_BRACES ObjectIterator fastIterator(MAP KEY_VALUE_GENERIC_TYPE map) { ObjectSet entries = map.ENTRY_SET(); return entries instanceof MAP.FastEntrySet ? ((MAP.FastEntrySet KEY_VALUE_GENERIC_TYPE)entries).fastIterator() : entries.iterator(); @@ -29,4 +74,626 @@ public class MAPS if(entries instanceof MAP.FastEntrySet) ((MAP.FastEntrySet KEY_VALUE_GENERIC_TYPE)entries).fastForEach(action); else entries.forEach(action); } + +#if !TYPE_BOOLEAN + public static GENERIC_KEY_VALUE_BRACES MAP KEY_VALUE_GENERIC_TYPE emptyMap() { +#if TYPE_OBJECT || VALUE_OBJECT + return (MAP KEY_VALUE_GENERIC_TYPE)EMPTY; +#else + return EMPTY; +#endif + } + + public static GENERIC_KEY_VALUE_BRACES MAP KEY_VALUE_GENERIC_TYPE synchronizeMap(MAP KEY_VALUE_GENERIC_TYPE map) { return map instanceof SynchronizedMap ? map : new SynchronizedMapKV_BRACES(map); } + public static GENERIC_KEY_VALUE_BRACES MAP KEY_VALUE_GENERIC_TYPE synchronizeMap(MAP KEY_VALUE_GENERIC_TYPE map, Object mutex) { return map instanceof SynchronizedMap ? map : new SynchronizedMapKV_BRACES(map, mutex); } + + public static GENERIC_KEY_VALUE_BRACES SORTED_MAP KEY_VALUE_GENERIC_TYPE synchronizeMap(SORTED_MAP KEY_VALUE_GENERIC_TYPE map) { return map instanceof SynchronizedSortedMap ? map : new SynchronizedSortedMapKV_BRACES(map); } + public static GENERIC_KEY_VALUE_BRACES SORTED_MAP KEY_VALUE_GENERIC_TYPE synchronizeMap(SORTED_MAP KEY_VALUE_GENERIC_TYPE map, Object mutex) { return map instanceof SynchronizedSortedMap ? map : new SynchronizedSortedMapKV_BRACES(map, mutex); } + + public static GENERIC_KEY_VALUE_BRACES NAVIGABLE_MAP KEY_VALUE_GENERIC_TYPE synchronizeMap(NAVIGABLE_MAP KEY_VALUE_GENERIC_TYPE map) { return map instanceof SynchronizedNavigableMap ? map : new SynchronizedNavigableMapKV_BRACES(map); } + public static GENERIC_KEY_VALUE_BRACES NAVIGABLE_MAP KEY_VALUE_GENERIC_TYPE synchronizeMap(NAVIGABLE_MAP KEY_VALUE_GENERIC_TYPE map, Object mutex) { return map instanceof SynchronizedNavigableMap ? map : new SynchronizedNavigableMapKV_BRACES(map, mutex); } + + public static GENERIC_KEY_VALUE_BRACES MAP KEY_VALUE_GENERIC_TYPE unmodifyableMap(MAP KEY_VALUE_GENERIC_TYPE map) { return map instanceof UnmodifyableMap ? map : new UnmodifyableMapKV_BRACES(map); } + public static GENERIC_KEY_VALUE_BRACES SORTED_MAP KEY_VALUE_GENERIC_TYPE unmodifyableMap(SORTED_MAP KEY_VALUE_GENERIC_TYPE map) { return map instanceof UnmodifyableSortedMap ? map : new UnmodifyableSortedMapKV_BRACES(map); } + public static GENERIC_KEY_VALUE_BRACES NAVIGABLE_MAP KEY_VALUE_GENERIC_TYPE unmodifyableMap(NAVIGABLE_MAP KEY_VALUE_GENERIC_TYPE map) { return map instanceof UnmodifyableNavigableMap ? map : new UnmodifyableNavigableMapKV_BRACES(map); } + public static GENERIC_KEY_VALUE_BRACES MAP.Entry KEY_VALUE_GENERIC_TYPE unmodifyableEntry(MAP.Entry KEY_VALUE_GENERIC_TYPE map) { return map instanceof UnmodifyableEntry ? map : new UnmodifyableEntryKV_BRACES(map); } + public static GENERIC_KEY_VALUE_BRACES MAP.Entry KEY_VALUE_GENERIC_TYPE unmodifyableEntry(Map.Entry map) { return map instanceof UnmodifyableEntry ? (UnmodifyableEntry KEY_VALUE_GENERIC_TYPE)map : new UnmodifyableEntryKV_BRACES(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 class SingletonMap KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_GENERIC_TYPE { + final KEY_TYPE key; + final VALUE_TYPE value; + SET KEY_GENERIC_TYPE keySet; + VALUE_COLLECTION VALUE_GENERIC_TYPE values; + ObjectSet entrySet; + + public SingletonMap(KEY_TYPE key, VALUE_TYPE value) { + this.key = key; + this.value = value; + } + + @Override + public VALUE_TYPE put(KEY_TYPE key, VALUE_TYPE value) { throw new UnsupportedOperationException(); } + @Override + public VALUE_TYPE putIfAbsent(KEY_TYPE key, VALUE_TYPE value) { throw new UnsupportedOperationException(); } +#if VALUE_PRIMITIVES + @Override + public VALUE_TYPE addTo(KEY_TYPE key, VALUE_TYPE value) { throw new UnsupportedOperationException(); } +#endif + @Override + public VALUE_TYPE REMOVE_KEY(KEY_TYPE key) { throw new UnsupportedOperationException(); } +#if !TYPE_OBJECT || !VALUE_OBJECT + @Override + public boolean remove(KEY_TYPE key, VALUE_TYPE value) { throw new UnsupportedOperationException(); } +#endif + @Override + public VALUE_TYPE GET_VALUE(KEY_TYPE key) { return EQUALS_KEY_TYPE(key, this.key) ? value : getDefaultReturnValue(); } +#if !TYPE_OBJECT || !VALUE_OBJECT + @Override + public VALUE_TYPE getOrDefault(KEY_TYPE key, VALUE_TYPE defaultValue) { return EQUALS_KEY_TYPE(key, this.key) ? value : defaultValue; } +#endif + @Override + public SET KEY_GENERIC_TYPE keySet() { + if(keySet == null) keySet = SETS.singletonSet(key); + return keySet; + } + + @Override + public VALUE_COLLECTION VALUE_GENERIC_TYPE values() { + if(values == null) values = VALUE_SETS.singletonSet(value); + return values; + } + @Override + public ObjectSet ENTRY_SET() { + if(entrySet == null) entrySet = ObjectSets.singletonSet(new ABSTRACT_MAP.BasicEntryKV_BRACES(key, value)); + return entrySet; + } + } + + public static class EmptyMap KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_GENERIC_TYPE { + @Override + public VALUE_TYPE put(KEY_TYPE key, VALUE_TYPE value) { throw new UnsupportedOperationException(); } + @Override + public VALUE_TYPE putIfAbsent(KEY_TYPE key, VALUE_TYPE value) { throw new UnsupportedOperationException(); } +#if VALUE_PRIMITIVES + @Override + public VALUE_TYPE addTo(KEY_TYPE key, VALUE_TYPE value) { throw new UnsupportedOperationException(); } +#endif + @Override + public VALUE_TYPE REMOVE_KEY(KEY_TYPE key) { throw new UnsupportedOperationException(); } +#if !TYPE_OBJECT || !VALUE_OBJECT + @Override + public boolean remove(KEY_TYPE key, VALUE_TYPE value) { throw new UnsupportedOperationException(); } +#endif + @Override + public VALUE_TYPE GET_VALUE(KEY_TYPE key) { return getDefaultReturnValue(); } +#if !TYPE_OBJECT || !VALUE_OBJECT + @Override + public VALUE_TYPE getOrDefault(KEY_TYPE key, VALUE_TYPE defaultValue) { return EMPTY_VALUE; } +#endif + @Override + public SET KEY_GENERIC_TYPE keySet() { return SETS.empty(); } + @Override + public VALUE_COLLECTION VALUE_GENERIC_TYPE values() { return VALUE_COLLECTIONS.emptyCollection(); } + @Override + public ObjectSet ENTRY_SET() { return ObjectSets.empty(); } + } + + public static class UnmodifyableEntry KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP.BasicEntry KEY_VALUE_GENERIC_TYPE { + + public UnmodifyableEntry(Map.Entry entry) { + super(entry.getKey(), entry.getValue()); + } + + public UnmodifyableEntry(MAP.Entry KEY_VALUE_GENERIC_TYPE entry) { + super(entry.ENTRY_KEY(), entry.ENTRY_VALUE()); + } + } + + 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; + + public UnmodifyableNavigableMap(NAVIGABLE_MAP KEY_VALUE_GENERIC_TYPE map) { + super(map); + this.map = map; + } + + @Override + public NAVIGABLE_MAP KEY_VALUE_GENERIC_TYPE descendingMap() { return unmodifyableMap(map.descendingMap()); } + @Override + public NAVIGABLE_SET KEY_GENERIC_TYPE navigableKeySet() { return SETS.unmodifiable(map.navigableKeySet()); } + @Override + public NAVIGABLE_SET KEY_GENERIC_TYPE descendingKeySet() { return SETS.unmodifiable(map.descendingKeySet()); } + @Override + public MAP.Entry KEY_VALUE_GENERIC_TYPE firstEntry() { return unmodifyableEntry(map.firstEntry()); } + @Override + public MAP.Entry KEY_VALUE_GENERIC_TYPE lastEntry() { return unmodifyableEntry(map.lastEntry()); } + @Override + public MAP.Entry KEY_VALUE_GENERIC_TYPE pollFirstEntry() { throw new UnsupportedOperationException(); } + @Override + public MAP.Entry KEY_VALUE_GENERIC_TYPE pollLastEntry() { throw new UnsupportedOperationException(); } + @Override + public NAVIGABLE_MAP KEY_VALUE_GENERIC_TYPE subMap(KEY_TYPE fromKey, boolean fromInclusive, KEY_TYPE toKey, boolean toInclusive) { return unmodifyableMap(map.subMap(fromKey, fromInclusive, toKey, toInclusive)); } + @Override + public NAVIGABLE_MAP KEY_VALUE_GENERIC_TYPE headMap(KEY_TYPE toKey, boolean inclusive) { return unmodifyableMap(map.headMap(toKey, inclusive)); } + @Override + public NAVIGABLE_MAP KEY_VALUE_GENERIC_TYPE tailMap(KEY_TYPE fromKey, boolean inclusive) { return unmodifyableMap(map.tailMap(fromKey, inclusive)); } + @Override + public NAVIGABLE_MAP KEY_VALUE_GENERIC_TYPE subMap(KEY_TYPE fromKey, KEY_TYPE toKey) { return unmodifyableMap(map.subMap(fromKey, toKey)); } + @Override + public NAVIGABLE_MAP KEY_VALUE_GENERIC_TYPE headMap(KEY_TYPE toKey) { return unmodifyableMap(map.headMap(toKey)); } + @Override + public NAVIGABLE_MAP KEY_VALUE_GENERIC_TYPE tailMap(KEY_TYPE fromKey) { return unmodifyableMap(map.tailMap(fromKey)); } +#if !TYPE_OBJECT + @Override + public void setDefaultMaxValue(KEY_TYPE e) { throw new UnsupportedOperationException(); } + @Override + public KEY_TYPE getDefaultMaxValue() { return map.getDefaultMaxValue(); } + @Override + public void setDefaultMinValue(KEY_TYPE e) { throw new UnsupportedOperationException(); } + @Override + public KEY_TYPE getDefaultMinValue() { return map.getDefaultMinValue(); } +#endif + @Override + public KEY_TYPE lowerKey(KEY_TYPE key) { return map.lowerKey(key); } + @Override + public KEY_TYPE higherKey(KEY_TYPE key) { return map.higherKey(key); } + @Override + public KEY_TYPE floorKey(KEY_TYPE key) { return map.floorKey(key); } + @Override + public KEY_TYPE ceilingKey(KEY_TYPE key) { return map.ceilingKey(key); } + @Override + public MAP.Entry KEY_VALUE_GENERIC_TYPE lowerEntry(KEY_TYPE key) { return unmodifyableEntry(map.lowerEntry(key)); } + @Override + public MAP.Entry KEY_VALUE_GENERIC_TYPE higherEntry(KEY_TYPE key) { return unmodifyableEntry(map.higherEntry(key)); } + @Override + public MAP.Entry KEY_VALUE_GENERIC_TYPE floorEntry(KEY_TYPE key) { return unmodifyableEntry(map.floorEntry(key)); } + @Override + public MAP.Entry KEY_VALUE_GENERIC_TYPE ceilingEntry(KEY_TYPE key) { return unmodifyableEntry(map.ceilingEntry(key)); } + } + + 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; + + public UnmodifyableSortedMap(SORTED_MAP KEY_VALUE_GENERIC_TYPE map) { + super(map); + this.map = map; + } + + @Override + public VALUE_TYPE putAndMoveToFirst(KEY_TYPE key, VALUE_TYPE value) { throw new UnsupportedOperationException(); } + @Override + public VALUE_TYPE putAndMoveToLast(KEY_TYPE key, VALUE_TYPE value) { throw new UnsupportedOperationException(); } + @Override + public boolean moveToFirst(KEY_TYPE key) { throw new UnsupportedOperationException(); } + @Override + public boolean moveToLast(KEY_TYPE key) { throw new UnsupportedOperationException(); } + @Override + public VALUE_TYPE getAndMoveToFirst(KEY_TYPE key) { throw new UnsupportedOperationException(); } + @Override + public VALUE_TYPE getAndMoveToLast(KEY_TYPE key) { throw new UnsupportedOperationException(); } + @Override + public COMPARATOR KEY_GENERIC_TYPE comparator() { return map.comparator(); } + @Override + public SORTED_MAP KEY_VALUE_GENERIC_TYPE subMap(KEY_TYPE fromKey, KEY_TYPE toKey) { return unmodifyableMap(map.subMap(fromKey, toKey)); } + @Override + public SORTED_MAP KEY_VALUE_GENERIC_TYPE headMap(KEY_TYPE toKey) { return unmodifyableMap(map.headMap(toKey)); } + @Override + public SORTED_MAP KEY_VALUE_GENERIC_TYPE tailMap(KEY_TYPE fromKey) { return unmodifyableMap(map.tailMap(fromKey)); } + @Override + public KEY_TYPE FIRST_ENTRY_KEY() { return map.FIRST_ENTRY_KEY(); } + @Override + public KEY_TYPE POLL_FIRST_ENTRY_KEY() { return map.POLL_FIRST_ENTRY_KEY(); } + @Override + public KEY_TYPE LAST_ENTRY_KEY() { return map.LAST_ENTRY_KEY(); } + @Override + public KEY_TYPE POLL_LAST_ENTRY_KEY() { return map.POLL_LAST_ENTRY_KEY(); } + @Override + public VALUE_TYPE FIRST_ENTRY_VALUE() { return map.FIRST_ENTRY_VALUE(); } + @Override + public VALUE_TYPE LAST_ENTRY_VALUE() { return map.LAST_ENTRY_VALUE(); } + } + + public static class UnmodifyableMap KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_GENERIC_TYPE implements MAP KEY_VALUE_GENERIC_TYPE { + MAP KEY_VALUE_GENERIC_TYPE map; + VALUE_COLLECTION VALUE_GENERIC_TYPE values; + SET KEY_GENERIC_TYPE keys; + ObjectSet entrySet; + + public UnmodifyableMap(MAP KEY_VALUE_GENERIC_TYPE map) { + this.map = map; + } + + @Override + public VALUE_TYPE put(KEY_TYPE key, VALUE_TYPE value) { throw new UnsupportedOperationException(); } + @Override + public VALUE_TYPE putIfAbsent(KEY_TYPE key, VALUE_TYPE value){ throw new UnsupportedOperationException(); } +#if VALUE_PRIMITIVES + @Override + public VALUE_TYPE addTo(KEY_TYPE key, VALUE_TYPE value) { throw new UnsupportedOperationException(); } +#endif + @Override + public VALUE_TYPE REMOVE_KEY(KEY_TYPE key) { throw new UnsupportedOperationException(); } +#if !TYPE_OBJECT || !VALUE_OBJECT + @Override + public boolean remove(KEY_TYPE key, VALUE_TYPE value) { throw new UnsupportedOperationException(); } +#endif + @Override + public VALUE_TYPE GET_VALUE(KEY_TYPE key) { return map.GET_VALUE(key); } +#if !TYPE_OBJECT || !VALUE_OBJECT + @Override + public VALUE_TYPE getOrDefault(KEY_TYPE key, VALUE_TYPE defaultValue) { return map.getOrDefault(key, defaultValue); } +#endif + + @Override + public SET KEY_GENERIC_TYPE keySet() { + if(keys == null) keys = SETS.unmodifiable(map.keySet()); + return keys; + } + + @Override + public VALUE_COLLECTION VALUE_GENERIC_TYPE values() { + if(values == null) values = VALUE_COLLECTIONS.unmodifiableCollection(map.values()); + return values; + } + + @Override + public ObjectSet ENTRY_SET() { + if(entrySet == null) entrySet = new UnmodifyableEntrySetKV_BRACES(map.ENTRY_SET()); + return entrySet; + } + } + + public static class UnmodifyableEntrySet KEY_VALUE_GENERIC_TYPE extends ObjectSets.UnmodifiableSet + { + ObjectSet s; + + public UnmodifyableEntrySet(ObjectSet c) + { + super(c); + s = c; + } + + @Override + public void forEach(Consumer action) { + s.forEach(T -> action.accept(unmodifyableEntry(T))); + } + + @Override + public ObjectIterator iterator() { + return new ObjectIterator() { + ObjectIterator iter = s.iterator(); + @Override + public boolean hasNext() { return iter.hasNext(); } + @Override + public MAP.Entry KEY_VALUE_GENERIC_TYPE next() { return unmodifyableEntry(iter.next()); } + }; + } + + } + + 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; + + public SynchronizedNavigableMap(NAVIGABLE_MAP KEY_VALUE_GENERIC_TYPE map) { + super(map); + this.map = map; + } + + public SynchronizedNavigableMap(NAVIGABLE_MAP KEY_VALUE_GENERIC_TYPE map, Object mutex) { + super(map, mutex); + this.map = map; + } + + @Override + public NAVIGABLE_MAP KEY_VALUE_GENERIC_TYPE descendingMap() { synchronized(mutex) { return synchronizeMap(map.descendingMap(), mutex); } } + @Override + public NAVIGABLE_SET KEY_GENERIC_TYPE navigableKeySet() { synchronized(mutex) { return SETS.synchronizedSet(map.navigableKeySet(), mutex); } } + @Override + public NAVIGABLE_SET KEY_GENERIC_TYPE descendingKeySet() { synchronized(mutex) { return SETS.synchronizedSet(map.descendingKeySet(), mutex); } } + @Override + public MAP.Entry KEY_VALUE_GENERIC_TYPE firstEntry() { synchronized(mutex) { return map.firstEntry(); } } + @Override + public MAP.Entry KEY_VALUE_GENERIC_TYPE lastEntry() { synchronized(mutex) { return map.firstEntry(); } } + @Override + public MAP.Entry KEY_VALUE_GENERIC_TYPE pollFirstEntry() { synchronized(mutex) { return map.pollFirstEntry(); } } + @Override + public MAP.Entry KEY_VALUE_GENERIC_TYPE pollLastEntry() { synchronized(mutex) { return map.pollLastEntry(); } } + @Override + public NAVIGABLE_MAP KEY_VALUE_GENERIC_TYPE subMap(KEY_TYPE fromKey, boolean fromInclusive, KEY_TYPE toKey, boolean toInclusive) { synchronized(mutex) { return synchronizeMap(map.subMap(fromKey, fromInclusive, toKey, toInclusive), mutex); } } + @Override + public NAVIGABLE_MAP KEY_VALUE_GENERIC_TYPE headMap(KEY_TYPE toKey, boolean inclusive) { synchronized(mutex) { return synchronizeMap(map.headMap(toKey, inclusive), mutex); } } + @Override + public NAVIGABLE_MAP KEY_VALUE_GENERIC_TYPE tailMap(KEY_TYPE fromKey, boolean inclusive) { synchronized(mutex) { return synchronizeMap(map.tailMap(fromKey, inclusive), mutex); } } + @Override + public NAVIGABLE_MAP KEY_VALUE_GENERIC_TYPE subMap(KEY_TYPE fromKey, KEY_TYPE toKey) { synchronized(mutex) { return synchronizeMap(map.subMap(fromKey, toKey), mutex); } } + @Override + public NAVIGABLE_MAP KEY_VALUE_GENERIC_TYPE headMap(KEY_TYPE toKey) { synchronized(mutex) { return synchronizeMap(map.headMap(toKey), mutex); } } + @Override + public NAVIGABLE_MAP KEY_VALUE_GENERIC_TYPE tailMap(KEY_TYPE fromKey) { synchronized(mutex) { return synchronizeMap(map.tailMap(fromKey), mutex); } } + @Override + public KEY_TYPE lowerKey(KEY_TYPE key) { synchronized(mutex) { return map.lowerKey(key); } } + @Override + public KEY_TYPE higherKey(KEY_TYPE key) { synchronized(mutex) { return map.higherKey(key); } } + @Override + public KEY_TYPE floorKey(KEY_TYPE key) { synchronized(mutex) { return map.floorKey(key); } } + @Override + public KEY_TYPE ceilingKey(KEY_TYPE key) { synchronized(mutex) { return map.ceilingKey(key); } } + @Override + public MAP.Entry KEY_VALUE_GENERIC_TYPE lowerEntry(KEY_TYPE key) { synchronized(mutex) { return map.lowerEntry(key); } } + @Override + public MAP.Entry KEY_VALUE_GENERIC_TYPE higherEntry(KEY_TYPE key) { synchronized(mutex) { return map.higherEntry(key); } } + @Override + public MAP.Entry KEY_VALUE_GENERIC_TYPE floorEntry(KEY_TYPE key) { synchronized(mutex) { return map.floorEntry(key); } } + @Override + public MAP.Entry KEY_VALUE_GENERIC_TYPE ceilingEntry(KEY_TYPE key) { synchronized(mutex) { return map.ceilingEntry(key); } } +#if !TYPE_OBJECT + @Override + @Deprecated + public NAVIGABLE_MAP KEY_VALUE_GENERIC_TYPE subMap(CLASS_TYPE fromKey, boolean fromInclusive, CLASS_TYPE toKey, boolean toInclusive) { synchronized(mutex) { return synchronizeMap(map.subMap(fromKey, fromInclusive, toKey, toInclusive), mutex); } } + @Override + @Deprecated + public NAVIGABLE_MAP KEY_VALUE_GENERIC_TYPE headMap(CLASS_TYPE toKey, boolean inclusive) { synchronized(mutex) { return synchronizeMap(map.headMap(toKey, inclusive), mutex); } } + @Override + @Deprecated + public NAVIGABLE_MAP KEY_VALUE_GENERIC_TYPE tailMap(CLASS_TYPE fromKey, boolean inclusive) { synchronized(mutex) { return synchronizeMap(map.tailMap(fromKey, inclusive), mutex); } } + @Override + @Deprecated + public NAVIGABLE_MAP KEY_VALUE_GENERIC_TYPE subMap(CLASS_TYPE fromKey, CLASS_TYPE toKey) { synchronized(mutex) { return synchronizeMap(map.subMap(fromKey, toKey), mutex); } } + @Override + @Deprecated + public NAVIGABLE_MAP KEY_VALUE_GENERIC_TYPE headMap(CLASS_TYPE toKey) { synchronized(mutex) { return synchronizeMap(map.headMap(toKey), mutex); } } + @Override + @Deprecated + public NAVIGABLE_MAP KEY_VALUE_GENERIC_TYPE tailMap(CLASS_TYPE fromKey) { synchronized(mutex) { return synchronizeMap(map.tailMap(fromKey), mutex); } } + @Override + public void setDefaultMaxValue(KEY_TYPE e) { synchronized(mutex) { map.setDefaultMaxValue(e); } } + @Override + public KEY_TYPE getDefaultMaxValue() { synchronized(mutex) { return map.getDefaultMaxValue(); } } + @Override + public void setDefaultMinValue(KEY_TYPE e) { synchronized(mutex) { map.setDefaultMinValue(e); } } + @Override + public KEY_TYPE getDefaultMinValue() { synchronized(mutex) { return map.getDefaultMinValue(); } } + @Override + @Deprecated + public CLASS_TYPE lowerKey(CLASS_TYPE key) { synchronized(mutex) { return map.lowerKey(key); } } + @Override + @Deprecated + public CLASS_TYPE floorKey(CLASS_TYPE key) { synchronized(mutex) { return map.floorKey(key); } } + @Override + @Deprecated + public CLASS_TYPE ceilingKey(CLASS_TYPE key) { synchronized(mutex) { return map.ceilingKey(key); } } + @Override + @Deprecated + public CLASS_TYPE higherKey(CLASS_TYPE key) { synchronized(mutex) { return map.higherKey(key); } } + @Override + @Deprecated + public MAP.Entry KEY_VALUE_GENERIC_TYPE lowerEntry(CLASS_TYPE key) { synchronized(mutex) { return map.lowerEntry(key); } } + @Override + @Deprecated + public MAP.Entry KEY_VALUE_GENERIC_TYPE floorEntry(CLASS_TYPE key) { synchronized(mutex) { return map.floorEntry(key); } } + @Override + @Deprecated + public MAP.Entry KEY_VALUE_GENERIC_TYPE ceilingEntry(CLASS_TYPE key) { synchronized(mutex) { return map.ceilingEntry(key); } } + @Override + @Deprecated + public MAP.Entry KEY_VALUE_GENERIC_TYPE higherEntry(CLASS_TYPE key) { synchronized(mutex) { return map.higherEntry(key); } } +#endif + } + + 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; + + public SynchronizedSortedMap(SORTED_MAP KEY_VALUE_GENERIC_TYPE map) { + super(map); + this.map = map; + } + + public SynchronizedSortedMap(SORTED_MAP KEY_VALUE_GENERIC_TYPE map, Object mutex) { + super(map, mutex); + this.map = map; + } + + @Override + public VALUE_TYPE putAndMoveToFirst(KEY_TYPE key, VALUE_TYPE value) { synchronized(mutex) { return map.putAndMoveToFirst(key, value); } } + @Override + public VALUE_TYPE putAndMoveToLast(KEY_TYPE key, VALUE_TYPE value) { synchronized(mutex) { return map.putAndMoveToLast(key, value); } } + @Override + public boolean moveToFirst(KEY_TYPE key) { synchronized(mutex) { return map.moveToFirst(key); } } + @Override + public boolean moveToLast(KEY_TYPE key) { synchronized(mutex) { return map.moveToLast(key); } } + @Override + public VALUE_TYPE getAndMoveToFirst(KEY_TYPE key) { synchronized(mutex) { return map.getAndMoveToFirst(key); } } + @Override + public VALUE_TYPE getAndMoveToLast(KEY_TYPE key) { synchronized(mutex) { return map.getAndMoveToLast(key); } } + @Override + public COMPARATOR KEY_GENERIC_TYPE comparator() { synchronized(mutex) { return map.comparator(); } } + @Override + public SORTED_MAP KEY_VALUE_GENERIC_TYPE subMap(KEY_TYPE fromKey, KEY_TYPE toKey) { synchronized(mutex) { return synchronizeMap(map.subMap(fromKey, toKey), mutex); } } + @Override + public SORTED_MAP KEY_VALUE_GENERIC_TYPE headMap(KEY_TYPE toKey) { synchronized(mutex) { return synchronizeMap(map.headMap(toKey), mutex); } } + @Override + public SORTED_MAP KEY_VALUE_GENERIC_TYPE tailMap(KEY_TYPE fromKey) { synchronized(mutex) { return synchronizeMap(map.tailMap(fromKey), mutex); } } + @Override + public KEY_TYPE FIRST_ENTRY_KEY() { synchronized(mutex) { return map.FIRST_ENTRY_KEY(); } } + @Override + public KEY_TYPE POLL_FIRST_ENTRY_KEY() { synchronized(mutex) { return map.POLL_FIRST_ENTRY_KEY(); } } + @Override + public KEY_TYPE LAST_ENTRY_KEY() { synchronized(mutex) { return map.LAST_ENTRY_KEY(); } } + @Override + public KEY_TYPE POLL_LAST_ENTRY_KEY() { synchronized(mutex) { return map.POLL_LAST_ENTRY_KEY(); } } + @Override + public VALUE_TYPE FIRST_ENTRY_VALUE() { synchronized(mutex) { return map.FIRST_ENTRY_VALUE(); } } + @Override + public VALUE_TYPE LAST_ENTRY_VALUE() { synchronized(mutex) { return map.LAST_ENTRY_VALUE(); } } +#if !TYPE_OBJECT + @Override + @Deprecated + public CLASS_TYPE firstKey() { synchronized(mutex) { return map.firstKey(); } } + @Override + @Deprecated + public CLASS_TYPE lastKey() { synchronized(mutex) { return map.lastKey(); } } + @Override + @Deprecated + public SORTED_MAP KEY_VALUE_GENERIC_TYPE subMap(CLASS_TYPE fromKey, CLASS_TYPE toKey) { synchronized(mutex) { return synchronizeMap(map.subMap(fromKey, toKey), mutex); } } + @Override + @Deprecated + public SORTED_MAP KEY_VALUE_GENERIC_TYPE headMap(CLASS_TYPE toKey) { synchronized(mutex) { return synchronizeMap(map.headMap(toKey), mutex); } } + @Override + @Deprecated + public SORTED_MAP KEY_VALUE_GENERIC_TYPE tailMap(CLASS_TYPE fromKey) { synchronized(mutex) { return synchronizeMap(map.tailMap(fromKey), mutex); } } +#endif + } + + public static class SynchronizedMap KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_GENERIC_TYPE implements MAP KEY_VALUE_GENERIC_TYPE { + MAP KEY_VALUE_GENERIC_TYPE map; + VALUE_COLLECTION VALUE_GENERIC_TYPE values; + SET KEY_GENERIC_TYPE keys; + ObjectSet entrySet; + + protected Object mutex; + + public SynchronizedMap(MAP KEY_VALUE_GENERIC_TYPE map) { + this.map = map; + mutex = this; + } + + public SynchronizedMap(MAP KEY_VALUE_GENERIC_TYPE map, Object mutex) { + this.map = map; + this.mutex = mutex; + } + + @Override + public VALUE_TYPE getDefaultReturnValue() { synchronized(mutex) { return map.getDefaultReturnValue(); } } + @Override + public ABSTRACT_MAP KEY_VALUE_GENERIC_TYPE setDefaultReturnValue(VALUE_TYPE v) { + synchronized(mutex) { + map.setDefaultReturnValue(v); + return this; + } + } + @Override + public VALUE_TYPE put(KEY_TYPE key, VALUE_TYPE value) { synchronized(mutex) { return map.put(key, value); } } + @Override + public VALUE_TYPE putIfAbsent(KEY_TYPE key, VALUE_TYPE value) { synchronized(mutex) { return map.putIfAbsent(key, value); } } +#if VALUE_PRIMITIVES + @Override + public VALUE_TYPE addTo(KEY_TYPE key, VALUE_TYPE value) { synchronized(mutex) { return map.addTo(key, value); } } +#endif + @Override + public void putAll(MAP KEY_VALUE_GENERIC_TYPE m) { synchronized(mutex) { map.putAll(m); } } + @Override + public void putAll(Map m) { synchronized(mutex) { map.putAll(m); } } +#if !TYPE_OBJECT + @Override + public boolean containsKey(KEY_TYPE key) { synchronized(mutex) { return map.containsKey(key); } } +#endif +#if !VALUE_OBJECT + @Override + public boolean containsValue(VALUE_TYPE value) { synchronized(mutex) { return map.containsValue(value); } } +#endif + @Override + public VALUE_TYPE GET_VALUE(KEY_TYPE key) { synchronized(mutex) { return map.GET_VALUE(key); } } + @Override + public VALUE_TYPE REMOVE_KEY(KEY_TYPE key) { synchronized(mutex) { return map.REMOVE_KEY(key); } } +#if !TYPE_OBJECT || !VALUE_OBJECT + @Override + public boolean remove(KEY_TYPE key, VALUE_TYPE value) { synchronized(mutex) { return map.remove(key, value); } } +#endif + @Override + public boolean replace(KEY_TYPE key, VALUE_TYPE oldValue, VALUE_TYPE newValue) { synchronized(mutex) { return map.replace(key, oldValue, newValue); } } + @Override + public VALUE_TYPE replace(KEY_TYPE key, VALUE_TYPE value) { synchronized(mutex) { return map.replace(key, value); } } + @Override + public void REPLACE_VALUES(UNARY_OPERATOR KEY_VALUE_GENERIC_TYPE mappingFunction) { synchronized(mutex) { map.REPLACE_VALUES(mappingFunction); } } + @Override + public VALUE_TYPE COMPUTE(KEY_TYPE key, UNARY_OPERATOR KEY_VALUE_GENERIC_TYPE mappingFunction) { synchronized(mutex) { return map.COMPUTE(key, mappingFunction); } } + @Override + public VALUE_TYPE COMPUTE_IF_ABSENT(KEY_TYPE key, FUNCTION KEY_VALUE_GENERIC_TYPE mappingFunction) { synchronized(mutex) { return map.COMPUTE_IF_ABSENT(key, mappingFunction); } } + @Override + public VALUE_TYPE COMPUTE_IF_PRESENT(KEY_TYPE key, UNARY_OPERATOR KEY_VALUE_GENERIC_TYPE mappingFunction) { synchronized(mutex) { return map.COMPUTE_IF_PRESENT(key, mappingFunction); } } + @Override + public VALUE_TYPE MERGE(KEY_TYPE key, VALUE_TYPE value, VALUE_UNARY_OPERATOR VALUE_VALUE_GENERIC_TYPE mappingFunction) { synchronized(mutex) { return map.MERGE(key, value, mappingFunction); } } +#if !TYPE_OBJECT || !VALUE_OBJECT + @Override + public VALUE_TYPE getOrDefault(KEY_TYPE key, VALUE_TYPE defaultValue) { synchronized(mutex) { return map.getOrDefault(key, defaultValue); } } +#endif + @Override + public void forEach(BI_CONSUMER KEY_VALUE_GENERIC_TYPE action) { synchronized(mutex) { map.forEach(action); } } + @Override + public int size() { synchronized(mutex) { return super.size(); } } + @Override + public SET KEY_GENERIC_TYPE keySet() { + if(keys == null) keys = SETS.synchronizedSet(map.keySet(), mutex); + return keys; + } + + @Override + public VALUE_COLLECTION VALUE_GENERIC_TYPE values() { + if(values == null) values = VALUE_COLLECTIONS.synchronizedCollection(map.values(), mutex); + return values; + } + + @Override + public ObjectSet ENTRY_SET() { + if(entrySet == null) entrySet = ObjectSets.synchronizedSet(map.ENTRY_SET(), mutex); + return entrySet; + } + +#if !TYPE_OBJECT + @Override + @Deprecated + public CLASS_VALUE_TYPE get(Object key) { synchronized(mutex) { return map.get(key); } } + @Override + @Deprecated + public CLASS_VALUE_TYPE getOrDefault(Object key, CLASS_VALUE_TYPE defaultValue) { synchronized(mutex) { return map.getOrDefault(key, defaultValue); } } + @Override + @Deprecated + public boolean containsValue(Object value) { synchronized(mutex) { return map.containsValue(value); } } + @Override + @Deprecated + public boolean containsKey(Object key) { synchronized(mutex) { return map.containsKey(key); } } + @Override + @Deprecated + public CLASS_VALUE_TYPE put(CLASS_TYPE key, CLASS_VALUE_TYPE value) { synchronized(mutex) { return map.put(key, value); } } + @Override + @Deprecated + public CLASS_VALUE_TYPE remove(Object key) { synchronized(mutex) { return map.remove(key); } } + @Override + @Deprecated + public void clear() { synchronized(mutex) { map.clear(); } } + @Override + @Deprecated + public CLASS_VALUE_TYPE putIfAbsent(CLASS_TYPE key, CLASS_VALUE_TYPE value) { synchronized(mutex) { return map.putIfAbsent(key, value); } } + @Override + @Deprecated + public boolean remove(Object key, Object value) { synchronized(mutex) { return map.remove(key, value); } } + @Override + @Deprecated + public boolean replace(CLASS_TYPE key, CLASS_VALUE_TYPE oldValue, CLASS_VALUE_TYPE newValue) { synchronized(mutex) { return map.replace(key, oldValue, newValue); } } + @Override + @Deprecated + public CLASS_VALUE_TYPE replace(CLASS_TYPE key, CLASS_VALUE_TYPE value) { synchronized(mutex) { return map.replace(key, value); } } + @Override + @Deprecated + public void replaceAll(BiFunction mappingFunction) { synchronized(mutex) { map.replaceAll(mappingFunction); } } + @Override + @Deprecated + public CLASS_VALUE_TYPE compute(CLASS_TYPE key, BiFunction mappingFunction) { synchronized(mutex) { return map.compute(key, mappingFunction); } } + @Override + @Deprecated + public CLASS_VALUE_TYPE computeIfAbsent(CLASS_TYPE key, Function mappingFunction) { synchronized(mutex) { return map.computeIfAbsent(key, mappingFunction); } } + @Override + @Deprecated + public CLASS_VALUE_TYPE computeIfPresent(CLASS_TYPE key, BiFunction mappingFunction) { synchronized(mutex) { return computeIfPresent(key, mappingFunction); } } + @Override + @Deprecated + public CLASS_VALUE_TYPE merge(CLASS_TYPE key, CLASS_VALUE_TYPE value, BiFunction mappingFunction) { synchronized(mutex) { return map.merge(key, value, mappingFunction); } } + @Override + @Deprecated + public void forEach(BiConsumer action) { synchronized(mutex) { map.forEach(action); } } +#endif + } +#endif } \ No newline at end of file