ソースを参照

new: CQuery#prefetch, infinite, finite
change: CQuery#onEach, each

Mariusz Czarnowski 4 年 前
コミット
43d8eae4ef

+ 1 - 1
assira.core/src/main/java/net/ranides/assira/collection/iterators/IterableUtils.java

@@ -104,7 +104,7 @@ public final class IterableUtils {
     }
 
     public static <T> Iterable<T> iterable(CheckedSupplier<Optional<T>, ?> generator) {
-        return () -> IteratorUtils.iterator(generator);
+        return () -> IteratorUtils.finite(generator);
     }
 
 }

+ 22 - 3
assira.core/src/main/java/net/ranides/assira/collection/iterators/IteratorUtils.java

@@ -212,7 +212,27 @@ public final class IteratorUtils {
         }
     }
 
-    public static <T> Iterator<T> iterator(CheckedSupplier<Optional<T>, ?> generator) {
+    public static <T> Iterator<T> infinite(CheckedSupplier<T, ?> generator) {
+        return new Iterator<T>() {
+            @Override
+            public boolean hasNext() {
+                return true;
+            }
+
+            @Override
+            public T next() {
+                try {
+                    return generator.get();
+                } catch (RuntimeException cause) {
+                    throw cause;
+                } catch (Exception cause) {
+                    throw new RuntimeException(cause);
+                }
+            }
+        };
+    }
+
+    public static <T> Iterator<T> finite(CheckedSupplier<Optional<T>, ?> generator) {
 	    return new Iterator<T>() {
 
 	        private Optional<T> last = Optional.empty();
@@ -223,8 +243,7 @@ public final class IteratorUtils {
                     return (last = generator.get()).isPresent();
                 } catch (RuntimeException cause) {
                     throw cause;
-                }
-                catch (Exception cause) {
+                } catch (Exception cause) {
                     throw new RuntimeException(cause);
                 }
             }

+ 19 - 4
assira.core/src/main/java/net/ranides/assira/collection/query/CQuery.java

@@ -15,6 +15,7 @@ import java.util.stream.Stream;
 import java.util.stream.StreamSupport;
 
 import net.ranides.assira.collection.HashFunction;
+import net.ranides.assira.collection.iterators.IteratorUtils;
 import net.ranides.assira.functional.Consumers.EachConsumer;
 import net.ranides.assira.functional.Functions.EachFunction;
 import net.ranides.assira.functional.Predicates.EachPredicate;
@@ -65,6 +66,8 @@ public interface CQuery<T> extends Iterable<T> {
 
     CQuery<T> fetch();
 
+    CQuery<T> prefetch();
+
     CQuery<T> cache(Path filename) throws IOException;
 
     CQuery<T> append(CQuery<T> next);
@@ -95,7 +98,7 @@ public interface CQuery<T> extends Iterable<T> {
 
     <R> CQuery<R> map(Function<? super T,? extends R> f);
 
-    <R> CQuery<R> mapOptional(Function<? super T, Optional<? extends R>> f);
+    <R> CQuery<R> mapOptional(Function<? super T, Optional<R>> f);
 
     <R> CQuery<R> mapEach(EachFunction<? super T,? extends R> f);
     
@@ -147,11 +150,15 @@ public interface CQuery<T> extends Iterable<T> {
 
     CQuery<T> reverse();
 
-    CQuery<T> each(Consumer<? super T> consumer);
+    void each(Consumer<? super T> consumer);
+
+    void each(EachConsumer<? super T> consumer);
 
-    CQuery<T> each(EachConsumer<? super T> consumer);
+    CQuery<T> onEach(Consumer<? super T> consumer);
 
-    CQuery<T> into(Collection<? super T> collection);
+    CQuery<T> onEach(EachConsumer<? super T> consumer);
+
+    void into(Collection<? super T> collection);
     
     boolean matchAny(Predicate<? super T> predicate);
     
@@ -242,6 +249,14 @@ public interface CQuery<T> extends Iterable<T> {
             return query(() -> source.apply(param));
         }
 
+        public final <T extends F> CQuery<T> infinite(Supplier<T> source) {
+            return iterable(() -> IteratorUtils.infinite(source::get));
+        }
+
+        public final <T extends F> CQuery<T> finite(Supplier<Optional<T>> source) {
+            return iterable(() -> IteratorUtils.finite(source::get));
+        }
+
     }
 
     /**

+ 56 - 18
assira.core/src/main/java/net/ranides/assira/collection/query/CQueryAbstract.java

@@ -6,16 +6,6 @@
  */
 package net.ranides.assira.collection.query;
 
-import java.io.IOException;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.util.*;
-import java.util.function.*;
-import java.util.stream.Collector;
-import java.util.stream.Collectors;
-import java.util.stream.Stream;
-import java.util.stream.StreamSupport;
-
 import net.ranides.assira.collection.HashFunction;
 import net.ranides.assira.collection.arrays.ArrayUtils;
 import net.ranides.assira.collection.iterators.IteratorUtils;
@@ -25,13 +15,25 @@ import net.ranides.assira.collection.sets.CustomSet;
 import net.ranides.assira.collection.sets.HashSet;
 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;
 import net.ranides.assira.functional.Predicates.EachPredicate;
 import net.ranides.assira.functional.special.Fold;
 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.*;
+import net.ranides.assira.reflection.IClass;
+
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.*;
+import java.util.function.*;
+import java.util.stream.Collector;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+import java.util.stream.StreamSupport;
 
 /**
  *
@@ -74,6 +76,11 @@ public abstract class CQueryAbstract<T> implements CQuery<T> {
         return CQuery.from().collection(list());
     }
 
+    @Override
+    public CQuery<T> prefetch() {
+        return new CQPrefetch<>(this);
+    }
+
     @Override
     public CQuery<T> cache(Path filename) throws IOException {
         List<T> data;
@@ -147,7 +154,7 @@ public abstract class CQueryAbstract<T> implements CQuery<T> {
     }
 
     @Override
-    public <R> CQuery<R> mapOptional(Function<? super T, Optional<? extends R>> f) {
+    public <R> CQuery<R> mapOptional(Function<? super T, Optional<R>> f) {
         return map(f).filter(Optional::isPresent).map(Optional::get);
     }
 
@@ -293,24 +300,31 @@ public abstract class CQueryAbstract<T> implements CQuery<T> {
     }
 
     @Override
-    public final CQuery<T> each(Consumer<? super T> consumer) {
+    public final void each(Consumer<? super T> consumer) {
         stream().forEach(consumer);
-        return this;
     }
 
     @Override
-    public final CQuery<T> each(EachConsumer<? super T> consumer) {
+    public final void each(EachConsumer<? super T> consumer) {
         int index = 0;
         for (T t : this) {
             consumer.apply(index++, t);
         }
-        return this;
     }
 
     @Override
-    public CQuery<T> into(Collection<? super T> collection) {
+    public final CQuery<T> onEach(Consumer<? super T> consumer) {
+        return map(FunctionUtils.asFunction(consumer));
+    }
+
+    @Override
+    public final CQuery<T> onEach(EachConsumer<? super T> consumer) {
+        return mapEach(FunctionUtils.asEachFunction(consumer));
+    }
+
+    @Override
+    public void into(Collection<? super T> collection) {
         stream().forEach(collection::add);
-        return this;
     }
 
     @Override
@@ -606,6 +620,30 @@ public abstract class CQueryAbstract<T> implements CQuery<T> {
         }
     }
 
+    protected static class CQPrefetch<T> extends CQueryAbstract<T> {
+
+        private final Supplier<CQuery<T>> source;
+
+        public CQPrefetch(CQuery<T> source) {
+            this.source = LazyReference.shared(() -> source.fetch());
+        }
+
+        @Override
+        public Stream<T> stream() {
+            return source.get().stream();
+        }
+
+        @Override
+        public Iterator<T> iterator() {
+            return source.get().iterator();
+        }
+
+        @Override
+        public int size() {
+            return source.get().size();
+        }
+    }
+
     protected static class CQSingle<T> extends CQueryAbstract<T> {
 
         private final T value;

+ 9 - 1
assira.core/src/main/java/net/ranides/assira/functional/FunctionUtils.java

@@ -1,6 +1,7 @@
 package net.ranides.assira.functional;
 
 import lombok.experimental.UtilityClass;
+import net.ranides.assira.functional.Consumers.EachConsumer;
 import net.ranides.assira.functional.Functions.*;
 import net.ranides.assira.functional.special.AnyFunction;
 
@@ -62,7 +63,7 @@ public class FunctionUtils {
         return arg -> function.apply(arg).orElse(other);
     }
 
-    public static <T> Function1<T, T> asFunction(Consumer<T> consumer) {
+    public static <T> Function1<? super T, T> asFunction(Consumer<? super T> consumer) {
         return input -> {
             consumer.accept(input);
             return input;
@@ -73,6 +74,13 @@ public class FunctionUtils {
         return input -> supplier.get();
     }
 
+    public static <T> EachFunction<? super T, T> asEachFunction(EachConsumer<? super T> consumer) {
+        return (index, value) -> {
+            consumer.apply(index, value);
+            return value;
+        };
+    }
+
     public static <R, A1, V1> Function1<V1, R> compose(Function<A1, R> function, Function<V1, A1> arg1) {
         return input -> function.apply(arg1.apply(input));
     }

+ 1 - 1
assira.core/src/test/java/net/ranides/assira/collection/iterators/IteratorUtilsTest.java

@@ -362,7 +362,7 @@ public class IteratorUtilsTest {
     @Test
     public void testIterator() {
         BufferedReader reader = new BufferedReader(new StringReader("hello\nworld\nhere\n"));
-        Iterator<String> iterator = IteratorUtils.iterator(() -> Optional.ofNullable(reader.readLine()));
+        Iterator<String> iterator = IteratorUtils.finite(() -> Optional.ofNullable(reader.readLine()));
 
         ArrayList<String> lines = IteratorUtils.collect(iterator, new ArrayList<>());
         assertEquals(Arrays.asList("hello", "world", "here"), lines);