Ranides Atterwim há 5 anos atrás
pai
commit
f6c2c5bce7

+ 352 - 0
assira/src/main/java/net/ranides/assira/collection/maps/CrossEnumMap.java

@@ -0,0 +1,352 @@
+package net.ranides.assira.collection.maps;
+
+import lombok.AllArgsConstructor;
+
+import net.ranides.assira.collection.sets.ASet;
+import net.ranides.assira.generic.Pair;
+
+import java.io.Serializable;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.NoSuchElementException;
+import java.util.Objects;
+import java.util.Optional;
+import java.util.Set;
+
+public class CrossEnumMap <K1 extends Enum<K1>, K2 extends Enum<K2>, V> implements CrossMap<K1, K2, V>, Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    private static final Cache<Class<? extends Enum<?>>, Object> KEYS_CACHE = Cache.getInstance();
+
+    private final Class<K1> type1;
+    private final Class<K2> type2;
+    private final K1[] universe1;
+    private final K2[] universe2;
+    private final Object[][] values;
+
+    private int size;
+
+    public CrossEnumMap(Class<K1> type1, Class<K2> type2) {
+        this.type1 = type1;
+        this.type2 = type2;
+        this.universe1 = (K1[])getSharedKeys(type1);
+        this.universe2 = (K2[])getSharedKeys(type2);
+        this.values = new Object[universe1.length][universe2.length];
+        this.size = 0;
+    }
+
+    @Override
+    public int size() {
+        return size;
+    }
+
+    @Override
+    public boolean isEmpty() {
+        return size == 0;
+    }
+
+    @Override
+    public boolean containsKey(K1 key1, K2 key2) {
+        return getOptional(key1, key2).isPresent();
+    }
+
+    @Override
+    public boolean containsValue(V value) {
+        for(int i1=0, n1=universe1.length; i1<n1; i1++) {
+            for(int i2=0, n2=universe2.length; i2<n2; i2++) {
+                if(Objects.equals(values[i1][i2], value)) {
+                    return true;
+                }
+            }
+        }
+        return false;
+    }
+
+    @Override
+    public V get(K1 key1, K2 key2) {
+        return getValueAt(key1.ordinal(), key2.ordinal());
+    }
+
+    @Override
+    public Optional<V> getOptional(K1 key1, K2 key2) {
+        return Optional.ofNullable(get(key1, key2));
+    }
+
+    @Override
+    public V put(K1 key1, K2 key2, V value) {
+        return setValueAt(key1.ordinal(), key2.ordinal(), value);
+    }
+
+    @Override
+    public V remove(K1 key1, K2 key2) {
+        return setValueAt(key1.ordinal(), key2.ordinal(), null);
+    }
+
+    protected V getValueAt(int index1, int index2) {
+        return (V)values[index1][index2];
+    }
+
+    protected V setValueAt(int index1, int index2, V value) {
+        V prev = getValueAt(index1, index2);
+
+        if(value == null) {
+            if(prev != null) {
+                size--;
+            }
+        } else {
+            if(prev == null) {
+                size++;
+            }
+        }
+
+        values[index1][index2] = value;
+        return prev;
+    }
+
+    @Override
+    public void putAll(CrossMap<K1, K2, ? extends V> values) {
+        values.forEachPair((pair, value) -> put(pair.getFirst(), pair.getSecond(), value));
+    }
+
+    @Override
+    public void clear() {
+        for(int i1=0, n1=universe1.length; i1<n1; i1++) {
+            for(int i2=0, n2=universe2.length; i2<n2; i2++) {
+                values[i1][i2] = null;
+            }
+        }
+        size = 0;
+    }
+
+    @Override
+    public MultiMap<K2, V> reduceFirst() {
+        HashMultiMap<K2, V> result = new HashMultiMap<>();
+        forEach((key1, key2, value) -> result.put(key2, value));
+        return result;
+    }
+
+    @Override
+    public MultiMap<K1, V> reduceSecond() {
+        HashMultiMap<K1, V> result = new HashMultiMap<>();
+        forEach((key1, key2, value) -> result.put(key1, value));
+        return result;
+    }
+
+    @Override
+    public Map<K1, K2> reduceValues() {
+        HashMultiMap<K1, K2> result = new HashMultiMap<>();
+        forEach((key1, key2, value) -> result.put(key1, key2));
+        return result;
+    }
+
+    @Override
+    public Set<Pair<K1, K2>> keySet() {
+        return new Keys();
+    }
+
+    @Override
+    public Collection<V> values() {
+        return new Values();
+    }
+
+    @Override
+    public Set<Map.Entry<Pair<K1, K2>, V>> entrySet() {
+        return new Entries();
+    }
+
+    private static Object getSharedKeys(Class<? extends Enum<?>> type) {
+        return KEYS_CACHE.get(type, Class::getEnumConstants);
+    }
+
+    private Optional<Map.Entry<Pair<K1, K2>,V>> castEntry(Object o) {
+        if (o instanceof Map.Entry<?, ?>) {
+            Map.Entry<?, ?> entry = (Map.Entry<?, ?>) o;
+            return castPair(entry.getKey()).map(x -> (Map.Entry)o);
+        }
+        return Optional.empty();
+    }
+
+    private Optional<Pair<K1, K2>> castPair(Object o) {
+            if (o instanceof Pair<?, ?>) {
+                Pair<?, ?> pair = (Pair<?, ?>) o;
+                Object key1 = pair.getFirst();
+                Object key2 = pair.getSecond();
+                if(type1.isInstance(key1) && type2.isInstance(key2)) {
+                    return Optional.of((Pair)pair);
+            }
+        }
+        return Optional.empty();
+    }
+
+    private class Keys extends ASet<Pair<K1, K2>> {
+        @Override
+        public Iterator<Pair<K1, K2>> iterator() {
+            return new KeyIterator();
+        }
+
+        @Override
+        public int size() {
+            return CrossEnumMap.this.size;
+        }
+
+        @Override
+        public boolean contains(Object value) {
+            return castPair(value)
+                .map(pair -> CrossEnumMap.this.containsKey(pair.getFirst(), pair.getSecond()))
+                .orElse(false);
+        }
+
+        @Override
+        public boolean remove(Object value) {
+            return castPair(value)
+                .map(pair -> CrossEnumMap.this.remove(pair.getFirst(), pair.getSecond()) != null)
+                .orElse(false);
+        }
+
+
+    }
+
+    private class Values extends ASet<V> {
+        @Override
+        public Iterator<V> iterator() {
+            return new ValueIterator();
+        }
+
+        @Override
+        public int size() {
+            return CrossEnumMap.this.size;
+        }
+
+        @Override
+        public boolean contains(Object value) {
+            return containsValue((V)value);
+        }
+    }
+
+    private class Entries extends ASet<Map.Entry<Pair<K1, K2>, V>> {
+        @Override
+        public Iterator<Map.Entry<Pair<K1, K2>, V>> iterator() {
+            return new EntryIterator();
+        }
+
+        @Override
+        public int size() {
+            return CrossEnumMap.this.size;
+        }
+
+        @Override
+        public boolean contains(Object o) {
+            return castEntry(o)
+                .filter(entry -> {
+                    Pair<K1, K2> pair = entry.getKey();
+                    V prev = CrossEnumMap.this.get(pair.getFirst(), pair.getSecond());
+                    return Objects.equals(prev, entry.getValue());
+                })
+                .isPresent();
+        }
+
+        @Override
+        public boolean remove(Object o) {
+            return castEntry(o)
+                .filter(entry -> {
+                    Pair<K1, K2> pair = entry.getKey();
+                    V prev = CrossEnumMap.this.get(pair.getFirst(), pair.getSecond());
+                    return Objects.equals(prev, entry.getValue());
+                })
+                .map(entry -> {
+                    Pair<K1, K2> pair = entry.getKey();
+                    CrossEnumMap.this.remove(pair.getFirst(), pair.getSecond());
+                    return true;
+                })
+                .orElse(false);
+        }
+
+    }
+
+    private class ValueIterator extends CrossIterator<V> {
+        @Override
+        public V produce() {
+            return getValueAt(index1, index2);
+        }
+    }
+
+    private class KeyIterator extends CrossIterator<Pair<K1, K2>> {
+        @Override
+        public Pair<K1, K2> produce() {
+            return Pair.of(universe1[index1], universe2[index2]);
+        }
+    }
+
+    private class EntryIterator extends CrossIterator<Map.Entry<Pair<K1, K2>, V>> {
+        @Override
+        public Map.Entry<Pair<K1, K2>, V> produce() {
+            return new CrossEntry(index1, index2);
+        }
+    }
+
+    @AllArgsConstructor
+    private class CrossEntry implements Map.Entry<Pair<K1, K2>, V> {
+        private final int index1;
+        private final int index2;
+
+        @Override
+        public Pair<K1, K2> getKey() {
+            return Pair.of(universe1[index1], universe2[index2]);
+        }
+
+        @Override
+        public V getValue() {
+            return getValueAt(index1, index2);
+        }
+
+        @Override
+        public V setValue(V value) {
+            V prev = getValueAt(index1, index2);
+            values[index1][index2] = value;
+            return prev;
+        }
+    }
+
+    private abstract class CrossIterator<Q> implements Iterator<Q> {
+        protected int visited;
+        protected int index1;
+        protected int index2;
+
+        public abstract Q produce();
+
+        @Override
+        public boolean hasNext() {
+            return visited < size;
+        }
+
+        @Override
+        public Q next() {
+            while (inc()) {}
+            visited++;
+            return produce();
+        }
+
+        private boolean inc() {
+            index1++;
+            if(index1 >= universe1.length) {
+                index1 = 0;
+                index2++;
+            }
+            if(index2 >= universe2.length) {
+                throw new NoSuchElementException();
+            }
+            return values[index1][index2] != null;
+        }
+
+        @Override
+        public void remove() {
+            if(values[index1][index2] != null) {
+                values[index1][index2] = null;
+                size--;
+            }
+        }
+    }
+
+}

