Bladeren bron

generic map

Ranides Atterwim 9 jaren geleden
bovenliggende
commit
98936b37fa

+ 25 - 0
assira.drafts/src/main/java/net/ranides/assira/collections/map/GenericEntry.java

@@ -0,0 +1,25 @@
+/*
+ * @author Ranides Atterwim <ranides@gmail.com>
+ * @copyright Ranides Atterwim
+ * @license WTFPL
+ * @url http://ranides.net/projects/assira.drafts
+ */
+package net.ranides.assira.collections.map;
+
+import net.ranides.assira.reflection.IClass;
+
+/**
+ *
+ * @author Ranides Atterwim <ranides@gmail.com>
+ */
+public interface GenericEntry<K> {
+    
+    IClass<?> type();
+    
+    GenericKey<K,?> getKey();
+    
+    Object getValue();
+    
+    void setValue(Object value);
+    
+}

+ 154 - 0
assira.drafts/src/main/java/net/ranides/assira/collections/map/GenericHashMap.java

@@ -0,0 +1,154 @@
+/*
+ * @author Ranides Atterwim <ranides@gmail.com>
+ * @copyright Ranides Atterwim
+ * @license WTFPL
+ * @url http://ranides.net/projects/assira.drafts
+ */
+package net.ranides.assira.collections.map;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+import net.ranides.assira.collection.sets.SetUtils;
+import net.ranides.assira.collection.utils.HashCollection;
+import net.ranides.assira.reflection.IClass;
+
+/**
+ *
+ * @author Ranides Atterwim <ranides@gmail.com>
+ */
+@SuppressWarnings("unchecked")
+public class GenericHashMap<K> implements GenericMap<K> {
+    
+    private final Map<GenericKey<K,?>, Object> map;
+    
+    public GenericHashMap() {
+        this(HashCollection.INITIAL_SIZE, HashCollection.LOAD_FACTOR);
+    }
+    
+    public GenericHashMap(int capacity) {
+        this(capacity, HashCollection.LOAD_FACTOR);
+    }
+    
+    public GenericHashMap(int capacity, float factor) {
+        this.map = new HashMap<>(capacity, factor);
+    }
+    
+    public GenericHashMap(GenericMap<? extends K> m) {
+        this(m.size());
+        putAll(m);
+    }
+
+    private GenericHashMap(Map<GenericKey<K, ?>, Object> map) {
+        this.map = map;
+    }
+    
+    public static <K> GenericHashMap<K> unmodifiable(GenericHashMap<K> map) {
+        return new GenericHashMap<>(Collections.unmodifiableMap(map.map));
+    }
+    
+    @Override
+    public int size() {
+        return map.size();
+    }
+
+    @Override
+    public boolean isEmpty() {
+        return map.isEmpty();
+    }
+
+    @Override
+    public boolean containsKey(GenericKey<K, ?> key) {
+        return map.containsKey(key);
+    }
+
+    @Override
+    public boolean containsValue(Object value) {
+        return map.containsValue(value);
+    }
+
+    @Override
+    public <V> V get(GenericKey<K, V> key) {
+        return (V)map.get(key);
+    }
+
+    @Override
+    public <V> V put(GenericKey<K, V> key, V value) {
+        return (V)map.put(key, value);
+    }
+
+    @Override
+    public <V> V remove(GenericKey<K, V> key) {
+        return (V)map.remove(key);
+    }
+
+    @Override
+    public final void putAll(GenericMap<? extends K> m) {
+        if(m instanceof GenericHashMap<?>) {
+            map.putAll(((GenericHashMap)m).map);
+        } else { 
+            iputAll(m);
+        }
+    }
+
+    private void iputAll(GenericMap<? extends K> m) {
+        for(GenericEntry<? extends K> e : m.entrySet()) {
+            GenericKey key1 = e.getKey();
+            map.put(key1, e.getValue());
+        }
+    }
+
+    @Override
+    public void clear() {
+        map.clear();
+    }
+
+    @Override
+    public Set<GenericKey<K, ?>> keySet() {
+        return map.keySet();
+    }
+
+    @Override
+    public Collection<?> values() {
+        return map.values();
+    }
+
+    @Override
+    public Set<GenericEntry<K>> entrySet() {
+        return SetUtils.map(map.entrySet(), CGEntry::new);
+    }
+    
+    private static final class CGEntry<K> implements GenericEntry<K> {
+        
+        private final Entry<GenericKey<K,?>, Object> entry;
+
+        public CGEntry(Entry<GenericKey<K,?>, Object> entry) {
+            this.entry = entry;
+        }
+
+        @Override
+        public IClass<?> type() {
+            return entry.getKey().type();
+        }
+
+        @Override
+        public GenericKey<K, ?> getKey() {
+            return entry.getKey();
+        }
+
+        @Override
+        public Object getValue() {
+            return entry.getValue();
+        }
+
+        @Override
+        public void setValue(Object value) {
+            entry.setValue(entry.getKey().type().cast(value));
+        }
+        
+    }
+    
+}

