ソースを参照

new: CollectionQuery! :)

Ranides Atterwim 10 年 前
コミット
5d1df166ff

+ 2 - 0
assira/pom.xml

@@ -33,6 +33,8 @@
                                 <include>net/ranides/assira/awt/ImageLoader*</include>
                                 <include>net/ranides/assira/awt/AWTInvoker*</include>
                                 
+                                <include>net/ranides/assira/collection/ACollectionQuery*</include>
+                                <include>net/ranides/assira/collection/CollectionQuery*</include>
                                 <include>net/ranides/assira/collection/arrays/NativeArrayUtils</include>
                                 <include>net/ranides/assira/collection/arrays/ArrayUtils</include>
                                 <include>net/ranides/assira/collection/iterators/ForwardIterator*</include>

+ 415 - 0
assira/src/main/java/net/ranides/assira/collection/ACollectionQuery.java

@@ -0,0 +1,415 @@
+/*
+ * @author Ranides Atterwim <ranides@gmail.com>
+ * @copyright Ranides Atterwim
+ * @license WTFPL
+ * @url http://ranides.net/projects/assira
+ */
+package net.ranides.assira.collection;
+
+import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Comparator;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.NoSuchElementException;
+import java.util.Set;
+import java.util.Spliterator;
+import java.util.function.BinaryOperator;
+import java.util.function.Consumer;
+import java.util.function.Function;
+import java.util.function.IntFunction;
+import java.util.function.IntSupplier;
+import java.util.function.Predicate;
+import java.util.function.Supplier;
+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.arrays.ArraySort;
+import net.ranides.assira.collection.arrays.ArrayUtils;
+import net.ranides.assira.collection.iterators.IteratorUtils;
+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.Fold;
+
+/**
+ *
+ * @author Ranides Atterwim <ranides@gmail.com>
+ */
+abstract class ACollectionQuery<T> implements CollectionQuery<T> {
+    
+    @Override
+    public final <A, R> R collect(Collector<T, A, R> collector) {
+        return stream().collect(collector);
+    }
+
+    @Override
+    public final Object[] array() {
+        return stream().toArray();
+    }
+
+    @Override
+    public final <A> A[] array(IntFunction<A[]> generator) {
+        return stream().toArray(generator);
+    }
+
+    @Override
+    public final List<T> list() {
+        return stream().collect(Collectors.toList());
+    }
+
+    @Override
+    public final Set<T> set() {
+        return stream().collect(Collectors.toSet());
+    }
+    
+    @Override
+    public CollectionQuery<T> limit(int n) {
+        return new CQBounded<>(this, 0, n);
+    }
+
+    @Override
+    public CollectionQuery<T> skip(int n) {
+        return new CQBounded<>(this, n, Integer.MAX_VALUE);
+    }
+    
+    @Override
+    public final <K> Map<K, T> group(Function<T, K> key) {
+        return stream().collect(Collectors.toMap(key, v -> v));
+    }
+
+    @Override
+    public final <K, V> Map<K, V> group(Function<T, K> key, Function<T, V> value) {
+        return stream().collect(Collectors.toMap(key, value));
+    }
+
+    @Override
+    public final boolean isEmpty() {
+        return !iterator().hasNext();
+    }
+
+    @Override
+    public final CollectionQuery<T> filter(Predicate<T> p) {
+        return new CQIterable<>(() -> IteratorUtils.filter(iterator(), p));
+    }
+
+    @Override
+    public final <R> CollectionQuery<R> map(Function<T, R> f) {
+        return new CQIterable<>(() -> IteratorUtils.map(iterator(), f), this::size);
+    }
+
+    @Override
+    public final <R> CollectionQuery<R> unfold(Function<T, CollectionQuery<R>> f) {
+        return new CQIterable<>(() -> IteratorUtils.flat(IteratorUtils.map(iterator(), (v) -> f.apply(v).iterator())));
+    }
+
+    @Override
+    public final T fold(T identity, BinaryOperator<T> accumulator) {
+        Iterator<T> i = iterator();
+        return i.hasNext() ? Fold.apply(i, accumulator::apply) : identity;
+    }
+
+    @Override
+    public final T fold(BinaryOperator<T> accumulator) {
+        return fold(null, accumulator);
+    }
+
+    @Override
+    public final T min(Comparator<T> cmp) {
+        return fold((a, b) -> cmp.compare(a, b) < 0 ? a : b);
+    }
+
+    @Override
+    public final T max(Comparator<T> cmp) {
+        return fold((a, b) -> cmp.compare(a, b) > 0 ? a : b);
+    }
+
+    @Override
+    public final T first() {
+        return IteratorUtils.first(iterator());
+    }
+
+    @Override
+    public final T last() {
+        return IteratorUtils.last(iterator());
+    }
+
+    @Override
+    public final CollectionQuery<T> distinct() {
+        return new CQLazy<>(() -> new HashSet<>(iterator()));
+    }
+
+    @Override
+    public final CollectionQuery<T> distinct(HashFunction<T> eq) {
+        return new CQLazy<>(() -> new CustomSet<>(iterator(), eq));
+    }
+
+    @Override
+    public final CollectionQuery<T> distinct(Comparator<T> cmp) {
+        return new CQLazy<>(() -> new RBTreeSet<>(iterator(), cmp));
+    }
+
+    @Override
+    public final CollectionQuery<T> sort() {
+        return new CQLazy<>(() -> {
+            List<T> list = list();
+            ArraySort.mergeSort(list);
+            return list;
+        });
+    }
+
+    @Override
+    public final CollectionQuery<T> sort(Comparator<T> cmp) {
+        return new CQLazy<>(() -> {
+            List<T> list = list();
+            ArraySort.mergeSort(list, cmp);
+            return list;
+        });
+    }
+
+    @Override
+    public final void each(Consumer<T> consumer) {
+        stream().forEach(consumer);
+    }
+
+    @Override
+    public final boolean matchAny(Predicate<T> predicate) {
+        return stream().anyMatch(predicate);
+    }
+
+    @Override
+    public final boolean matchAll(Predicate<T> predicate) {
+        return stream().allMatch(predicate);
+    }
+
+    @Override
+    public final boolean matchNone(Predicate<T> predicate) {
+        return stream().noneMatch(predicate);
+    }
+
+    protected static final class CQCollection<T> extends ACollectionQuery<T> {
+        
+        private final Collection<T> source;
+        
+        
+        public CQCollection(Collection<T> source) {
+            this.source = source;
+        }
+
+        @Override
+        public Iterator<T> iterator() {
+            return source.iterator();
+        }
+
+        @Override
+        public Spliterator<T> spliterator() {
+            return source.spliterator();
+        }
+
+        @Override
+        public Stream<T> stream() {
+            return source.stream();
+        }
+
+        @Override
+        public int size() {
+            return source.size();
+        }
+        
+    }
+
+    protected static final class CQArray<T> extends ACollectionQuery<T> {
+        
+        private final T[] source;
+        private final int offset;
+        private final int limit;
+        
+        public CQArray(T[] source) {
+            this(source, 0, source.length);
+        }
+        
+        @SuppressWarnings("PMD.ArrayIsStoredDirectly")    
+        @SuppressFBWarnings("EI_EXPOSE_REP2")
+        public CQArray(T[] source, int offset, int limit) {
+            this.source = source;
+            this.offset = offset;
+            this.limit = Math.min(source.length, limit);
+        }
+
+        @Override
+        public Iterator<T> iterator() {
+            return ArrayUtils.iterator(source, offset, offset+limit);
+        }
+
+        @Override
+        public Spliterator<T> spliterator() {
+            return Arrays.spliterator(source, offset, offset+limit);
+        }
+
+        @Override
+        public Stream<T> stream() {
+            return Arrays.stream(source, offset, offset+limit);
+        }
+
+        @Override
+        public int size() {
+            return limit;
+        }
+        
+        @Override
+        public CollectionQuery<T> limit(int n) {
+            return new CQArray<>(source, offset, Math.min(limit, n));
+        }
+
+        @Override
+        public CollectionQuery<T> skip(int n) {
+            return new CQArray<>(source, offset+n, limit);
+        }
+        
+    }
+    
+    protected static final class CQIterable<T> extends ACollectionQuery<T> {
+        
+        private final Iterable<T> source;
+        
+        private final IntSupplier size;
+        
+        public CQIterable(Iterable<T> source) {
+            this.source = source;
+            this.size = () -> IteratorUtils.size(source.iterator());
+        }
+        
+        public CQIterable(Iterable<T> source, IntSupplier size) {
+            this.source = source;
+            this.size = size;
+        }
+
+        @Override
+        public Iterator<T> iterator() {
+            return source.iterator();
+        }
+
+        @Override
+        public Spliterator<T> spliterator() {
+            return source.spliterator();
+        }
+
+        @Override
+        public Stream<T> stream() {
+            return StreamSupport.stream(spliterator(), false);
+        }
+
+        @Override
+        public int size() {
+            return size.getAsInt();
+        }
+        
+    }
+    
+    protected static final class CQLazy<T> extends ACollectionQuery<T> {
+        
+        private final Supplier<Collection<T>> source;
+
+        public CQLazy(Supplier<Collection<T>> source) {
+            this.source = source;
+        }
+
+        @Override
+        public Iterator<T> iterator() {
+            return source.get().iterator();
+        }
+
+        @Override
+        public Spliterator<T> spliterator() {
+            return source.get().spliterator();
+        }
+
+        @Override
+        public Stream<T> stream() {
+            return source.get().stream();
+        }
+
+        @Override
+        public int size() {
+            return source.get().size();
+        }
+       
+    }
+    
+    protected static final class CQBounded<T> extends ACollectionQuery<T> {
+        
+        private final CollectionQuery<T> stream;
+        private final int begin;
+        private final int size;
+
+        public CQBounded(CollectionQuery<T> stream, int begin, int size) {
+            this.stream = stream;
+            this.begin = begin;
+            this.size = size;
+        }
+        
+        @Override
+        public CollectionQuery<T> limit(int n) {
+            return new CQBounded<>(stream, begin, Math.min(n, size));
+        }
+
+        @Override
+        public CollectionQuery<T> skip(int n) {
+            return new CQBounded<>(stream, begin+n, size);
+        }
+
+        @Override
+        public Iterator<T> iterator() {
+            Iterator<T> i = stream.iterator();
+            IteratorUtils.next(i, begin);
+            return new BIterator<>(i, size);
+        }
+
+        @Override
+        public Spliterator<T> spliterator() {
+            return stream().spliterator();
+        }
+
+        @Override
+        public Stream<T> stream() {
+            return stream.stream().skip(begin).limit(size);
+        }
+
+        @Override
+        public int size() {
+            return Math.min(stream.size(), size);
+        }
+        
+    }
+    
+    private static final class BIterator<T> implements Iterator<T> {
+        
+        private final Iterator<T> src;
+        private final int limit;
+        private int count;
+
+        public BIterator(Iterator<T> src, int limit) {
+            this.src = src;
+            this.limit = limit;
+        }
+
+        @Override
+        public boolean hasNext() {
+            return count<limit && src.hasNext();
+        }
+
+        @Override
+        public T next() {
+            if(count>=limit) {
+                throw new NoSuchElementException();
+            }
+            count++;
+            return src.next();
+        }
+        
+    }
+    
+}