+ 106 - 0
assira/src/main/java/net/ranides/assira/collection/maps/CrossHashMap.java

@@ -0,0 +1,106 @@
+package net.ranides.assira.collection.maps;
+
+import net.ranides.assira.generic.Pair;
+
+import java.io.Serializable;
+import java.util.Collection;
+import java.util.Map;
+import java.util.Optional;
+import java.util.Set;
+
+public class CrossHashMap<K1, K2, V> implements CrossMap<K1, K2, V>, Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    private final Map<Pair<K1, K2>, V> map;
+
+    public CrossHashMap() {
+        this.map = new HashMap<>();
+    }
+
+    @Override
+    public int size() {
+        return map.size();
+    }
+
+    @Override
+    public boolean isEmpty() {
+        return map.isEmpty();
+    }
+
+    @Override
+    public boolean containsKey(K1 key1, K2 key2) {
+        return map.containsKey(Pair.of(key1, key2));
+    }
+
+    @Override
+    public boolean containsValue(V value) {
+        return map.containsValue(value);
+    }
+
+    @Override
+    public V get(K1 key1, K2 key2) {
+        return map.get(Pair.of(key1, key2));
+    }
+
+    @Override
+    public Optional<V> getOptional(K1 key1, K2 key2) {
+        return Optional.ofNullable(get(key1, key2));
+    }
+
+    @Override
+    public V put(K1 key1, K2 key2, V value) {
+        return map.put(Pair.of(key1, key2), value);
+    }
+
+    @Override
+    public V remove(K1 key1, K2 key2) {
+        return map.remove(Pair.of(key1, key2));
+    }
+
+    @Override
+    public void putAll(CrossMap<K1, K2, ? extends V> values) {
+        values.forEachPair(map::put);
+    }
+
+    @Override
+    public void clear() {
+        map.clear();
+    }
+
+    @Override
+    public MultiMap<K2, V> reduceFirst() {
+        HashMultiMap<K2, V> result = new HashMultiMap<>();
+        map.forEach((key, value) -> result.put(key.getSecond(), value));
+        return result;
+    }
+
+    @Override
+    public MultiMap<K1, V> reduceSecond() {
+        HashMultiMap<K1, V> result = new HashMultiMap<>();
+        map.forEach((key, value) -> result.put(key.getFirst(), value));
+        return result;
+    }
+
+    @Override
+    public Map<K1, K2> reduceValues() {
+        HashMultiMap<K1, K2> result = new HashMultiMap<>();
+        map.forEach((key, value) -> result.put(key.getFirst(), key.getSecond()));
+        return result;
+    }
+
+    @Override
+    public Set<Pair<K1, K2>> keySet() {
+        return map.keySet();
+    }
+
+    @Override
+    public Collection<V> values() {
+        return map.values();
+    }
+
+    @Override
+    public Set<Map.Entry<Pair<K1, K2>, V>> entrySet() {
+        return map.entrySet();
+    }
+}

