Browse Source

new: IntMapCollectors
new: MapCollectors
new: EnumUtils

Ranides Atterwim 10 years ago
parent
commit
203e4559a7

+ 155 - 0
assira/src/main/java/net/ranides/assira/collection/maps/IntMapCollectors.java

@@ -0,0 +1,155 @@
+/*
+ * @author Ranides Atterwim <ranides@gmail.com>
+ * @copyright Ranides Atterwim
+ * @license WTFPL
+ * @url http://ranides.net/projects/assira
+ */
+
+package net.ranides.assira.collection.maps;
+
+import java.util.EnumSet;
+import java.util.Set;
+import java.util.function.BiConsumer;
+import java.util.function.BinaryOperator;
+import java.util.function.Function;
+import java.util.function.Supplier;
+import java.util.function.ToIntFunction;
+import java.util.stream.Collector;
+
+/**
+ *
+ * @author Ranides Atterwim <ranides@gmail.com>
+ */
+public final class IntMapCollectors {
+    
+    private IntMapCollectors() {
+        /* utility class */
+    }
+    
+    public static <R,V> Collector<R,?, IntMap<R>> unique(ToIntFunction<? super R> key) {
+        return IntMapCollectors.unique(key, v -> v);
+    }
+    
+    public static <R,V> Collector<R,?, IntMap<V>> unique(ToIntFunction<? super R> key, Function<R, V> val) {
+        return unique(key, val, () -> new IntHashMap<>());
+    }
+    
+    public static <R,V> Collector<R,?, IntMap<V>> unique(ToIntFunction<? super R> key, Function<? super R, ? extends V> val, Supplier<IntMap<V>> supplier) {
+        return new UCollector<>(key, val, supplier);
+    }
+    
+    public static <R,V> Collector<R,?, IntMultiMap<R>> multimap(ToIntFunction<? super R> key) {
+        return IntMapCollectors.multimap(key, v -> v);
+    }
+    
+    public static <R,V> Collector<R,?, IntMultiMap<V>> multimap(ToIntFunction<? super R> key, Function<R, V> val) {
+        return multimap(key, val, () -> new IntHashMultiMap<>());
+    }
+    
+    public static <R,V> Collector<R,?, IntMultiMap<V>> multimap(ToIntFunction<? super R> key, Function<? super R, ? extends V> val, Supplier<IntMultiMap<V>> supplier) {
+        return new MCollector<>(key, val, supplier);
+    }
+    
+    private static IllegalArgumentException duplicate(Object key, Object previous, Object current) {
+        return new IllegalArgumentException("Duplicate values (" + previous + "," + current + ") for key: " + key);
+    }
+    
+    private static class UCollector<R,K,V> implements Collector<R,IntMap<V>,IntMap<V>> {
+        
+        private final ToIntFunction<? super R> key;
+        private final Function<? super R, ? extends V> val;
+        private final Supplier<IntMap<V>> supplier;
+
+        public UCollector(ToIntFunction<? super R> key, Function<? super R, ? extends V> val, Supplier<IntMap<V>> supplier) {
+            this.key = key;
+            this.val = val;
+            this.supplier = supplier;
+        }
+        
+        @Override
+        public Supplier<IntMap<V>> supplier() {
+            return supplier;
+        }
+
+        @Override
+        public BiConsumer<IntMap<V>, R> accumulator() {
+            return this::$accumulate;
+        }
+        
+        private void $accumulate(IntMap<V> map, R r) {
+            int ik = key.applyAsInt(r);
+            V iv = val.apply(r);
+            if(map.containsKey(ik)) {
+                throw duplicate(ik, map.get(ik), iv);
+            }
+            map.put(ik, iv);
+        }
+
+        @Override
+        public BinaryOperator<IntMap<V>> combiner() {
+            return this::$combine;
+        }
+        
+        private IntMap<V> $combine(IntMap<V> target, IntMap<V> source) {
+            for(IntMap.IntEntry<V> item : source.fastEntrySet()) {
+                int ik = item.getIntKey();
+                V iv = item.getValue();
+                if(target.containsKey(ik)) {
+                    throw duplicate(ik, target.get(ik), iv);
+                }
+            }
+            return target;
+        }
+
+        @Override
+        public Function<IntMap<V>,IntMap<V>> finisher() {
+            return m -> m;
+        }
+
+        @Override
+        public Set<Collector.Characteristics> characteristics() {
+            return EnumSet.of(Collector.Characteristics.IDENTITY_FINISH);
+        }
+
+    }
+    
+    private static class MCollector<R,V> implements Collector<R,IntMultiMap<V>,IntMultiMap<V>> {
+        
+        private final ToIntFunction<? super R> key;
+        private final Function<? super R, ? extends V> val;
+        private final Supplier<IntMultiMap<V>> supplier;
+
+        public MCollector(ToIntFunction<? super R> key, Function<? super R, ? extends V> val, Supplier<IntMultiMap<V>> supplier) {
+            this.key = key;
+            this.val = val;
+            this.supplier = supplier;
+        }
+        
+        @Override
+        public Supplier<IntMultiMap<V>> supplier() {
+            return supplier;
+        }
+
+        @Override
+        public BiConsumer<IntMultiMap<V>, R> accumulator() {
+            return (map, r) -> map.put(key.applyAsInt(r), val.apply(r));
+        }
+
+        @Override
+        public BinaryOperator<IntMultiMap<V>> combiner() {
+            return (a,b) -> { a.putAll(b); return a; };
+        }
+
+        @Override
+        public Function<IntMultiMap<V>, IntMultiMap<V>> finisher() {
+            return m -> m;
+        }
+
+        @Override
+        public Set<Collector.Characteristics> characteristics() {
+            return EnumSet.of(Collector.Characteristics.IDENTITY_FINISH);
+        }
+
+    }
+    
+}