+ 61 - 17
assira.drafts/src/main/java/net/ranides/assira/collections/map/GenericKey.java

@@ -1,17 +1,61 @@
-/*
- * @author Ranides Atterwim <ranides@gmail.com>
- * @copyright Ranides Atterwim
- * @license WTFPL
- * @url http://ranides.net/projects/assira
- */
-package net.ranides.assira.collections.map;
-
-/**
- *
- * @author msieron
- */
-public interface GenericKey<K,V> {
-    
-    
-    
-}
+/*
+ * @author Ranides Atterwim <ranides@gmail.com>
+ * @copyright Ranides Atterwim
+ * @license WTFPL
+ * @url http://ranides.net/projects/assira
+ */
+package net.ranides.assira.collections.map;
+
+import java.util.Objects;
+import net.ranides.assira.generic.HashUtils;
+import net.ranides.assira.reflection.IClass;
+
+/**
+ *
+ * @author msieron
+ */
+public class GenericKey<K,V> {
+    
+    private final IClass<V> type;
+    private final K key;
+
+    public GenericKey(IClass<V> type, K key) {
+        this.type = type;
+        this.key = key;
+    }
+    
+    public GenericKey(Class<V> type, K key) {
+        this(IClass.typeinfo(type), key);
+    }
+    
+    public IClass<V> type() {
+        return type;
+    }
+    
+    public K key() {
+        return key;
+    }
+
+    @Override
+    public int hashCode() {
+        return HashUtils.hashPair(type, key);
+    }
+
+    @Override
+    public boolean equals(Object object) {
+        if (this == object) {
+            return true;
+        }
+        if (object == null) {
+            return false;
+        }
+        if (getClass() != object.getClass()) {
+            return false;
+        }
+        final GenericKey<?, ?> that = (GenericKey<?, ?>) object;
+        return Objects.equals(this.type, that.type) && Objects.equals(this.key, that.key);
+    }
+    
+    
+    
+}

+ 180 - 211
assira.drafts/src/main/java/net/ranides/assira/collections/map/GenericMap.java