+ 96 - 0
assira/src/main/java/net/ranides/assira/collection/maps/CrossMap.java

@@ -0,0 +1,96 @@
+/*
+ *  @author Ranides Atterwim <ranides@gmail.com>
+ *  @copyright Ranides Atterwim
+ *  @license WTFPL
+ *  @url http://ranides.net/projects/assira
+ */
+
+package net.ranides.assira.collection.maps;
+
+import net.ranides.assira.functional.Consumers;
+import net.ranides.assira.functional.Consumers.Consumer3;
+import net.ranides.assira.generic.Pair;
+
+import java.util.Collection;
+import java.util.ConcurrentModificationException;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Optional;
+import java.util.Set;
+import java.util.function.BiConsumer;
+
+/**
+ * 2-dimensional map
+ *
+ * @param <K1>
+ * @param <K2>
+ * @param <V> 
+ * @author Ranides Atterwim <ranides@gmail.com>
+ */
+public interface CrossMap<K1, K2, V> {
+
+    int size();
+
+    boolean isEmpty();
+
+    boolean containsKey(K1 key1, K2 key2);
+
+    boolean containsValue(V value);
+
+    V get(K1 key1, K2 key2);
+
+    Optional<V> getOptional(K1 key1, K2 key2);
+
+    V put(K1 key1, K2 key2, V value);
+    
+    V remove(K1 key1, K2 key2);
+
+    void putAll(CrossMap<K1, K2, ? extends V> values);
+
+    void clear();
+
+    MultiMap<K2, V> reduceFirst();
+
+    MultiMap<K1, V> reduceSecond();
+
+    Map<K1, K2> reduceValues();
+
+    Set<Pair<K1, K2>> keySet();
+
+    Collection<V> values();
+
+    Set<Map.Entry<Pair<K1, K2>, V>> entrySet();
+
+    default void forEachPair(BiConsumer<Pair<K1, K2>, V> action) {
+        Objects.requireNonNull(action);
+        for (Map.Entry<Pair<K1, K2>, V> entry : entrySet()) {
+            Pair<K1, K2> pair;
+            V val;
+            try {
+                pair = entry.getKey();
+                val = entry.getValue();
+            } catch (IllegalStateException ise) {
+                // this usually means the entry is no longer in the map.
+                throw new ConcurrentModificationException(ise);
+            }
+            action.accept(pair, val);
+        }
+    }
+
+    default void forEach(Consumer3<K1, K2, V> action) {
+        Objects.requireNonNull(action);
+        for (Map.Entry<Pair<K1, K2>, V> entry : entrySet()) {
+            Pair<K1, K2> pair;
+            V val;
+            try {
+                pair = entry.getKey();
+                val = entry.getValue();
+            } catch (IllegalStateException ise) {
+                // this usually means the entry is no longer in the map.
+                throw new ConcurrentModificationException(ise);
+            }
+            action.accept(pair.getFirst(), pair.getSecond(), val);
+        }
+    }
+
+}