+ 155 - 0
assira/src/main/java/net/ranides/assira/collection/maps/MapCollectors.java

@@ -0,0 +1,155 @@
+/*
+ * @author Ranides Atterwim <ranides@gmail.com>
+ * @copyright Ranides Atterwim
+ * @license WTFPL
+ * @url http://ranides.net/projects/assira
+ */
+
+package net.ranides.assira.collection.maps;
+
+import java.util.EnumSet;
+import java.util.Map;
+import java.util.Set;
+import java.util.function.BiConsumer;
+import java.util.function.BinaryOperator;
+import java.util.function.Function;
+import java.util.function.Supplier;
+import java.util.stream.Collector;
+
+/**
+ *
+ * @author Ranides Atterwim <ranides@gmail.com>
+ */
+public final class MapCollectors {
+    
+    private MapCollectors() {
+        /* utility class */
+    }
+
+    public static <R,K,V> Collector<R,?, Map<K,R>> unique(Function<? super R, ? extends K> key) {
+        return MapCollectors.unique(key, v -> v);
+    }
+    
+    public static <R,K,V> Collector<R,?, Map<K,V>> unique(Function<? super R, ? extends K> key, Function<R, V> val) {
+        return MapCollectors.unique(key, val, () -> new HashMap<>());
+    }
+    
+    public static <R,K,V> Collector<R,?, Map<K,V>> unique(Function<? super R, ? extends K> key, Function<? super R, ? extends V> val, Supplier<Map<K, V>> supplier) {
+        return new UCollector<>(key, val, supplier);
+    }
+    
+    public static <R,K,V> Collector<R,?, MultiMap<K,R>> multimap(Function<? super R, ? extends K> key) {
+        return MapCollectors.multimap(key, v -> v);
+    }
+    
+    public static <R,K,V> Collector<R,?, MultiMap<K,V>> multimap(Function<? super R, ? extends K> key, Function<R, V> val) {
+        return MapCollectors.multimap(key, val, () -> new HashMultiMap<>());
+    }
+    
+    public static <R,K,V> Collector<R,?, MultiMap<K,V>> multimap(Function<? super R, ? extends K> key, Function<? super R, ? extends V> val, Supplier<MultiMap<K, V>> supplier) {
+        return new MCollector<>(key, val, supplier);
+    }
+    
+    private static IllegalArgumentException duplicate(Object key, Object previous, Object current) {
+        return new IllegalArgumentException("Duplicate values (" + previous + "," + current + ") for key: " + key);
+    }
+    
+    private static class UCollector<R,K,V> implements Collector<R,Map<K,V>,Map<K,V>> {
+        
+        private final Function<? super R, ? extends K> key;
+        private final Function<? super R, ? extends V> val;
+        private final Supplier<Map<K, V>> supplier;
+
+        public UCollector(Function<? super R, ? extends K> key, Function<? super R, ? extends V> val, Supplier<Map<K, V>> supplier) {
+            this.key = key;
+            this.val = val;
+            this.supplier = supplier;
+        }
+        
+        @Override
+        public Supplier<Map<K, V>> supplier() {
+            return supplier;
+        }
+
+        @Override
+        public BiConsumer<Map<K, V>, R> accumulator() {
+            return this::$accumulate;
+        }
+        
+        private void $accumulate(Map<K, V> map, R r) {
+            K ik = key.apply(r);
+            V iv = val.apply(r);
+            if(map.containsKey(ik)) {
+                throw duplicate(ik, map.get(ik), iv);
+            }
+            map.put(ik, iv);
+        }
+
+        @Override
+        public BinaryOperator<Map<K, V>> combiner() {
+            return this::$combine;
+        }
+        
+        private Map<K, V> $combine(Map<K, V> target, Map<K, V> source) {
+            for(Map.Entry<K,V> item : source.entrySet()) {
+                K ik = item.getKey();
+                V iv = item.getValue();
+                if(target.containsKey(ik)) {
+                    throw duplicate(ik, target.get(ik), iv);
+                }
+            }
+            return target;
+        }
+
+        @Override
+        public Function<Map<K, V>, Map<K, V>> finisher() {
+            return m -> m;
+        }
+
+        @Override
+        public Set<Collector.Characteristics> characteristics() {
+            return EnumSet.of(Collector.Characteristics.IDENTITY_FINISH);
+        }
+
+    }
+    
+    private static class MCollector<R,K,V> implements Collector<R,MultiMap<K,V>,MultiMap<K,V>> {
+        
+        private final Function<? super R, ? extends K> key;
+        private final Function<? super R, ? extends V> val;
+        private final Supplier<MultiMap<K, V>> supplier;
+
+        public MCollector(Function<? super R, ? extends K> key, Function<? super R, ? extends V> val, Supplier<MultiMap<K, V>> supplier) {
+            this.key = key;
+            this.val = val;
+            this.supplier = supplier;
+        }
+        
+        @Override
+        public Supplier<MultiMap<K, V>> supplier() {
+            return supplier;
+        }
+
+        @Override
+        public BiConsumer<MultiMap<K, V>, R> accumulator() {
+            return (map, r) -> map.put(key.apply(r), val.apply(r));
+        }
+
+        @Override
+        public BinaryOperator<MultiMap<K, V>> combiner() {
+            return (a,b) -> { a.putAll(b); return a; };
+        }
+
+        @Override
+        public Function<MultiMap<K, V>, MultiMap<K, V>> finisher() {
+            return m -> m;
+        }
+
+        @Override
+        public Set<Collector.Characteristics> characteristics() {
+            return EnumSet.of(Collector.Characteristics.IDENTITY_FINISH);
+        }
+
+    }
+    
+}