@@ -1,211 +1,180 @@
-/*
- * @author Ranides Atterwim <ranides@gmail.com>
- * @copyright Ranides Atterwim
- * @license WTFPL
- * @url http://ranides.net/projects/assira
- */
-package net.ranides.assira.collections.map;
-
-import java.util.Collection;
-import java.util.ConcurrentModificationException;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Objects;
-import java.util.Set;
-import java.util.function.BiConsumer;
-import java.util.function.BiFunction;
-import java.util.function.Function;
-
-/**
- *
- * @author msieron
- */
-
-
-public interface GenericMap<K> {
-
-    int size();
-
-    boolean isEmpty();
-
-    boolean containsKey(GenericKey<K,?> key);
-
-    boolean containsValue(Object value);
-
-    <V> V get(GenericKey<K,V> key);
-
-    <V> V put(GenericKey<K,V> key, V value);
-
-    <V> V remove(GenericKey<K,V> key);
-
-
-    void putAll(GenericMap<? extends K> m);
-
-    void clear();
-
-    Set<GenericKey<K,?>> keySet();
-
-    Collection<?> values();
-
-    Set<Map.Entry<GenericKey<K,?>, ?>> entrySet();
-
-    boolean equals(Object o);
-
-    int hashCode();
-
-    
-    
-    default <V> V getOrDefault(GenericKey<K,V> key, V defaultValue) {
-        V v;
-        return (((v = get(key)) != null) || containsKey(key)) ? v : defaultValue;
-    }
-
-    default void forEach(BiConsumer<? super GenericKey<K,?>, Object> action) {
-        Objects.requireNonNull(action);
-        for (Map.Entry<GenericKey<K,?>, ?> entry : entrySet()) {
-            GenericKey<K,?> k;
-            Object v;
-            try {
-                k = entry.getKey();
-                v = entry.getValue();
-            } catch(IllegalStateException ise) {
-                // this usually means the entry is no longer in the map.
-                throw new ConcurrentModificationException(ise);
-            }
-            action.accept(k, v);
-        }
-    }
-
-    default void replaceAll(BiFunction<? super GenericKey<K,?>, Object, Object> function) {
-        Objects.requireNonNull(function);
-        for (Map.Entry<GenericKey<K,?>, ?> entry : entrySet()) {
-            GenericKey<K,?> k;
-            Object v;
-            try {
-                k = entry.getKey();
-                v = entry.getValue();
-            } catch(IllegalStateException ise) {
-                // this usually means the entry is no longer in the map.
-                throw new ConcurrentModificationException(ise);
-            }
-
-            // ise thrown from function is not a cme.
-            v = function.apply(k, v);
-
-            try {
-                ((Entry)entry).setValue(v);
-            } catch(IllegalStateException ise) {
-                // this usually means the entry is no longer in the map.
-                throw new ConcurrentModificationException(ise);
-            }
-        }
-    }
-
-    default <V> V putIfAbsent(GenericKey<K,V> key, V value) {
-        V v = get(key);
-        if (v == null) {
-            v = put(key, value);
-        }
-
-        return v;
-    }
-
-    default <V> boolean remove(GenericKey<K,V> key, V value) {
-        Object curValue = get(key);
-        if (!Objects.equals(curValue, value) ||
-            (curValue == null && !containsKey(key))) {
-            return false;
-        }
-        remove(key);
-        return true;
-    }
-
-    default <V> boolean replace(GenericKey<K,V> key, V oldValue, V newValue) {
-        Object curValue = get(key);
-        if (!Objects.equals(curValue, oldValue) ||
-            (curValue == null && !containsKey(key))) {
-            return false;
-        }
-        put(key, newValue);
-        return true;
-    }
-
-    default <V> V replace(GenericKey<K,V> key, V value) {
-        V curValue;
-        if (((curValue = get(key)) != null) || containsKey(key)) {
-            curValue = put(key, value);
-        }
-        return curValue;
-    }
-
-    default <V> V computeIfAbsent(GenericKey<K,V> key,
-            Function<? super GenericKey<K,V>, ? extends V> mappingFunction) {
-        Objects.requireNonNull(mappingFunction);
-        V v;
-        if ((v = get(key)) == null) {
-            V newValue;
-            if ((newValue = mappingFunction.apply(key)) != null) {
-                put(key, newValue);
-                return newValue;
-            }
-        }
-
-        return v;
-    }
-
-    default <V> V computeIfPresent(GenericKey<K,V> key,
-            BiFunction<? super GenericKey<K,?>, ? super V, ? extends V> remappingFunction) {
-        Objects.requireNonNull(remappingFunction);
-        V oldValue;
-        if ((oldValue = get(key)) != null) {
-            V newValue = remappingFunction.apply(key, oldValue);
-            if (newValue != null) {
-                put(key, newValue);
-                return newValue;
-            } else {
-                remove(key);
-                return null;
-            }
-        } else {
-            return null;
-        }
-    }
-
-    default <V> V compute(GenericKey<K,V> key,
-            BiFunction<? super GenericKey<K,V>, ? super V, ? extends V> remappingFunction) {
-        Objects.requireNonNull(remappingFunction);
-        V oldValue = get(key);
-
-        V newValue = remappingFunction.apply(key, oldValue);
-        if (newValue == null) {
-            // delete mapping
-            if (oldValue != null || containsKey(key)) {
-                // something to remove
-                remove(key);
-                return null;
-            } else {
-                // nothing to do. Leave things as they were.
-                return null;
-            }
-        } else {
-            // add or replace old mapping
-            put(key, newValue);
-            return newValue;
-        }
-    }
-
-    default <V> V merge(GenericKey<K,V> key, V value,
-            BiFunction<? super V, ? super V, ? extends V> remappingFunction) {
-        Objects.requireNonNull(remappingFunction);
-        Objects.requireNonNull(value);
-        V oldValue = get(key);
-        V newValue = (oldValue == null) ? value :
-                   remappingFunction.apply(oldValue, value);
-        if(newValue == null) {
-            remove(key);
-        } else {
-            put(key, newValue);
-        }
-        return newValue;
-    }
-}
+/*
+ * @author Ranides Atterwim <ranides@gmail.com>
+ * @copyright Ranides Atterwim
+ * @license WTFPL
+ * @url http://ranides.net/projects/assira
+ */
+package net.ranides.assira.collections.map;
+
+import java.util.Collection;
+import java.util.ConcurrentModificationException;
+import java.util.Objects;
+import java.util.Optional;
+import java.util.Set;
+import java.util.function.BiConsumer;
+import java.util.function.BiFunction;
+import java.util.function.Function;
+
+/**
+ *
+ * @author msieron
+ */
+public interface GenericMap<K> {
+
+    int size();
+
+    boolean isEmpty();
+
+    boolean containsKey(GenericKey<K,?> key);
+
+    boolean containsValue(Object value);
+
+    <V> V get(GenericKey<K,V> key);
+
+    <V> V put(GenericKey<K,V> key, V value);
+    
+    default <V> V put(GenericKey<K,V> key, Optional<V> value) {
+        if(value.isPresent()) {
+            return put(key, value.get());
+        } else {
+            return get(key);
+        }
+    }
+
+    <V> V remove(GenericKey<K,V> key);
+
+    void putAll(GenericMap<? extends K> m);
+
+    void clear();
+
+    Set<GenericKey<K,?>> keySet();
+
+    Collection<?> values();
+
+    Set<GenericEntry<K>> entrySet();
+
+    @Override
+    boolean equals(Object o);
+
+    @Override
+    int hashCode();
+    
+    default <V> V getOrDefault(GenericKey<K,V> key, V ddefault) {
+        V v;
+        return (((v = get(key)) != null) || containsKey(key)) ? v : ddefault;
+    }
+
+    default void forEach(BiConsumer<? super GenericKey<K,?>, Object> action) {
+        Objects.requireNonNull(action);
+        for (GenericEntry<K> entry : entrySet()) {
+            GenericKey<K,?> k;
+            Object v;
+            try {
+                k = entry.getKey();
+                v = entry.getValue();
+            } catch(IllegalStateException ise) {
+                // this usually means the entry is no longer in the map.
+                throw new ConcurrentModificationException(ise);
+            }
+            action.accept(k, v);
+        }
+    }
+
+    default void replaceAll(BiFunction<? super GenericKey<K,?>, Object, Object> function) {
+        Objects.requireNonNull(function);
+        for (GenericEntry<K> entry : entrySet()) {
+            GenericKey<K,?> k;
+            Object v;
+            try {
+                k = entry.getKey();
+                v = entry.getValue();
+            } catch(IllegalStateException ise) {
+                // this usually means the entry is no longer in the map.
+                throw new ConcurrentModificationException(ise);
+            }
+
+            // ise thrown from function is not a cme.
+            v = function.apply(k, v);
+
+            try {
+                entry.setValue(k.type().cast(v));
+            } catch(IllegalStateException ise) {
+                // this usually means the entry is no longer in the map.
+                throw new ConcurrentModificationException(ise);
+            }
+        }
+    }
+
+    default <V> V putIfAbsent(GenericKey<K,V> key, V value) {
+        V v = get(key);
+        if (v == null) {
+            v = put(key, value);
+        }
+
+        return v;
+    }
+
+    default <V> boolean remove(GenericKey<K,V> key, V value) {
+        Object current = get(key);
+        if (!Objects.equals(current, value) || (current == null && !containsKey(key))) {
+            return false;
+        }
+        remove(key);
+        return true;
+    }
+
+    default <V> boolean replace(GenericKey<K,V> key, V oldValue, V value) {
+        Object current = get(key);
+        if (!Objects.equals(current, oldValue) || (current == null && !containsKey(key))) {
+            return false;
+        }
+        put(key, value);
+        return true;
+    }
+
+    default <V> V replace(GenericKey<K,V> key, V value) {
+        V current;
+        if (((current = get(key)) != null) || containsKey(key)) {
+            current = put(key, value);
+        }
+        return current;
+    }
+
+    default <V> V computeIfAbsent(GenericKey<K,V> key, Function<? super GenericKey<K,V>, ? extends V> function) {
+        Objects.requireNonNull(function);
+        V prev;
+        if (null == (prev = get(key)) && !containsKey(key)) {
+            V value = function.apply(key);
+            put(key, value);
+            return value;
+        }
+        return prev;
+    }
+
+    default <V> V computeIfPresent(GenericKey<K,V> key, BiFunction<? super GenericKey<K,?>, ? super V, ? extends V> function) {
+        Objects.requireNonNull(function);
+        V prev;
+        if (null != (prev = get(key)) || containsKey(key)) {
+            V value = function.apply(key, prev);
+            put(key, value);
+            return value;
+        } else {
+            return null;
+        }
+    }
+
+    default <V> V compute(GenericKey<K,V> key, BiFunction<? super GenericKey<K,V>, ? super V, ? extends V> function) {
+        Objects.requireNonNull(function);
+        V value = function.apply(key, get(key));
+        put(key, value);
+        return value;
+    }
+
+    default <V> V merge(GenericKey<K,V> key, V value, BiFunction<? super V, ? super V, ? extends V> function) {
+        Objects.requireNonNull(function);
+        V prev = get(key);
+        V newValue = (prev == null) ? value : function.apply(prev, value);
+        put(key, newValue);
+        return newValue;
+    }
+}