+ 27 - 14
assira/src/main/java/net/ranides/assira/streams/IStream.java

@@ -5,15 +5,15 @@
  * @url http://ranides.net/projects/assira
  */
 
-package net.ranides.assira.streams;
+package net.ranides.assira.collection;
 
+import java.util.Collection;
 import java.util.Comparator;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
 import java.util.Spliterator;
-import java.util.function.BiPredicate;
 import java.util.function.BinaryOperator;
 import java.util.function.Consumer;
 import java.util.function.Function;
@@ -21,13 +21,26 @@ import java.util.function.IntFunction;
 import java.util.function.Predicate;
 import java.util.stream.Collector;
 import java.util.stream.Stream;
-import net.ranides.assira.collection.HashFunction;
 
 /**
  *
  * @author Ranides Atterwim <ranides@gmail.com>
  */
-public interface IStream<T> {
+@SuppressWarnings("PMD.TooManyDifferentMethods")
+public interface CollectionQuery<T> {
+    
+    static <T> CollectionQuery<T> of(Iterable<T> source) {
+        return new ACollectionQuery.CQIterable<>(source);
+    }
+    
+    static <T> CollectionQuery<T> of(Collection<T> source) {
+        return new ACollectionQuery.CQCollection<>(source);
+    }
+    
+    @SafeVarargs
+    static <T> CollectionQuery<T> of(T... source) {
+        return new ACollectionQuery.CQArray<>(source);
+    }
     
     Iterator<T> iterator();
     
@@ -53,15 +66,15 @@ public interface IStream<T> {
     
     boolean isEmpty();
     
-    IStream<T> limit(int n);
+    CollectionQuery<T> limit(int n);
     
-    IStream<T> skip(int n);
+    CollectionQuery<T> skip(int n);
 
-    IStream<T> filter(Predicate<T> p);
+    CollectionQuery<T> filter(Predicate<T> p);
     
-    <R> IStream<R> map(Function<T,R> f);
+    <R> CollectionQuery<R> map(Function<T,R> f);
     
-    <R> IStream<R> unfold(Function<T,IStream<R>> f);
+    <R> CollectionQuery<R> unfold(Function<T,CollectionQuery<R>> f);
     
     T fold(T identity, BinaryOperator<T> accumulator);
     
@@ -75,15 +88,15 @@ public interface IStream<T> {
     
     T last();
     
-    IStream<T> distinct();
+    CollectionQuery<T> distinct();
     
-    IStream<T> distinct(HashFunction<T> eq);
+    CollectionQuery<T> distinct(HashFunction<T> eq);
     
-    IStream<T> distinct(Comparator<T> cmp);
+    CollectionQuery<T> distinct(Comparator<T> cmp);
     
-    IStream<T> sort();
+    CollectionQuery<T> sort();
     
-    IStream<T> sort(Comparator<T> cmp);
+    CollectionQuery<T> sort(Comparator<T> cmp);
     
     void each(Consumer<T> consumer);
     

+ 0 - 397
assira/src/main/java/net/ranides/assira/streams/IStreams.java

@@ -1,397 +0,0 @@
-/*
- * @author Ranides Atterwim <ranides@gmail.com>
- * @copyright Ranides Atterwim
- * @license WTFPL
- * @url http://ranides.net/projects/assira
- */
-
-package net.ranides.assira.streams;
-
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Comparator;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.NoSuchElementException;
-import java.util.Set;
-import java.util.Spliterator;
-import java.util.function.BiPredicate;
-import java.util.function.BinaryOperator;
-import java.util.function.Consumer;
-import java.util.function.Function;
-import java.util.function.IntFunction;
-import java.util.function.IntSupplier;
-import java.util.function.Predicate;
-import java.util.function.Supplier;
-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.ACollection;
-import net.ranides.assira.collection.HashFunction;
-import net.ranides.assira.collection.arrays.ArraySort;
-import net.ranides.assira.collection.arrays.NativeArraySort;
-import net.ranides.assira.collection.iterators.IteratorUtils;
-import net.ranides.assira.collection.lists.JoinList;
-import net.ranides.assira.collection.lists.ListUtils;
-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.Fold;
-import net.ranides.assira.generic.LazyReference;
-
-/**
- *
- * @author Ranides Atterwim <ranides@gmail.com>
- */
-public final class IStreams {
-    
-    private IStreams() {
-        /* utility class */
-    }
-
-    public static <T> IStream<T> wrap(Iterable<T> source) {
-        return new SIterable<>(source);
-    }
-    
-    public static <T> IStream<T> wrap(Collection<T> source) {
-        return new SCollection<>(source);
-    }
-    
-    @SafeVarargs
-    public static <T> IStream<T> wrap(T... source) {
-        return new SCollection<>(Arrays.asList(source));
-    }
-    
-    private static abstract class SAbstract<T> implements IStream<T> {
-
-        @Override
-        public final <A, R> R collect(Collector<T, A, R> collector) {
-            return stream().collect(collector);
-        }
-
-        @Override
-        public final Object[] array() {
-            return stream().toArray();
-        }
-
-        @Override
-        public final <A> A[] array(IntFunction<A[]> generator) {
-            return stream().toArray(generator);
-        }
-
-        @Override
-        public final List<T> list() {
-            return stream().collect(Collectors.toList());
-        }
-
-        @Override
-        public final Set<T> set() {
-            return stream().collect(Collectors.toSet());
-        }
-
-        @Override
-        public final <K> Map<K,T> group(Function<T, K> key) {
-            return stream().collect(Collectors.toMap(key, v -> v));
-        }
-
-        @Override
-        public final <K, V> Map<K, V> group(Function<T, K> key, Function<T, V> value) {
-            return stream().collect(Collectors.toMap(key, value));
-        }
-
-        @Override
-        public final boolean isEmpty() {
-            return !iterator().hasNext();
-        }
-
-        @Override
-        public final IStream<T> filter(Predicate<T> p) {
-            return new SIterable<>(() -> IteratorUtils.filter(iterator(), p));
-        }
-
-        @Override
-        public final <R> IStream<R> map(Function<T, R> f) {
-            return new SIterable<>(() -> IteratorUtils.map(iterator(), f), this::size);
-        }
-
-        @Override
-        public final <R> IStream<R> unfold(Function<T, IStream<R>> f) {
-            return new SIterable<R>(() ->
-                IteratorUtils.flat(IteratorUtils.map(iterator(), v -> f.apply(v).iterator()))
-            );
-        }
-
-        @Override
-        public final T fold(T identity, BinaryOperator<T> accumulator) {
-            Iterator<T> i = iterator();
-            return i.hasNext() ? Fold.apply(i, accumulator::apply) : identity;
-        }
-
-        @Override
-        public final T fold(BinaryOperator<T> accumulator) {
-            return fold(null, accumulator);
-        }
-
-        @Override
-        public final T min(Comparator<T> cmp) {
-            return fold((a,b) -> cmp.compare(a, b)<0 ? a : b);
-        }
-
-        @Override
-        public final T max(Comparator<T> cmp) {
-            return fold((a,b) -> cmp.compare(a, b)>0 ? a : b);
-        }
-
-        @Override
-        public final T first() {
-            return IteratorUtils.first(iterator());
-        }
-
-        @Override
-        public final T last() {
-            return IteratorUtils.last(iterator());
-        }
-
-        @Override
-        public final IStream<T> distinct() {
-            return new SSupplier<>(() -> new HashSet<>(iterator()));
-        }
-        
-        @Override
-        public final IStream<T> distinct(HashFunction<T> eq) {
-            return new SSupplier<>(() -> new CustomSet<>(iterator(), eq));
-        }
-    
-        @Override
-        public final IStream<T> distinct(Comparator<T> cmp) {
-            return new SSupplier<>(() -> new RBTreeSet<>(iterator(), cmp));
-        }
-        
-        @Override
-        public final IStream<T> sort() {
-            return new SSupplier<>(() -> {
-                List<T> list = list();
-                ArraySort.mergeSort(list);
-                return list;
-            });
-        }
-
-        @Override
-        public final IStream<T> sort(Comparator<T> cmp) {
-            return new SSupplier<>(() -> {
-                List<T> list = list();
-                ArraySort.mergeSort(list, cmp);
-                return list;
-            });
-        }
-
-        @Override
-        public final void each(Consumer<T> consumer) {
-            stream().forEach(consumer);
-        }
-
-        @Override
-        public final boolean matchAny(Predicate<T> predicate) {
-            return stream().anyMatch(predicate);
-        }
-
-        @Override
-        public final boolean matchAll(Predicate<T> predicate) {
-            return stream().allMatch(predicate);
-        }
-
-        @Override
-        public final boolean matchNone(Predicate<T> predicate) {
-            return stream().noneMatch(predicate);
-        }
-        
-        @Override
-        public IStream<T> limit(int n) {
-            return new SLimit<>(this, 0, n);
-        }
-
-        @Override
-        public IStream<T> skip(int n) {
-            return new SLimit<>(this, n, Integer.MAX_VALUE);
-        }
-        
-    }
-    
-    private static final class SCollection<T> extends SAbstract<T> {
-        
-        private final Collection<T> source;
-        
-        
-        public SCollection(Collection<T> source) {
-            this.source = source;
-        }
-
-        @Override
-        public Iterator<T> iterator() {
-            return source.iterator();
-        }
-
-        @Override
-        public Spliterator<T> spliterator() {
-            return source.spliterator();
-        }
-
-        @Override
-        public Stream<T> stream() {
-            return source.stream();
-        }
-
-        @Override
-        public int size() {
-            return source.size();
-        }
-        
-    }
-    
-    private static final class SIterable<T> extends SAbstract<T> {
-        
-        private final Iterable<T> source;
-        
-        private final IntSupplier size;
-        
-        public SIterable(Iterable<T> source) {
-            this.source = source;
-            this.size = () -> IteratorUtils.size(source.iterator());
-        }
-        
-        public SIterable(Iterable<T> source, IntSupplier size) {
-            this.source = source;
-            this.size = size;
-        }
-
-        @Override
-        public Iterator<T> iterator() {
-            return source.iterator();
-        }
-
-        @Override
-        public Spliterator<T> spliterator() {
-            return source.spliterator();
-        }
-
-        @Override
-        public Stream<T> stream() {
-            return StreamSupport.stream(spliterator(), false);
-        }
-
-        @Override
-        public int size() {
-            return size.getAsInt();
-        }
-        
-        
-    }
-    
-    private static final class SSupplier<T> extends SAbstract<T> {
-        
-        private final Supplier<Collection<T>> source;
-
-        public SSupplier(Supplier<Collection<T>> source) {
-            this.source = source;
-        }
-
-        @Override
-        public Iterator<T> iterator() {
-            return source.get().iterator();
-        }
-
-        @Override
-        public Spliterator<T> spliterator() {
-            return source.get().spliterator();
-        }
-
-        @Override
-        public Stream<T> stream() {
-            return source.get().stream();
-        }
-
-        @Override
-        public int size() {
-            return source.get().size();
-        }
-       
-    }
-    
-    private static final class SLimit<T> extends SAbstract<T> {
-        
-        private final IStream<T> stream;
-        private final int begin;
-        private final int size;
-
-        public SLimit(IStream<T> stream, int begin, int size) {
-            this.stream = stream;
-            this.begin = begin;
-            this.size = size;
-        }
-        
-        @Override
-        public IStream<T> limit(int n) {
-            return new SLimit<>(stream, begin, Math.min(n, size));
-        }
-
-        @Override
-        public IStream<T> skip(int n) {
-            return new SLimit<>(stream, begin+n, size);
-        }
-
-        @Override
-        public Iterator<T> iterator() {
-            Iterator<T> i = stream.iterator();
-            IteratorUtils.next(i, begin);
-            return new LimitIterator<>(i, size);
-        }
-
-        @Override
-        public Spliterator<T> spliterator() {
-            return stream().spliterator();
-        }
-
-        @Override
-        public Stream<T> stream() {
-            return stream.stream().skip(begin).limit(size);
-        }
-
-        @Override
-        public int size() {
-            return Math.min(stream.size(), size);
-        }
-        
-    }
-    
-    private static final class LimitIterator<T> implements Iterator<T> {
-        
-        private final Iterator<T> src;
-        private final int limit;
-        private int count;
-
-        public LimitIterator(Iterator<T> src, int limit) {
-            this.src = src;
-            this.limit = limit;
-        }
-
-        @Override
-        public boolean hasNext() {
-            return count<limit && src.hasNext();
-        }
-
-        @Override
-        public T next() {
-            if(count>=limit) {
-                throw new NoSuchElementException();
-            }
-            count++;
-            return src.next();
-        }
-        
-        
-        
-    }
-    
-}

+ 56 - 0
assira/src/test/java/net/ranides/assira/collection/CollectionQueryTest.java

@@ -0,0 +1,56 @@
+/*
+ * @author Ranides Atterwim <ranides@gmail.com>
+ * @copyright Ranides Atterwim
+ * @license WTFPL
+ * @url http://ranides.net/projects/assira
+ */
+package net.ranides.assira.collection;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import org.junit.Test;
+import static net.ranides.assira.junit.NewAssert.*;
+
+/**
+ *
+ * @author Ranides Atterwim <ranides@gmail.com>
+ */
+public class CollectionQueryTest {
+    
+    private static final List<Character> CHARS = Arrays.asList('a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z');
+    
+    @Test
+    public void testSimple() {
+        List<String> exp1 = Arrays.asList(
+            "4.a", "4.b", 
+            "6.a", "6.b", "6.c",
+            "8.a", "8.b", "8.c", "8.d"
+        );
+        List<String> exp2 = Arrays.asList(
+            "6.a", "6.b", "6.c",
+            "6.a", "6.b", "6.c",
+            "10.a", "10.b", "10.c", "10.d", "10.e"
+        );
+        
+        List<Integer> src = new ArrayList<>();
+        
+        CollectionQuery<String> query = CollectionQuery.of(src)
+            .filter(v -> v%2 == 0)
+            .filter(v -> v>3)
+            .limit(3)
+            .unfold(i -> CollectionQuery.of(CHARS).limit(i/2).map(c->i+"."+c));
+        
+        src.addAll(Arrays.asList(0,1,2,3,4,5,6,7,8,9,10));
+        
+        assertEquals(exp1, query.list());
+        assertEquals(exp1, query.list());
+        
+        src.clear();
+        src.addAll(Arrays.asList(6,3,5,6,7,9,10));
+        
+        assertEquals(exp2, query.list());
+        assertEquals(exp2, query.list());
+    }
+    
+}