+ 0 - 43
assira/src/main/java/net/ranides/assira/collection/maps/MultiMap.java

@@ -50,47 +50,4 @@ public interface MultiMap<K,V> extends Map<K,V> {
         return new HashSet<>(keySet());
     }
     
-    static <R,K,V> Collector<R,?, MultiMap<K,R>> collector(Function<? super R, ? extends K> key) {
-        return collector(key, v -> v);
-    }
-    
-    static <R,K,V> Collector<R,?, MultiMap<K,V>> collector(Function<? super R, ? extends K> key, Function<R, V> val) {
-        return collector(key, val, () -> new HashMultiMap<>());
-    }
-    
-    static <R,K,V> Collector<R,?, MultiMap<K,V>> collector(Function<? super R, ? extends K> key, Function<? super R, ? extends V> val, Supplier<MultiMap<K, V>> supplier) {
-        
-        class MMCollector implements Collector<R,MultiMap<K,V>,MultiMap<K,V>> {
-
-            @Override
-            public Supplier<MultiMap<K, V>> supplier() {
-                return supplier;
-            }
-
-            @Override
-            public BiConsumer<MultiMap<K, V>, R> accumulator() {
-                return (map, r) -> map.put(key.apply(r), val.apply(r));
-            }
-
-            @Override
-            public BinaryOperator<MultiMap<K, V>> combiner() {
-                return (a,b) -> { a.putAll(b); return a; };
-            }
-
-            @Override
-            public Function<MultiMap<K, V>, MultiMap<K, V>> finisher() {
-                return m -> m;
-            }
-
-            @Override
-            public Set<Collector.Characteristics> characteristics() {
-                return EnumSet.of(Collector.Characteristics.IDENTITY_FINISH);
-            }
-
-        }
-        
-        return new MMCollector();
-    }
-        
-    
 }

+ 37 - 0
assira/src/main/java/net/ranides/assira/generic/EnumUtils.java

@@ -0,0 +1,37 @@
+/*
+ *  @author Ranides Atterwim <ranides@gmail.com>
+ *  @copyright Ranides Atterwim
+ *  @license WTFPL
+ *  @url http://ranides.net/projects/assira
+ */
+
+package net.ranides.assira.generic;
+
+import java.util.Arrays;
+import java.util.Map;
+import java.util.function.Function;
+import java.util.function.ToIntFunction;
+import net.ranides.assira.collection.maps.IntMap;
+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ć
+    //      oraz MapCollectors
+    //      oraz IntMapCollectors
+
+    private EnumUtils() {
+        // utility class
+    }
+
+    public static <K,E extends Enum<E>> Map<K, E> map(Class<E> eenum, Function<E,? extends K> function) {
+        return Arrays.stream(eenum.getEnumConstants()).collect(MapCollectors.unique(function));
+    }
+    
+    public static <E extends Enum<E>> IntMap<E> intmap(Class<E> eenum, ToIntFunction<E> function) {
+        return Arrays.stream(eenum.getEnumConstants()).collect(IntMapCollectors.unique(function));
+    }
+
+}