+ 27 - 0
assira/src/main/java/net/ranides/assira/generic/IntPair.java

@@ -0,0 +1,27 @@
+/*
+ * @author Ranides Atterwim <ranides@gmail.com>
+ * @copyright Ranides Atterwim
+ * @license WTFPL
+ * @url http://ranides.net/projects/assira
+ */
+package net.ranides.assira.generic;
+
+import lombok.Data;
+
+import java.io.Serializable;
+
+@Data(staticConstructor = "of")
+public final class IntPair implements Comparable<IntPair>, Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    private final int first;
+    private final int second;
+
+    @Override
+    public int compareTo(IntPair that) {
+        int cmp1 = Integer.compare(this.first, that.first);
+        return cmp1 != 0 ? cmp1 : Integer.compare(this.second, that.second);
+    }
+
+}

+ 28 - 0
assira/src/main/java/net/ranides/assira/generic/Pair.java

@@ -0,0 +1,28 @@
+/*
+ * @author Ranides Atterwim <ranides@gmail.com>
+ * @copyright Ranides Atterwim
+ * @license WTFPL
+ * @url http://ranides.net/projects/assira
+ */
+package net.ranides.assira.generic;
+
+import lombok.Data;
+import org.jetbrains.annotations.NotNull;
+
+import java.io.Serializable;
+
+@Data(staticConstructor = "of")
+public final class Pair<P,Q> implements Comparable<Pair<P,Q>>, Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    private final P first;
+    private final Q second;
+
+    @Override
+    public int compareTo(Pair<P, Q> that) {
+        int cmp1 = CompareUtils.cmp(this.first, that.first);
+        return cmp1 != 0 ? cmp1 : CompareUtils.cmp(this.second, that.second);
+    }
+
+}

