Sfoglia il codice sorgente

new: IntMapUtils#map
new: IntMapUtils#wrap
new: IntMultiMap - default methods

Ranides Atterwim 10 anni fa
parent
commit
76454714e7

+ 1 - 0
assira/pom.xml

@@ -39,6 +39,7 @@
                                 <include>net/ranides/assira/collection/lists/ListUtils</include>
                                 <include>net/ranides/assira/collection/sets/Bitmask*</include>
                                 <include>net/ranides/assira/collection/maps/MapUtils*</include>
+                                <include>net/ranides/assira/collection/maps/IntMapUtils*</include>
                                 <include>net/ranides/assira/collection/maps/IntMapCollectors*</include>
                                 <include>net/ranides/assira/collection/maps/MapCollectors*</include>
                                 <include>net/ranides/assira/collection/maps/MultiMap*</include>

+ 209 - 12
assira/src/main/java/net/ranides/assira/collection/maps/IntMapUtils.java

@@ -6,9 +6,11 @@
  */
 package net.ranides.assira.collection.maps;
 
+import java.io.Serializable;
 import java.util.Collection;
 import java.util.Map;
 import java.util.Set;
+import java.util.function.BiFunction;
 import java.util.function.Function;
 import net.ranides.assira.collection.CollectionUtils;
 import net.ranides.assira.collection.sets.IntSet;
