Ranides Atterwim 4 năm trước cách đây
mục cha
commit
45495a5173

+ 1 - 1
assira.commons/src/main/java/net/ranides/assira/collection/maps/EnumCrossMap.java

@@ -137,7 +137,7 @@ public class EnumCrossMap<K1 extends Enum<K1>, K2 extends Enum<K2>, V> implement
     }
 
     @Override
-    public Map<K1, K2> reduceValues() {
+    public MultiMap<K1, K2> reduceValues() {
         OpenMultiMap<K1, K2> result = new OpenMultiMap<>();
         forEach((key1, key2, value) -> result.put(key1, key2));
         return result;

+ 1 - 1
assira.core/src/main/java/net/ranides/assira/collection/maps/CrossMap.java

@@ -52,7 +52,7 @@ public interface CrossMap<K1, K2, V> {
 
     MultiMap<K1, V> reduceSecond();
 
-    Map<K1, K2> reduceValues();
+    MultiMap<K1, K2> reduceValues();
 
     Set<Pair<K1, K2>> keySet();
 

+ 1 - 1
assira.core/src/main/java/net/ranides/assira/collection/maps/OpenCrossMap.java

@@ -83,7 +83,7 @@ public class OpenCrossMap<K1, K2, V> implements CrossMap<K1, K2, V>, Serializabl
     }
 
     @Override
-    public Map<K1, K2> reduceValues() {
+    public MultiMap<K1, K2> reduceValues() {
         OpenMultiMap<K1, K2> result = new OpenMultiMap<>();
         map.forEach((key, value) -> result.put(key.getFirst(), key.getSecond()));
         return result;

+ 3 - 1
assira.core/src/main/java/net/ranides/assira/collection/query/CQuery.java

@@ -178,7 +178,9 @@ public interface CQuery<T> extends Iterable<T> {
     
     boolean matchNone(Predicate<? super T> predicate);
 
-    <R> R apply(Function<CQuery<? extends T>, R> function);
+    <R> R apply(Function<CQuery<T>, R> function);
+
+    boolean apply(Predicate<CQuery<T>> function);
 
     class WrapBuilder<F> {
 

+ 7 - 3
assira.core/src/main/java/net/ranides/assira/collection/query/CQueryAbstract.java

@@ -13,7 +13,6 @@ import net.ranides.assira.collection.lists.ListUtils;
 import net.ranides.assira.collection.lists.ReversedList;
 import net.ranides.assira.collection.sets.CustomSet;
 import net.ranides.assira.collection.sets.OpenSet;
-//import net.ranides.assira.collection.sets.RBTreeSet;
 import net.ranides.assira.functional.Consumers.EachConsumer;
 import net.ranides.assira.functional.FunctionUtils;
 import net.ranides.assira.functional.Functions.EachFunction;
@@ -23,7 +22,7 @@ import net.ranides.assira.generic.CompareUtils;
 import net.ranides.assira.generic.LazyReference;
 import net.ranides.assira.generic.SerializationUtils;
 import net.ranides.assira.generic.TypeToken;
-import net.ranides.assira.reflection.IClass;
+import net.ranides.assira.reflection.*;
 
 import java.io.IOException;
 import java.nio.file.Files;
@@ -377,10 +376,15 @@ public abstract class CQueryAbstract<T> implements CQuery<T> {
     }
 
     @Override
-    public <R> R apply(Function<CQuery<? extends T>, R> function) {
+    public <R> R apply(Function<CQuery<T>, R> function) {
         return function.apply(this);
     }
 
+    @Override
+    public boolean apply(Predicate<CQuery<T>> function) {
+        return function.test(this);
+    }
+
     protected static class CQCollection<T> extends CQueryAbstract<T> {
         
         private final Supplier<Collection<T>> source;

+ 182 - 0
assira.core/src/main/java/net/ranides/assira/collection/query/CQueryFunction.java

@@ -0,0 +1,182 @@
+/*
+ * @author Ranides Atterwim {@literal <ranides@gmail.com>}
+ * @copyright Ranides Atterwim
+ * @license WTFPL
+ * @url http://ranides.net/projects/assira
+ */
+package net.ranides.assira.collection.query;
+
+import net.ranides.assira.collection.HashFunction;
+import net.ranides.assira.functional.Consumers.EachConsumer;
+import net.ranides.assira.functional.Functions.EachFunction;
+import net.ranides.assira.functional.Predicates.EachPredicate;
+import net.ranides.assira.functional.checked.CheckedFunction;
+import net.ranides.assira.reflection.*;
+
+import java.nio.file.Path;
+import java.util.Comparator;
+import java.util.Optional;
+import java.util.function.Consumer;
+import java.util.function.Function;
+import java.util.function.Predicate;
+
+/**
+ * @param <S>
+ * @param <T>
+ * @author Ranides Atterwim {@literal <ranides@gmail.com>}
+ */
+public interface CQueryFunction<S, T> extends Function<CQuery<S>, CQuery<T>> {
+
+    static <R> CQueryFunction<R,R> prepare() {
+        return s -> s;
+    }
+
+    default <Q> CQueryFunction<S,Q> andQuery(Function<? super CQuery<T>, ? extends CQuery<Q>> after) {
+        return s -> after.apply(apply(s));
+    }
+
+    default CQueryFunction<S, T> fetch() {
+        return andQuery(CQuery::fetch);
+    }
+
+    default CQueryFunction<S, T> prefetch() {
+        return andQuery(CQuery::prefetch);
+    }
+
+    default CQueryFunction<S, T> cache(Path filename) {
+        return andQuery(CheckedFunction.sneaky(s -> s.cache(filename)));
+    }
+
+    default CQueryFunction<S, T> append(CQuery<T> next) {
+        return andQuery(s -> s.append(next));
+    }
+
+    default CQueryFunction<S, T> limit(Predicate<? super T> p) {
+        return andQuery(s -> s.limit(p));
+    }
+
+    default CQueryFunction<S, T> limit(int n) {
+        return andQuery(s -> s.limit(n));
+    }
+
+    default CQueryFunction<S, T> skip(int n) {
+        return andQuery(s -> s.skip(n));
+    }
+
+    default CQueryFunction<S, T> slice(int begin, int end) {
+        return andQuery(s -> s.slice(begin, end));
+    }
+
+    default CQueryFunction<S, T> filter(Predicate<? super T> p) {
+        return andQuery(s -> s.filter(p));
+    }
+
+    default CQueryFunction<S, T> filterEach(EachPredicate<? super T> p) {
+        return andQuery(s -> s.filterEach(p));
+    }
+
+    default <Q> CQueryFunction<S, Q> filter(Class<Q> p) {
+        return andQuery(s -> s.filter(p));
+    }
+
+    default <Q> CQueryFunction<S, Q> filter(IClass<Q> p) {
+        return andQuery(s -> s.filter(p));
+    }
+
+    default CQueryFunction<S, T> discard(Predicate<? super T> p) {
+        return andQuery(s -> s.discard(p));
+    }
+
+    default CQueryFunction<S, T> discardEach(EachPredicate<? super T> p) {
+        return andQuery(s -> s.discardEach(p));
+    }
+
+    default CQueryFunction<S, T> discard(Class<?> p) {
+        return andQuery(s -> s.discard(p));
+    }
+
+    default CQueryFunction<S, T> discard(IClass<?> p) {
+        return andQuery(s -> s.discard(p));
+    }
+
+    default <R> CQueryFunction<S,R> map(Function<? super T, ? extends R> f) {
+        return andQuery(s -> s.map(f));
+    }
+
+    default <R> CQueryFunction<S,R> mapOptional(Function<? super T, Optional<R>> f) {
+        return andQuery(s -> s.mapOptional(f));
+    }
+
+    default <R> CQueryFunction<S,R> mapEach(EachFunction<? super T, ? extends R> f) {
+        return andQuery(s -> s.mapEach(f));
+    }
+
+    default <R> CQueryFunction<S,R> unfold(Function<? super T, CQuery<R>> f) {
+        return andQuery(s -> s.unfold(f));
+    }
+
+    default <R> CQueryFunction<S,R> flat(Function<? super T, Iterable<R>> f) {
+        return andQuery(s -> s.flat(f));
+    }
+
+    default <R> CQueryFunction<S,R> split(Function<? super T, R[]> f) {
+        return andQuery(s -> s.split(f));
+    }
+
+    default CQueryFunction<S, T> mapIf(Predicate<? super T> p, Function<? super T, ? extends T> f) {
+        return andQuery(s -> s.mapIf(p,f));
+    }
+
+    default CQueryFunction<S, T> mapEachIf(EachPredicate<? super T> p, EachFunction<? super T, ? extends T> f) {
+        return andQuery(s -> s.mapEachIf(p,f));
+    }
+
+    default CQueryFunction<S, T> mapOptionalIf(Predicate<? super T> p, Function<? super T, Optional<? extends T>> f) {
+        return andQuery(s -> s.mapOptionalIf(p,f));
+    }
+
+    default CQueryFunction<S, T> unfoldIf(Predicate<? super T> p, Function<? super T, CQuery<T>> f) {
+        return andQuery(s -> s.unfoldIf(p, f));
+    }
+
+    default CQueryFunction<S, T> flatIf(Predicate<? super T> p, Function<? super T, Iterable<T>> f) {
+        return andQuery(s -> s.flatIf(p, f));
+    }
+
+    default CQueryFunction<S, T> splitIf(Predicate<? super T> p, Function<? super T, T[]> f) {
+        return andQuery(s -> s.splitIf(p,f));
+    }
+
+    default CQueryFunction<S, T> distinct() {
+        return andQuery(s -> s.distinct());
+    }
+
+    default CQueryFunction<S, T> distinct(HashFunction<T> eq) {
+        return andQuery(s -> s.distinct(eq));
+    }
+
+    default CQueryFunction<S, T> distinct(Comparator<? super T> cmp) {
+        return andQuery(s -> s.distinct(cmp));
+    }
+
+    default CQueryFunction<S, T> sort() {
+        return andQuery(s -> s.sort());
+    }
+
+    default CQueryFunction<S, T> sort(Comparator<? super T> cmp) {
+        return andQuery(s -> s.sort(cmp));
+    }
+
+    default CQueryFunction<S, T> reverse() {
+        return andQuery(s -> s.reverse());
+    }
+
+    default CQueryFunction<S, T> onEach(Consumer<? super T> consumer) {
+        return andQuery(s -> s.onEach(consumer));
+    }
+
+    default CQueryFunction<S, T> onEach(EachConsumer<? super T> consumer) {
+        return andQuery(s -> s.onEach(consumer));
+    }
+
+}

+ 54 - 0
assira.core/src/test/java/net/ranides/assira/collection/query/CQueryFunctionTest.java

@@ -0,0 +1,54 @@
+package net.ranides.assira.collection.query;
+
+import lombok.Data;
+import lombok.RequiredArgsConstructor;
+import org.junit.Test;
+
+import net.ranides.assira.collection.IntComparator;
+
+import java.util.Arrays;
+import java.util.function.Function;
+
+import static org.junit.Assert.assertEquals;
+
+public class CQueryFunctionTest {
+
+    @Test
+    public void simple() {
+        CQueryFunction<String, Integer> filter = CQueryFunction.<String>prepare()
+            .filter(s -> s.matches("[0-9,; ]+"))
+            .split(s -> s.split("[; ,]+"))
+            .map(Integer::valueOf)
+            .sort(IntComparator.DESC);
+
+        CQuery<String> input = CQuery.from().values("1,2,8", "o,t,h,er", "6 9 4", "q", "7;3");
+
+        assertEquals(Arrays.asList(9,8,7,6,4,3,2,1), input.apply(filter).list() );
+    }
+
+    private interface Text extends CharSequence {
+
+    }
+
+    @RequiredArgsConstructor
+    private static class TextValue implements Text {
+
+        private final CharSequence text;
+
+        @Override
+        public int length() {
+            return text.length();
+        }
+
+        @Override
+        public char charAt(int index) {
+            return text.charAt(index);
+        }
+
+        @Override
+        public TextValue subSequence(int start, int end) {
+            return new TextValue(text.subSequence(start, end));
+        }
+    }
+
+}