diff --git a/src/main/java/com/bgsoftware/superiorskyblock/key/dataset/KeyMapImpl.java b/src/main/java/com/bgsoftware/superiorskyblock/key/dataset/KeyMapImpl.java index 49dcb80ca..8577e2a26 100644 --- a/src/main/java/com/bgsoftware/superiorskyblock/key/dataset/KeyMapImpl.java +++ b/src/main/java/com/bgsoftware/superiorskyblock/key/dataset/KeyMapImpl.java @@ -5,8 +5,10 @@ import com.bgsoftware.superiorskyblock.key.KeyImpl; import org.jetbrains.annotations.NotNull; +import javax.annotation.Nullable; import java.util.AbstractMap; import java.util.AbstractSet; +import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.Iterator; @@ -27,6 +29,7 @@ public final class KeyMapImpl extends AbstractMap implements KeyMap innerMap; private Set> entrySet; + private Map innerReflectedMap; public static KeyMapImpl create(Supplier> mapCreator) { return new KeyMapImpl<>(mapCreator); @@ -144,9 +147,7 @@ public V getOrDefault(Object key, V defaultValue) { @Override public Map asMap() { - return innerMap.entrySet().stream().collect(Collectors.toMap(entry -> KeyImpl.of(entry.getKey()), Entry::getValue, (v1, v2) -> { - throw new IllegalStateException(String.format("Duplicate key %s", v1)); - }, HashMap::new)); + return Collections.unmodifiableMap(innerReflectedMap == null ? (innerReflectedMap = new InnerReflectedMap()) : innerReflectedMap); } private final class EntrySet extends AbstractSet> { @@ -243,6 +244,155 @@ public int characteristics() { } } + private final class InnerReflectedMap implements Map { + + private Set keySet; + private Set> entrySet; + + @Override + public int size() { + return KeyMapImpl.this.innerMap.size(); + } + + @Override + public boolean isEmpty() { + return KeyMapImpl.this.innerMap.isEmpty(); + } + + @Override + public boolean containsKey(Object key) { + return KeyMapImpl.this.innerMap.containsKey(key); + } + + @Override + public boolean containsValue(Object value) { + return KeyMapImpl.this.innerMap.containsValue(value); + } + + @Override + public V get(Object key) { + return KeyMapImpl.this.innerMap.get(key); + } + + @Nullable + @Override + public V put(Key key, V value) { + // No implementation + return null; + } + + @Override + public V remove(Object key) { + // No implementation + return null; + } + + @Override + public void putAll(@NotNull Map m) { + // No implementation + } + + @Override + public void clear() { + // No implementation + } + + @NotNull + @Override + public Set keySet() { + Set keySet = this.keySet; + if (keySet == null) { + keySet = this.keySet = new AbstractSet() { + public Iterator iterator() { + return new Iterator() { + private final Iterator> iterator = KeyMapImpl.this.innerMap.entrySet().iterator(); + + public boolean hasNext() { + return iterator.hasNext(); + } + + public Key next() { + return Key.of(iterator.next().getKey()); + } + + public void remove() { + iterator.remove(); + } + }; + } + + public int size() { + return InnerReflectedMap.this.size(); + } + + public boolean isEmpty() { + return InnerReflectedMap.this.isEmpty(); + } + + public void clear() { + InnerReflectedMap.this.clear(); + } + + public boolean contains(Object k) { + return InnerReflectedMap.this.containsKey(k); + } + }; + } + return keySet; + } + + @NotNull + @Override + public Collection values() { + return KeyMapImpl.this.innerMap.values(); + } + + @NotNull + @Override + public Set> entrySet() { + Set> entrySet = this.entrySet; + if (entrySet == null) { + entrySet = this.entrySet = new AbstractSet>() { + public Iterator> iterator() { + return new Iterator>() { + private final Iterator> iterator = KeyMapImpl.this.innerMap.entrySet().iterator(); + + public boolean hasNext() { + return iterator.hasNext(); + } + + public Entry next() { + return new KeyEntry(iterator.next()); + } + + public void remove() { + iterator.remove(); + } + }; + } + + public int size() { + return InnerReflectedMap.this.size(); + } + + public boolean isEmpty() { + return InnerReflectedMap.this.isEmpty(); + } + + public void clear() { + InnerReflectedMap.this.clear(); + } + + public boolean contains(Object k) { + return InnerReflectedMap.this.containsKey(k); + } + }; + } + return entrySet; + } + + } + private final class KeyEntry implements Entry { private final Entry entry;