@@ -22,28 +24,59 @@ import net.ranides.assira.generic.CompareUtils;
  */
 public final class IntMapUtils {
     
-    // @todo (assira #6) IntMapUtils: multimap, inserter
-    
     private IntMapUtils() {
         /* utility class */
     }
     
     public static <TV, RV> IntMap<RV> map(IntMap<TV> map, Function<? super TV, ? extends RV> function) {
-        return new MapAdapter<>(map, function);
+        return new MapAdapter<>(map, function, null);
+    }
+    
+    public static <TV, RV> IntMap<RV> map(IntMap<TV> map, Function<? super TV, ? extends RV> function, BiFunction<Integer, ? super RV, ? extends RV> inserter) {
+        return new MapAdapter<>(map, function, inserter);
     }
     
     public static <TV, RV> IntMap<RV> map(IntMap<TV> map, ProjectionFunction<TV, RV> function) {
         return new MapProjection<>(map, function);
     }
     
+    public static <TV, RV> IntMultiMap<RV> map(IntMultiMap<TV> map, Function<? super TV, ? extends RV> function) {
+        return new MMapAdapter<>(map, function, null);
+    }
+    
+    public static <TV, RV> IntMultiMap<RV> map(IntMultiMap<TV> map, Function<? super TV, ? extends RV> function, BiFunction<Integer, ? super RV, ? extends RV> inserter) {
+        return new MMapAdapter<>(map, function, inserter);
+    }
+    
+    public static <TV, RV> IntMultiMap<RV> map(IntMultiMap<TV> map, ProjectionFunction<TV, RV> function) {
+        return new MMapProjection<>(map, function);
+    }
+    
+    public static <TV, RV> IntMap<RV> wrap(IntMap<TV> map, Function<? super TV, ? extends RV> getter, BiFunction<? super TV, ? super RV, ? extends RV> setter) {
+        return new MapWrapper<>(map, getter, setter);
+    }
+    
+    public static <K, TV, RV> IntMultiMap<RV> wrap(IntMultiMap<TV> map, Function<? super TV, ? extends RV> getter, BiFunction<? super TV, ? super RV, ? extends RV> setter) {
+        return new MMapWrapper<>(map, getter, setter);
+    }
+    
     private static class MapAdapter<TV, RV> extends AIntMap<RV> {
+        
+        private static final long serialVersionUID = 1L;
+        
+        @SuppressWarnings("unchecked")
+        private static final BiFunction NSE = (Serializable & BiFunction)(a,b) -> { 
+            throw new UnsupportedOperationException(); 
+        };
 
-        private final IntMap<TV> content;
-        private final Function<? super TV, ? extends RV> function;
+        protected final IntMap<TV> content;
+        protected final Function<? super TV, ? extends RV> function;
+        protected final BiFunction<Integer, ? super RV, ? extends RV> inserter;
 
-        public MapAdapter(IntMap<TV> content, Function<? super TV, ? extends RV> function) {
+        public MapAdapter(IntMap<TV> content, Function<? super TV, ? extends RV> function, BiFunction<Integer, ? super RV, ? extends RV> inserter) {
             this.content = content;
             this.function = function;
+            this.inserter = null != inserter ? inserter : NSE;
         }
 
         @Override
@@ -91,6 +124,12 @@ public final class IntMapUtils {
         public RV get(int key) {
             return function.apply(content.get(key));
         }
+        
+        @Override
+        public RV put(int key, RV value) {
+            return inserter.apply(key, value);
+        }
+        
 
         private final class EntryAdapter implements IntEntry<RV> {
             
@@ -112,7 +151,7 @@ public final class IntMapUtils {
 
             @Override
             public RV setValue(RV value) {
-                throw new UnsupportedOperationException();
+                return inserter.apply(delegate.getKey(), value);
             }
             
             @Override
@@ -143,10 +182,12 @@ public final class IntMapUtils {
 
     }
     
-    private static class MapProjection<K, TV, RV> extends AIntMap<RV> {
+    private static class MapProjection<TV, RV> extends AIntMap<RV> {
+        
+        private static final long serialVersionUID = 1L;
 
-        private final IntMap<TV> content;
-        private final ProjectionFunction<TV, RV> function;
+        protected final IntMap<TV> content;
+        protected final ProjectionFunction<TV, RV> function;
 
         public MapProjection(IntMap<TV> content, ProjectionFunction<TV, RV> function) {
             this.content = content;
@@ -261,11 +302,11 @@ public final class IntMapUtils {
                 }
                 if (getClass() == obj.getClass()) {
                     @SuppressWarnings("unchecked")
-                    MapProjection.EntryProjection other = (MapProjection.EntryProjection) obj;
+                    EntryProjection other = (EntryProjection) obj;
                     return delegate.equals(other.delegate);
                 } else {
                     @SuppressWarnings("unchecked")
-                    Map.Entry<K,RV> other = (Map.Entry<K,RV>)obj;
+                    Map.Entry<Integer,RV> other = (Map.Entry<Integer,RV>)obj;
                     return CompareUtils.equals(getKey(), other.getKey()) && CompareUtils.equals(getValue(), other.getValue());
                 }
             }
@@ -274,4 +315,160 @@ public final class IntMapUtils {
 
     }
     
+    private static class MMapAdapter<TV, RV> extends MapAdapter<TV, RV> implements IntMultiMap<RV> {
+        
+        private static final long serialVersionUID = 1L;
+        
+        private final IntMultiMap<TV> mcontent;
+
+        public MMapAdapter(IntMultiMap<TV> mcontent, Function<? super TV, ? extends RV> function, BiFunction<Integer, ? super RV, ? extends RV> setter) {
+            super(mcontent, function, setter);
+            this.mcontent = mcontent;
+        }
+        
+        @Override
+        public Collection<RV> getAll(int key) {
+            return CollectionUtils.map(mcontent.getAll(key), function);
+        }
+        
+    }
+    
+    private static class MMapProjection<TV, RV> extends MapProjection<TV,RV> implements IntMultiMap<RV> {
+        
+        private static final long serialVersionUID = 1L;
+        
+        private final IntMultiMap<TV> mcontent;
+        
+        public MMapProjection(IntMultiMap<TV> content, ProjectionFunction<TV, RV> function) {
+            super(content, function);
+            this.mcontent = content;
+        }
+        
+        @Override
+        public Collection<RV> getAll(int key) {
+            return CollectionUtils.map(mcontent.getAll(key), function);
+        }
+
+    }
+    
+    private static class MMapWrapper<TV, RV> extends MapWrapper<TV,RV> implements IntMultiMap<RV> { 
+        
+        private static final long serialVersionUID = 1L;
+
+        private final IntMultiMap<TV> mcontent;
+                
+        public MMapWrapper(IntMultiMap<TV> content, Function<? super TV, ? extends RV> getter, BiFunction<? super TV, ? super RV, ? extends RV> setter) {
+            super(content, getter, setter);
+            this.mcontent = content;
+        }
+
+        @Override
+        public Collection<RV> getAll(int key) {
+            return CollectionUtils.map(mcontent.getAll(key), getter);
+        }
+        
+    }
+    
+    private static class MapWrapper<TV, RV> extends AIntMap<RV> implements IntMap<RV> { 
+
+        private static final long serialVersionUID = 1L;
+
+        protected final IntMap<TV> content;        
+        protected final Function<? super TV, ? extends RV> getter;
+        protected final BiFunction<? super TV, ? super RV, ? extends RV> setter;
+
+        public MapWrapper(IntMap<TV> content, Function<? super TV, ? extends RV> getter, BiFunction<? super TV, ? super RV, ? extends RV> setter) {
+            this.content = content;
+            this.getter = getter;
+            this.setter = setter;
+        }
+
+        @Override
+        public int size() {
+            return content.size();
+        }
+
+        @Override
+        public boolean containsKey(int key) {
+            return content.containsKey(key);
+        }
+
+        @Override
+        public boolean containsValue(Object value) {
+            return values().contains(value);
+        }
+
+        @Override
+        public RV get(int key) {
+            TV var = content.get(key);
+            return null!=var ? getter.apply(var) : null;
+        }
+
+        @Override
+        public RV put(int key, RV value) {
+            TV var = content.get(key);
+            return null!=var ? setter.apply(var, value) : null;
+        }
+        
+        @Override
+        public IntSet keySet() {
+            return content.keySet();
+        }
+
+        @Override
+        public Collection<RV> values() {
+            return CollectionUtils.map(content.values(), getter);
+        }
+        
+        @Override
+        public Set<IntEntry<RV>> fastEntrySet() {
+            return SetUtils.map(content.fastEntrySet(), e -> new EntryWrapper(e));
+        }
+        
+        private final class EntryWrapper implements IntEntry<RV> {
+            
+            private final IntEntry<TV> delegate;
+
+            public EntryWrapper(IntEntry<TV> delegate) {
+                this.delegate = delegate;
+            }
+
+            @Override
+            public int getIntKey() {
+                return delegate.getKey();
+            }
+
+            @Override
+            public RV getValue() {
+                return getter.apply(delegate.getValue());
+            }
+
+            @Override
+            public RV setValue(RV value) {
+                return setter.apply(delegate.getValue(), value);
+            }
+
+            @Override
+            public int hashCode() {
+                return delegate.hashCode();
+            }
+
+            @Override
+            public boolean equals(Object obj) {
+                if (this == obj) {
+                    return true;
+                }
+                if (!(obj instanceof Map.Entry)) {
+                    return false;
+                }
+                @SuppressWarnings("unchecked")
+                Map.Entry<Integer,RV> other = (Map.Entry<Integer,RV>)obj;
+                return CompareUtils.equals(getKey(), other.getKey()) 
+                    && CompareUtils.equals(getValue(), other.getValue());
+            }
+            
+        }
+        
+    }
+    
 }

+ 27 - 5
assira/src/main/java/net/ranides/assira/collection/maps/IntMultiMap.java

@@ -6,9 +6,14 @@
  */
 package net.ranides.assira.collection.maps;
 
+import java.util.ArrayList;
 import java.util.Collection;
+import java.util.NoSuchElementException;
 import java.util.function.BinaryOperator;
+import net.ranides.assira.collection.sets.HashSet;
+import net.ranides.assira.collection.sets.IntHashSet;
 import net.ranides.assira.collection.sets.IntSet;
+import net.ranides.assira.functional.Fold;
 //import net.ranides.assira.functional.Fold;
 
 /**
@@ -19,13 +24,28 @@ public interface IntMultiMap<V> extends IntMap<V>, MultiMap<Integer, V> {
     
     Collection<V> getAll(int key);
     
-    V get(int key, BinaryOperator<V> fold);
+    default V get(int key, BinaryOperator<V> fold) {
+        return getAll(key).stream().reduce(fold).orElseThrow(()->new NoSuchElementException());
+    }
     
-    boolean containsEntry(int key, Object value);
+    default boolean containsEntry(int key, Object value) {
+        return getAll(key).contains(value);
+    }
 
-    void putAll(int key, Iterable<? extends V> values);
+    default void putAll(int key, Iterable<? extends V> values) {
+        for(V value : values) {
+            put(key, value);
+        }
+    }
 
-    Collection<V> removeAll(int key);
+    default Collection<V> removeAll(int key) {
+        Collection<V> prev = new ArrayList<>();
+        V last;
+        while(null != (last=remove(key))) {
+            prev.add(last);
+        }
+        return prev;
+    }
     
     @Override
     default Collection<V> getAll(Object key) {
@@ -53,7 +73,9 @@ public interface IntMultiMap<V> extends IntMap<V>, MultiMap<Integer, V> {
     }
     
     @Override
-    IntSet uniqueKeySet();
+    default IntSet uniqueKeySet() {
+        return new IntHashSet(keySet());
+    }
     
     
 }

+ 8 - 8
assira/src/main/java/net/ranides/assira/collection/maps/MapUtils.java

@@ -23,11 +23,6 @@ import net.ranides.assira.generic.CompareUtils;
  */
 public final class MapUtils {
     
-    @SuppressWarnings("unchecked")
-    private static final BiFunction NSE = (Serializable & BiFunction)(a,b) -> { 
-        throw new UnsupportedOperationException(); 
-    };
-    
     private MapUtils() {
         /* utility class */
     }
@@ -85,10 +80,15 @@ public final class MapUtils {
     private static class MapAdapter<K, TV, RV> extends AMap<K, RV> implements Map<K, RV> {
         
         private static final long serialVersionUID = 1L;
-
+        
+        @SuppressWarnings("unchecked")
+        private static final BiFunction NSE = (Serializable & BiFunction)(a,b) -> { 
+            throw new UnsupportedOperationException(); 
+        };
+        
         protected final Map<K, TV> content;
-        protected  final Function<? super TV, ? extends RV> function;
-        protected  final BiFunction<? super K, ? super RV, ? extends RV> inserter;
+        protected final Function<? super TV, ? extends RV> function;
+        protected final BiFunction<? super K, ? super RV, ? extends RV> inserter;
         
         public MapAdapter(Map<K, TV> content, Function<? super TV, ? extends RV> function, BiFunction<? super K, ? super RV, ? extends RV> setter) {
             this.content = content;

+ 1 - 3
assira/src/main/java/net/ranides/assira/generic/EnumUtils.java

@@ -8,6 +8,7 @@
 package net.ranides.assira.generic;
 
 import java.util.Arrays;
+import java.util.EnumMap;
 import java.util.Map;
 import java.util.function.Function;
 import java.util.function.ToIntFunction;
@@ -16,9 +17,6 @@ import net.ranides.assira.collection.maps.IntMapCollectors;
 import net.ranides.assira.collection.maps.MapCollectors;
 
 public final class EnumUtils {
-    
-    // @todo (assira #4) EnumUtils ?
-    // przemyśleć, jak to pakietować / czy w ogóle powinno być
 
     private EnumUtils() {
         // utility class

+ 0 - 6
assira/src/test/java/net/ranides/assira/xml/impl/W3DocumentTest.java

@@ -93,12 +93,6 @@ public class W3DocumentTest {
         
         assertEquals(exp, out);
         
-        // @todo (assira #3.5) xml: namespaces
-        // nie umiemy wstawiać elementów z namespace'ami
-        // w ogóle nie umiemy konfigurować dokumentu w kwestii NS
-        // http://stackoverflow.com/questions/11133754/adding-namespace-to-an-already-created-xml-document
-        
-        
     }
     
 }