+ 4 - 1
assira/src/main/java/net/ranides/assira/generic/Tuple.java

@@ -6,10 +6,13 @@
  */
 package net.ranides.assira.generic;
 
+import java.io.Serializable;
 import java.util.Arrays;
 import net.ranides.assira.collection.arrays.ArrayUtils;
 
-public final class Tuple implements Comparable<Tuple> {
+public final class Tuple implements Comparable<Tuple>, Serializable {
+
+    private static final long serialVersionUID = 1L;
 
     private final Object[] values;
 

+ 0 - 129
assira1/src/main/java/net/ranides/assira/collection_map/CrossCompositeMap.java

@@ -1,129 +0,0 @@
-/*
- *  @author Ranides Atterwim <ranides@gmail.com>
- *  @copyright Ranides Atterwim
- *  @license WTFPL
- *  @url http://ranides.net/projects/assira
- */
-
-package net.ranides.assira.collection.map;
-
-import java.util.HashMap;
-import java.util.Map.Entry;
-
-/**
- * Implementacja dwu-wymiarowej mapy używająca wewnętrznie jednej mapy, 
- * zawierającej klucze złożone. 
- * @param <KX> 
- * @param <KY> 
- * @param <V> 
- * @author ranides
- */
-@SuppressWarnings("unchecked")
-public class CrossCompositeMap<KX, KY, V> implements CrossMap<KX, KY, V>  {
-
-    private final HashMap<CKey, V> map;
-
-    /**
-     * Constructs an empty <tt>CrossCompositeMap</tt> with the default initial capacity
-     * (16) and the default load factor (0.75).
-     */
-    public CrossCompositeMap() {
-        map = new HashMap<>();
-    }
-
-    /**
-     * Constructs an empty <tt>CrossCompositeMap</tt> with the specified initial
-     * capacity and load factor.
-     *
-     * @param  initialCapacity the initial capacity
-     * @param  loadFactor      the load factor
-     * @throws IllegalArgumentException if the initial capacity is negative
-     *         or the load factor is nonpositive
-     */
-    public CrossCompositeMap(int initialCapacity, float loadFactor) {
-        map = new HashMap<>(initialCapacity, loadFactor);
-    }
-
-    @Override
-    public boolean contains(KX xKey, KY yKey) {
-        return map.containsKey( new CKey(xKey, yKey) );
-    }
-
-    @Override
-    public V put(KX xKey, KY yKey, V value) {
-        return map.put(new CKey(xKey, yKey), value);
-    }
-
-    @Override
-    public V remove(KX xKey, KY yKey) {
-        return map.remove(new CKey(xKey, yKey));
-    }
-
-    @Override
-    public V get(KX xKey, KY yKey) {
-        return map.get(new CKey(xKey, yKey));
-    }
-
-    @Override
-    public int size() {
-        return map.size();
-    }
-
-    @Override
-    public boolean isEmpty() {
-        return map.isEmpty();
-    }
-
-    @Override
-    public void clear() {
-        map.clear();
-    }
-
-    @Override
-    public MultiMap<KX, KY> reduceZ() {
-        MultiMap<KX, KY> result = new MultiHashMap<>();
-        for(CKey item : map.keySet() ) {
-            result.putItem(item.xKey, item.yKey);
-
-        }
-        return result;
-    }
-
-    @Override
-    public MultiMap<KX, V> reduceY() {
-        MultiMap<KX, V> result = new MultiHashMap<>();
-        for( Entry<CKey, V> item : map.entrySet() ) {
-            result.get( item.getKey().xKey ).add( item.getValue() );
-        }
-        return result;
-    }
-
-/* ************************************************************************** */
-
-    private final class CKey {
-        private final KX xKey;
-        private final KY yKey;
-
-        public CKey(KX xKey, KY yKey) {
-            this.xKey = xKey;
-            this.yKey = yKey;
-        }
-
-        @Override
-        public boolean equals(Object object) {
-            if (object==null || object.getClass().equals(CKey.class) ) {
-                return false;
-            }
-            final CKey value =(CKey) object;
-            return value.xKey.equals(xKey) && value.yKey.equals(yKey);
-        }
-
-        @Override
-        public int hashCode() {
-            // duża liczba pierwsza
-            return 1073676287 * xKey.hashCode() + yKey.hashCode();
-        }
-
-    }
-
-}

+ 0 - 96
assira1/src/main/java/net/ranides/assira/collection_map/CrossEnumMap.java

@@ -1,96 +0,0 @@
-/*
- * @author Ranides Atterwim <ranides@gmail.com>
- * @copyright Ranides Atterwim
- * @license WTFPL
- * @url http://ranides.net/projects/assira
- */
-package net.ranides.assira.collection.map;
-
-import java.util.ArrayList;
-import java.util.EnumMap;
-import java.util.Map;
-
-/**
- * Implementacja dwu-wymiarowej mapy zoptymalizowana dla typów {@code Enum}.
- * @param <KX> 
- * @param <KY> 
- * @param <V> 
- * @author ranides
- */
-@SuppressWarnings("PMD.ShortVar")
-public final class CrossEnumMap<KX extends Enum<KX>, KY extends Enum<KY>, V> implements CrossMap<KX, KY, V> {
-    
-    private final EnumMap<KX, EnumMap<KY, V>> data;
-
-    /**
-     * Tworzy pustą mapę, która jako współrzędnych używa podanych typów {@code enum}.
-     * @param xclass
-     * @param yclass
-     */
-    public CrossEnumMap(Class<KX> xclass, Class<KY> yclass) {
-        this.data = new EnumMap<>(xclass);
-        for(KX x : xclass.getEnumConstants()) {
-            this.data.put(x, new EnumMap<KY, V>(yclass));
-        }
-    }
-
-    @Override
-    public boolean contains(KX x, KY y) {
-        return data.get(x).containsKey(y);
-    }
-
-    @Override
-    public V put(KX x, KY y, V value) {
-        V prev = data.get(x).get(y);
-        data.get(x).put(y, value);
-        return prev;
-    }
-
-    @Override
-    public V remove(KX x, KY y) {
-        V prev = data.get(x).get(y);
-        data.get(x).remove(y);
-        return prev;
-    }
-
-    @Override
-    public V get(KX x, KY y) {
-        return data.get(x).get(y);
-    }
-
-    @Override
-    public int size() {
-        int size = 0;
-        for(EnumMap<KY,V> map : data.values()) { size += map.size(); }
-        return size;
-    }
-
-    @Override
-    public boolean isEmpty() {
-        return size() == 0;
-    }
-
-    @Override
-    public void clear() {
-        for(EnumMap<KY,V> map : data.values()) { map.clear(); }
-    }
-
-    @Override
-    public MultiMap<KX, KY> reduceZ() {
-        MultiMap<KX, KY> result = new MultiHashMap<>();
-        for(Map.Entry<KX, ? extends Map<KY,V>> entry : data.entrySet() ) {
-            result.put(entry.getKey(), new ArrayList<>(entry.getValue().keySet()) );
-        }
-        return result;
-    }
-
-    @Override
-    public MultiMap<KX, V> reduceY() {
-        MultiMap<KX, V> result = new MultiHashMap<>();
-        for( Map.Entry<KX, ? extends Map<KY,V>> item : data.entrySet() ) {
-            result.put( item.getKey(), new ArrayList<>(item.getValue().values()) );
-        }
-        return result;
-    }
-    
-}

+ 0 - 105
assira1/src/main/java/net/ranides/assira/collection_map/CrossHashMap.java

@@ -1,105 +0,0 @@
-/*
- *  @author Ranides Atterwim <ranides@gmail.com>
- *  @copyright Ranides Atterwim
- *  @license WTFPL
- *  @url http://ranides.net/projects/assira
- */
-
-package net.ranides.assira.collection.map;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.Map.Entry;
-
-/**
- * Implementacja dwu-wymiarowej mapy używająca wewnętrznie {@code HashMap<HashMap<>>}
- * @param <KX> 
- * @param <KY> 
- * @param <V> 
- * @author ranides
- */
-@SuppressWarnings("PMD.ShortVar")
-public class CrossHashMap<KX, KY, V> implements CrossMap<KX, KY, V> {
-    
-    private static final long serialVersionUID = 3L;
-    
-    private final HashMap<KX, HashMap<KY,V>> data;
-
-    /**
-     * Constructs an empty <tt>CrossHashMap</tt> with the default initial capacity
-     * (16) and the default load factor (0.75).
-     */
-    public CrossHashMap() {
-        data = new HashMap<>();
-    }
-
-    @Override
-    public boolean contains(KX x, KY y) {
-        return data.containsKey(x) && data.get(x).containsKey(y);
-    }
-
-    @Override
-    public V put(KX x, KY y, V value) {
-        if( !data.containsKey(x) ) {
-            data.put(x, new HashMap<KY,V>());
-        }
-        return data.get(x).put(y, value);
-    }
-
-    @Override
-    public V remove(KX x, KY y) {
-        if( !data.containsKey(x) ) {
-            return null;
-        }
-        V value = data.get(x).remove(y);
-        if( data.get(x).isEmpty() ) {
-            data.remove(x);
-        }
-        return value;
-    }
-
-    @Override
-    public V get(KX x, KY y) {
-        return data.containsKey(x) ? data.get(x).get(y) : null;
-    }
-
-    @Override
-    public final MultiMap<KX, KY> reduceZ() {
-        MultiMap<KX, KY> result = new MultiHashMap<>();
-        for(Entry<KX, HashMap<KY,V>> entry : data.entrySet() ) {
-            result.put(entry.getKey(), new ArrayList<>(entry.getValue().keySet()) );
-        }
-        return result;
-    }
-
-    @Override
-    public final MultiMap<KX, V> reduceY() {
-        MultiMap<KX, V> result = new MultiHashMap<>();
-        for( Entry<KX, HashMap<KY,V>> item : data.entrySet() ) {
-            result.put( item.getKey(), new ArrayList<>(item.getValue().values()) );
-        }
-        return result;
-    }
-
-    @Override
-    public int size() {
-        int sum = 0;
-        for(HashMap<KY,V> row : data.values()) {
-            sum += row.size();
-        }
-        return sum;
-    }
-
-    @Override
-    public boolean isEmpty() {
-        return 0 == size();
-    }
-
-    @Override
-    public void clear() {
-        data.clear();
-    }
-
-    
-
-}

+ 0 - 81
assira1/src/main/java/net/ranides/assira/collection_map/CrossMap.java

@@ -1,81 +0,0 @@
-/*
- *  @author Ranides Atterwim <ranides@gmail.com>
- *  @copyright Ranides Atterwim
- *  @license WTFPL
- *  @url http://ranides.net/projects/assira
- */
-
-package net.ranides.assira.collection.map;
-
-/**
- * Interfejs reprezentujący mapę dwuwymiarową.
- * @param <KX> 
- * @param <KY> 
- * @param <V> 
- * @author ranides
- */
-@SuppressWarnings("PMD.ShortVar")
-public interface CrossMap<KX, KY, V> {
-
-    /**
-     * Sprawdza, czy zawiera wartość przypisaną do podanych kluczy.
-     * @param x
-     * @param y
-     * @return
-     */
-    boolean contains(KX x, KY y);
-    
-    /**
-     * Przypisuje nową wartość do podanych kluczy.
-     * @param x
-     * @param y
-     * @param value
-     * @return poprzednio przypisana wartość lub {@code null}.
-     */
-    V put(KX x, KY y, V value);
-    
-    /**
-     * Usuwa wartość przypisaną do podanych kluczy.
-     * @param x
-     * @param y
-     * @return usunięta wartość lub {@code null}.
-     */
-    V remove(KX x, KY y);
-    
-    /**
-     * Pobiera wartość przypisaną do podanych kluczy.
-     * @param x
-     * @param y
-     * @return przypisana wartość lub {@code null}.
-     */
-    V get(KX x, KY y);
-
-    /**
-     * Zwraca rozmiar mapy.
-     * @return
-     */
-    int size();
-    
-    /**
-     * Sprawdza, czy mapa jest pusta.
-     * @return
-     */
-    boolean isEmpty();
-    
-    /**
-     * Usuwa całą zawartość mapy.
-     */
-    void clear();
-
-    /**
-     * Redukuje przypisane wartości i zwraca multi-mapę zawierającą klucze
-     * @return
-     */
-    MultiMap<KX, KY> reduceZ();
-    
-    /**
-     * Redukuje klucz drugiego rzędu i zwraca multi-mapę zawierającą klucze główne i przypisane im wartości
-     * @return
-     */
-    MultiMap<KX, V> reduceY();
-}