From b78c081286456655848005c8407fae838501b6f4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?D=C3=A1vid=20Karnok?= Date: Tue, 5 Jul 2016 21:53:11 +0200 Subject: [PATCH 01/66] IxJava 1.0.0 fresh start --- README.md | 17 +- gradle.properties | 2 +- src/main/java/ix/CloseableIterable.java | 26 - src/main/java/ix/CloseableIterator.java | 41 - src/main/java/ix/Enumerable.java | 31 - src/main/java/ix/Enumerator.java | 44 - src/main/java/ix/GroupedIterable.java | 63 - src/main/java/ix/Ix.java | 1500 +-------- src/main/java/ix/Pair.java | 66 - .../java/ix/exceptions/MultiIOException.java | 85 - .../exceptions/TooManyElementsException.java | 58 - src/main/java/ix/exceptions/package-info.java | 19 - .../internal/operators/AggregateIterable.java | 107 - .../ix/internal/operators/AllIterable.java | 97 - .../ix/internal/operators/AnyIterable.java | 71 - .../ix/internal/operators/BufferIterable.java | 94 - .../ix/internal/operators/CastIterable.java | 52 - .../internal/operators/CollectIterable.java | 97 - .../ix/internal/operators/ConcatIterable.java | 70 - .../ix/internal/operators/CountIterable.java | 78 - .../ix/internal/operators/DeferIterable.java | 33 - .../operators/DematerializeIterable.java | 68 - .../operators/DoOnCompletedIterable.java | 68 - .../internal/operators/DoOnEachIterable.java | 87 - .../internal/operators/DoOnNextIterable.java | 54 - .../internal/operators/DoWhileIterable.java | 66 - .../operators/EnumerationToIterator.java | 67 - .../ix/internal/operators/ErrorIterable.java | 66 - .../operators/FilterIndexedIterable.java | 79 - .../internal/operators/FlatMapIterable.java | 77 - .../internal/operators/GenerateIterable.java | 76 - .../operators/GenerateIterableTimed.java | 91 - .../ix/internal/operators/Interactive.java | 2867 ----------------- .../operators/IteratorToEnumerator.java | 53 - .../ix/internal/operators/JustIterable.java | 63 - .../internal/operators/LongCountIterable.java | 78 - .../internal/operators/LongRangeIterable.java | 60 - .../operators/MapIndexedIterable.java | 56 - .../operators/MaterializeIterable.java | 77 - .../operators/MemoizeAllIterable.java | 72 - .../internal/operators/MemoizeIterable.java | 82 - .../ix/internal/operators/MergeIterable.java | 127 - .../ix/internal/operators/MinMaxIterable.java | 128 - .../internal/operators/OnErrorResumeNext.java | 94 - .../operators/OnErrorResumeNextIterable.java | 93 - .../internal/operators/OrderByIterable.java | 103 - .../internal/operators/PartialIterable.java | 69 - .../ix/internal/operators/PrintAction1.java | 69 - .../ix/internal/operators/RangeIterable.java | 60 - .../ix/internal/operators/ReduceIterable.java | 100 - .../operators/RepeatCountIterable.java | 64 - .../ix/internal/operators/RepeatIterable.java | 53 - .../ix/internal/operators/RetryIterable.java | 79 - .../ix/internal/operators/ScanIterable.java | 59 - .../ix/internal/operators/ShareIterable.java | 36 - .../operators/ShareSelectorIterable.java | 37 - src/main/java/ix/internal/operators/Skip.java | 48 - .../internal/operators/SkipLastIterable.java | 71 - .../operators/SubsequentCountIterable.java | 71 - .../operators/SubsequentIterable.java | 62 - .../operators/SwitchCaseIterable.java | 37 - .../ix/internal/operators/TakeIterable.java | 68 - .../internal/operators/TakeLastIterable.java | 71 - .../ix/internal/operators/ToIterable.java | 84 - .../ix/internal/operators/UsingIterable.java | 84 - .../ix/internal/operators/ZipIterable.java | 90 - .../ix/internal/operators/package-info.java | 19 - .../java/ix/internal/util/CircularBuffer.java | 94 - .../ix/internal/util/IxHelperFunctions.java | 548 ---- .../java/ix/internal/util/LinkedBuffer.java | 50 - .../util/ObservableToIterableAdapter.java | 57 - .../internal/util/ObserverToIteratorSink.java | 95 - .../ix/internal/util/SingleContainer.java | 67 - .../java/ix/internal/util/SingleOption.java | 150 - .../java/ix/internal/util/package-info.java | 19 - src/test/java/ix/CollectTest.java | 80 - src/test/java/ix/FirstOrDefaultTest.java | 42 - .../java/ix/IxTest.java} | 40 +- src/test/java/ix/LastOrDefaultTest.java | 42 - src/test/java/ix/LastTest.java | 42 - src/test/java/ix/ReduceTest.java | 63 - src/test/java/ix/SkipTest.java | 59 - src/test/java/ix/TestInteractiveConcat.java | 74 - src/test/java/ix/TestInteractiveTake.java | 39 - src/test/java/ix/TestUtil.java | 119 - 85 files changed, 50 insertions(+), 10364 deletions(-) delete mode 100644 src/main/java/ix/CloseableIterable.java delete mode 100644 src/main/java/ix/CloseableIterator.java delete mode 100644 src/main/java/ix/Enumerable.java delete mode 100644 src/main/java/ix/Enumerator.java delete mode 100644 src/main/java/ix/GroupedIterable.java delete mode 100644 src/main/java/ix/Pair.java delete mode 100644 src/main/java/ix/exceptions/MultiIOException.java delete mode 100644 src/main/java/ix/exceptions/TooManyElementsException.java delete mode 100644 src/main/java/ix/exceptions/package-info.java delete mode 100644 src/main/java/ix/internal/operators/AggregateIterable.java delete mode 100644 src/main/java/ix/internal/operators/AllIterable.java delete mode 100644 src/main/java/ix/internal/operators/AnyIterable.java delete mode 100644 src/main/java/ix/internal/operators/BufferIterable.java delete mode 100644 src/main/java/ix/internal/operators/CastIterable.java delete mode 100644 src/main/java/ix/internal/operators/CollectIterable.java delete mode 100644 src/main/java/ix/internal/operators/ConcatIterable.java delete mode 100644 src/main/java/ix/internal/operators/CountIterable.java delete mode 100644 src/main/java/ix/internal/operators/DeferIterable.java delete mode 100644 src/main/java/ix/internal/operators/DematerializeIterable.java delete mode 100644 src/main/java/ix/internal/operators/DoOnCompletedIterable.java delete mode 100644 src/main/java/ix/internal/operators/DoOnEachIterable.java delete mode 100644 src/main/java/ix/internal/operators/DoOnNextIterable.java delete mode 100644 src/main/java/ix/internal/operators/DoWhileIterable.java delete mode 100644 src/main/java/ix/internal/operators/EnumerationToIterator.java delete mode 100644 src/main/java/ix/internal/operators/ErrorIterable.java delete mode 100644 src/main/java/ix/internal/operators/FilterIndexedIterable.java delete mode 100644 src/main/java/ix/internal/operators/FlatMapIterable.java delete mode 100644 src/main/java/ix/internal/operators/GenerateIterable.java delete mode 100644 src/main/java/ix/internal/operators/GenerateIterableTimed.java delete mode 100644 src/main/java/ix/internal/operators/Interactive.java delete mode 100644 src/main/java/ix/internal/operators/IteratorToEnumerator.java delete mode 100644 src/main/java/ix/internal/operators/JustIterable.java delete mode 100644 src/main/java/ix/internal/operators/LongCountIterable.java delete mode 100644 src/main/java/ix/internal/operators/LongRangeIterable.java delete mode 100644 src/main/java/ix/internal/operators/MapIndexedIterable.java delete mode 100644 src/main/java/ix/internal/operators/MaterializeIterable.java delete mode 100644 src/main/java/ix/internal/operators/MemoizeAllIterable.java delete mode 100644 src/main/java/ix/internal/operators/MemoizeIterable.java delete mode 100644 src/main/java/ix/internal/operators/MergeIterable.java delete mode 100644 src/main/java/ix/internal/operators/MinMaxIterable.java delete mode 100644 src/main/java/ix/internal/operators/OnErrorResumeNext.java delete mode 100644 src/main/java/ix/internal/operators/OnErrorResumeNextIterable.java delete mode 100644 src/main/java/ix/internal/operators/OrderByIterable.java delete mode 100644 src/main/java/ix/internal/operators/PartialIterable.java delete mode 100644 src/main/java/ix/internal/operators/PrintAction1.java delete mode 100644 src/main/java/ix/internal/operators/RangeIterable.java delete mode 100644 src/main/java/ix/internal/operators/ReduceIterable.java delete mode 100644 src/main/java/ix/internal/operators/RepeatCountIterable.java delete mode 100644 src/main/java/ix/internal/operators/RepeatIterable.java delete mode 100644 src/main/java/ix/internal/operators/RetryIterable.java delete mode 100644 src/main/java/ix/internal/operators/ScanIterable.java delete mode 100644 src/main/java/ix/internal/operators/ShareIterable.java delete mode 100644 src/main/java/ix/internal/operators/ShareSelectorIterable.java delete mode 100644 src/main/java/ix/internal/operators/Skip.java delete mode 100644 src/main/java/ix/internal/operators/SkipLastIterable.java delete mode 100644 src/main/java/ix/internal/operators/SubsequentCountIterable.java delete mode 100644 src/main/java/ix/internal/operators/SubsequentIterable.java delete mode 100644 src/main/java/ix/internal/operators/SwitchCaseIterable.java delete mode 100644 src/main/java/ix/internal/operators/TakeIterable.java delete mode 100644 src/main/java/ix/internal/operators/TakeLastIterable.java delete mode 100644 src/main/java/ix/internal/operators/ToIterable.java delete mode 100644 src/main/java/ix/internal/operators/UsingIterable.java delete mode 100644 src/main/java/ix/internal/operators/ZipIterable.java delete mode 100644 src/main/java/ix/internal/operators/package-info.java delete mode 100644 src/main/java/ix/internal/util/CircularBuffer.java delete mode 100644 src/main/java/ix/internal/util/IxHelperFunctions.java delete mode 100644 src/main/java/ix/internal/util/LinkedBuffer.java delete mode 100644 src/main/java/ix/internal/util/ObservableToIterableAdapter.java delete mode 100644 src/main/java/ix/internal/util/ObserverToIteratorSink.java delete mode 100644 src/main/java/ix/internal/util/SingleContainer.java delete mode 100644 src/main/java/ix/internal/util/SingleOption.java delete mode 100644 src/main/java/ix/internal/util/package-info.java delete mode 100644 src/test/java/ix/CollectTest.java delete mode 100644 src/test/java/ix/FirstOrDefaultTest.java rename src/{main/java/ix/package-info.java => test/java/ix/IxTest.java} (89%) delete mode 100644 src/test/java/ix/LastOrDefaultTest.java delete mode 100644 src/test/java/ix/LastTest.java delete mode 100644 src/test/java/ix/ReduceTest.java delete mode 100644 src/test/java/ix/SkipTest.java delete mode 100644 src/test/java/ix/TestInteractiveConcat.java delete mode 100644 src/test/java/ix/TestInteractiveTake.java delete mode 100644 src/test/java/ix/TestUtil.java diff --git a/README.md b/README.md index 899002a..3ac5707 100644 --- a/README.md +++ b/README.md @@ -5,21 +5,18 @@ Interactive Extensions for Java, the dual of RxJava. Originally implemented in t The aim is to provide pull-based datastream support with the same naming as in RxJava mainly for the pre-Java-8 world. The Stream API in Java 8 is not exactly the same thing because Streams can be only consumed once while Iterables can be consumed many times. Google Guava features a lot of Iterable operators but without method chaining support. -# Releases - - +**This branch starts from scratch by reimplementing `ix.Ix` and all of its operators based on the +5 year experience with reactive +and interactive dataflows.** -You can download any necessary JAR files manually from - -https://oss.sonatype.org/content/groups/public/com/github/akarnokd/ixjava/ +# Releases -Alternatively, you can use the usual maven dependency management to get the files: + **gradle** ``` dependencies { - compile "com.github.akarnokd:ixjava:0.92.6" + compile "com.github.akarnokd:ixjava:1.0.0" } ``` @@ -27,10 +24,10 @@ dependencies { ``` - + ``` -or the maven search facility +Maven search: [http://search.maven.org](http://search.maven.org/#search%7Cga%7C1%7Cg%3A%22com.github.akarnokd%22) diff --git a/gradle.properties b/gradle.properties index 75a7dc5..aef125e 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1 +1 @@ -version=0.92.6 +version=1.0.0 diff --git a/src/main/java/ix/CloseableIterable.java b/src/main/java/ix/CloseableIterable.java deleted file mode 100644 index bfb4ad0..0000000 --- a/src/main/java/ix/CloseableIterable.java +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright 2011-2016 David Karnok - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package ix; - - -/** - * An iterable type which returns iterators that support a close() method. - * @param the iterator element type - */ -public interface CloseableIterable extends Iterable { - @Override - CloseableIterator iterator(); -} diff --git a/src/main/java/ix/CloseableIterator.java b/src/main/java/ix/CloseableIterator.java deleted file mode 100644 index bb36961..0000000 --- a/src/main/java/ix/CloseableIterator.java +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright 2011-2016 David Karnok - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package ix; - -import java.util.Iterator; -import rx.Subscription; - -/** - * An iterator which supports a close() method. Usage: - *

- * CloseableIterator<T> it = citerable.iterator();
- * try {
- *     while (it.hasNext()) {
- *         doSomething(it.next());
- *         if (condition) {
- *             break;
- *         }
- *     }
- * } finally {
- *     it.close();
- * }
- * it.close();
- * 
- * @param the element type - */ -public interface CloseableIterator extends Iterator, Subscription { - -} diff --git a/src/main/java/ix/Enumerable.java b/src/main/java/ix/Enumerable.java deleted file mode 100644 index e3db935..0000000 --- a/src/main/java/ix/Enumerable.java +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright 2011-2016 David Karnok - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package ix; - -/** - * The base interface for an Enumerable-Enumerator - * pair of iteration method where the - * enumerator has next() to - * advance the iteration and current() - * to return the current element. An example - * from normal Java for such - * kind of iteration is the java.sql.ResultSet. - * @param the element type - */ -public interface Enumerable { - /** @return the enumerator. */ - Enumerator enumerator(); -} diff --git a/src/main/java/ix/Enumerator.java b/src/main/java/ix/Enumerator.java deleted file mode 100644 index 40431ea..0000000 --- a/src/main/java/ix/Enumerator.java +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright 2011-2016 David Karnok - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package ix; - -/** - * The base interface for an Enumerable-Enumerator - * pair of iteration method where the - * enumerator has next() to - * advance the iteration and current() - * to return the current element. An example - * from normal Java for such - * kind of iteration is the java.sql.ResultSet. - * @param the element type - */ -public interface Enumerator { - /** - * Tries to move to the next element. - * Only this method may throw an exception. - * @return false if there are no more elements - */ - boolean next(); - /** - * Returns the current element. If the - * enumeration was not started via the next() - * method, or the enumeration has already finished and next() - * returned false, a NoSuchElementException is thrown. - * Other than these, this method should not throw any exception. - * @return the current element. - */ - T current(); -} diff --git a/src/main/java/ix/GroupedIterable.java b/src/main/java/ix/GroupedIterable.java deleted file mode 100644 index 8c3fbc6..0000000 --- a/src/main/java/ix/GroupedIterable.java +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright 2011-2016 David Karnok - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package ix; - -import java.util.LinkedList; -import java.util.List; - -/** - * Contains a sequence values with an associated key used by the groupBy operator. - * @param the group key type - * @param the value type - */ -public final class GroupedIterable extends Ix { - /** The group key. */ - protected final K key; - /** The values in the group. */ - protected final List values; - /** - * Constructs a new grouped iterable with the given key. - * @param key the group key - */ - public GroupedIterable(K key) { - super(new LinkedList()); - this.key = key; - this.values = (List)this.it; - } - /** - * Returns the key associated with this group. - * @return the key associated with this group - */ - public K getKey() { - return key; - } - /** - * Adds one element to the values. - * @param value the value - */ - public void add(V value) { - values.add(value); - } - /** - * Add the values of the target iterable. - * @param values the values to add - */ - public void add(Iterable values) { - for (V v : values) { - this.values.add(v); - } - } -} diff --git a/src/main/java/ix/Ix.java b/src/main/java/ix/Ix.java index be7575d..e9d2203 100644 --- a/src/main/java/ix/Ix.java +++ b/src/main/java/ix/Ix.java @@ -1,1479 +1,21 @@ -/* - * Copyright 2011-2016 David Karnok - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package ix; - -import java.math.*; -import java.util.*; - -import ix.internal.operators.*; -import ix.internal.util.IxHelperFunctions; -import rx.*; -import rx.Observable; -import rx.functions.*; - -/** - * An iterable builder which offers methods to chain the - * sequence of some Interactive operations. - *

This builder is the dual of the - * {@link rx.Observable} class.

- * @param the element type - */ -public class Ix implements Iterable { - /** - * Creates an iterable builder which contains the concatenation - * of all the iterables returned by the iterable. - * @param the value type - * @param sources the source iterables - * @return the created iterable - */ - public static Ix concat(Iterable> sources) { - return from(Interactive.concat(sources)); - } - - /** - * Concatenates the array of Iterable sources into a single Iterable sequence. - * @param the value type - * @param sources the sources to concatenate - * @return the created iterable - * @since 0.92.3 - */ - public static Ix concat(Iterable... sources) { - return from(Interactive.concat(Arrays.asList(sources))); - } - - /** - * Defers the source iterable creation to registration time and - * calls the given func for the actual source. - * @param the element type - * @param func the function that returns an iterable. - * @return the new iterable - */ - public static Ix defer( - final Func0> func) { - return from(Interactive.defer(func)); - } - /** - * Creates a new iterable builder instance by wrapping the given - * source sequence, if not already a builder. - * @param the element type - * @param source the source sequence - * @return the created iterable builder - */ - public static Ix from(final Iterable source) { - if (source instanceof Ix) { - return (Ix)source; - } - return new Ix(source); - } - /** - * Creates a new iterable builder by wrapping the given observable. - *

The resulting iterable does not support the {@code remove()} method.

- * @param the element type - * @param source the source observable - * @return the created iterable builder - */ - public static Ix from(Observable source) { - return from(new ToIterable(source)); - } - /** - * Creates a new iterable builder instance by wrapping the given - * array. Changes to the array will be visible through - * the iterator. - * @param the element type - * @param ts the array of ts - * @return the created iterable builder - */ - public static Ix from(final T... ts) { - return from(Interactive.toIterable(ts)); - } - /** - * Creates an iterable which returns only a single element. - *

The returned iterator will throw an UnsupportedOperationException - * for its remove() method.

- * @param the element type - * @param value the value to return - * @return the new iterable - */ - public static Ix just(final T value) { - return from(Interactive.just(value)); - } - /** - * Returns an iterator which will throw the given - * Throwable exception when the client invokes - * next() the first time. Any subsequent - * next() call will simply throw a NoSuchElementException. - * Calling remove() will always throw a IllegalStateException. - * If the given Throwable instance extends a RuntimeException, it is throws - * as is, but when the throwable is a checked exception, it is wrapped - * into a RuntimeException. - * @param the element type, irrelevant - * @param t the exception to throw - * @return the new iterable - */ - public static Ix error( - final Throwable t) { - return from(Interactive.error(t)); - } - - /** - * The singleton instance of an empty Ix. - */ - static final Ix EMPTY = from(Interactive.empty()); - - /** - * Returns an empty iterable which will not produce elements. - * Its hasNext() returns always false, - * next() throws a NoSuchElementException - * and remove() throws an IllegalStateException. - * Note that the Collections.emptyIterable() static method is introduced by Java 7. - * @param the element type, irrelevant - * @return the iterable - */ - @SuppressWarnings("unchecked") - public static Ix empty() { - return (Ix)EMPTY; - } - /** - * Creates a new iterable builder instance by wrapping the given - * array. Changes to the array will be visible through - * the iterator. - * @param the element type - * @param from the source index inclusive - * @param to the destination index exclusive - * @param ts the array of ts - * @return the created iterable builder - */ - public static Ix fromPart(int from, int to, final T... ts) { - return from(Interactive.toIterablePart(from, to, ts)); - } - /** - * A generator function which returns Ts based on the termination condition and the way it computes the next values. - * This is equivalent to: - *

-     * T value = seed;
-     * while (predicate(value)) {
-     *     yield value;
-     *     value = next(value);
-     * }
-     * 
- *

The returned iterator will throw an UnsupportedOperationException - * for its remove() method.

- * @param the element type - * @param seed the initial value - * @param predicate the predicate to terminate the process - * @param next the function that computes the next value. - * @return the new iterable - */ - public static Ix generate(T seed, Func1 predicate, Func1 next) { - return from(Interactive.generate(seed, predicate, next)); - } - /** - * Creates a new iterable builder instance by wrapping the given - * source sequence. - * @param the element type - * @param source the source sequence - * @return the created iterable builder - */ - public static Ix newBuilder(final Iterable source) { - return new Ix(source); - } - /** - * Creates an integer iteratable builder which returns numbers from the start position in the count size. - *

The returned iterator will throw an UnsupportedOperationException - * for its remove() method.

- * @param start the starting value. - * @param count the number of elements to return, negative count means counting down from the start. - * @return the iterator. - */ - public static Ix range(int start, int count) { - return from(Interactive.range(start, count)); - } - /** - * Creates an long iterable builder which returns numbers from the start position in the count size. - *

The returned iterator will throw an UnsupportedOperationException - * for its remove() method.

- * @param start the starting value. - * @param count the number of elements to return, negative count means counting down from the start. - * @return the iterator. - */ - public static Ix range(long start, long count) { - return from(Interactive.range(start, count)); - } - - /** - * Creates an iterable builder which repeats the given - * value indefinitely. - *

The resulting iterable does not support the {@code remove()} method.

- * @param the element type - * @param t the value to repeat - * @return the created iterable builder - */ - public static Ix repeat(final T t) { - return from(Interactive.repeat(t)); - } - /** - * Returns an iterable builder which repeats the given single value the specified number of times. - *

The returned iterable does not support the {@code remove()} method.

- * @param the value type - * @param t the value to repeat - * @param count the repeat amount - * @return the iterable - */ - public static Ix repeat(final T t, int count) { - return from(Interactive.repeat(t, count)); - } - /** - * @param the element type - * @return a function which wraps its iterable parameter into an iterablebuilder instance - */ - public static Func1, Ix> toBuilder() { - return new Func1, Ix>() { - @Override - public Ix call(Iterable param1) { - return from(param1); - } - }; - } - /** The backing iterable. */ - protected final Iterable it; - /** - * Constructor. - * @param source the backing iterable - */ - protected Ix(Iterable source) { - this.it = source; - } - /** - * Creates an iterable which traverses the source iterable and maintains a running sum value based - * on the sum function parameter. Once the source is depleted, it - * applies the divide function and returns its result. - * This operator is a general base for averaging (where {@code sum(u, t) => u + t}, {@code divide(u, index) => u / index}), - * summing (where {@code sum(u, t) => u + t}, and {@code divide(u, index) => u)}), - * minimum, maximum, etc. - * If the traversal of the source fails due an exception, that exception is reflected on the - * {@code next()} call of the returned iterator. - * The returned iterator will throw an UnsupportedOperationException - * for its remove() method. - * @param the itermediate aggregation type - * @param the resulting aggregation type - * @param sum the function which takes the current itermediate value, - * the current source value and should produce a new intermediate value. - * for the first element of T, the U parameter will receive null - * @param divide the function which takes the last intermediate value and a total count of Ts seen and should return the final aggregation value. - * @return the new iterable - */ - public final Ix aggregate( - final Func2 sum, - final Func2 divide) { - return from(Interactive.aggregate(it, sum, divide)); - } - /** - * Returns an iterable which contains true if all - * elements of the source iterable satisfy the predicate. - * The operator might return a false before fully iterating the source. - *

The returned iterator will throw an UnsupportedOperationException - * for its remove() method.

- * @param predicate the predicate - * @return the new iterable - */ - public final Ix all(final Func1 predicate) { - return from(Interactive.all(it, predicate)); - } - /** - * Determines if the given source has any elements at all. - *

The returned iterator will throw an UnsupportedOperationException - * for its remove() method.

- * @return the new iterable with a single true or false - */ - public final Ix any() { - return from(Interactive.any(it)); - } - /** - * Tests if there is any element of the source that satisfies the given predicate function. - * @param predicate the predicate tester function - * @return the new iterable - */ - public final Ix any( - final Func1 predicate - ) { - return from(Interactive.any(it, predicate)); - } - /** - * Returns a pair of the maximum argument and value from the given sequence. - * @param the value type for the comparison, must be self comparable - * @param valueSelector the value selector function - * @return the pair of the first maximum element and value, null if the sequence was empty - */ - public final > Pair argAndMax( - Func1 valueSelector) { - return Interactive.argAndMax(it, valueSelector); - } - /** - * Returns a pair of the maximum argument and value from the given sequence. - * @param the value type - * @param valueSelector the selector to extract the value from T - * @param valueComparator the comparator to compare two values - * @return the first pair of max argument and value or null if the source sequence was empty - */ - public final Pair argAndMax( - Func1 valueSelector, - Comparator valueComparator) { - return Interactive.argAndMax(it, valueSelector, valueComparator); - } - /** - * Returns a pair of the minimum argument and value from the given sequence. - * @param the value type for the comparison, must be self comparable - * @param valueSelector the value selector function - * @return the pair of the first minimum element and value, null if the sequence was empty - */ - public final > Pair argAndMin( - Func1 valueSelector) { - return Interactive.argAndMin(it, valueSelector); - } - /** - * Returns a pair of the minimum argument and value from the given sequence. - * @param the value type - * @param valueSelector the selector to extract the value from T - * @param valueComparator the comparator to compare two values - * @return the first pair of minimum argument and value or null if the source sequence was empty - */ - public final Pair argAndMin( - Func1 valueSelector, - Comparator valueComparator) { - return Interactive.argAndMin(it, valueSelector, valueComparator); - } - /** - * Computes and signals the average value of the BigDecimal source. - * The source may not send nulls. - *

Note that it uses forced cast of this sequence. If T != BigDecimal this - * method is guaranteed to throw ClassCastException.

- * @return the observable for the average value - */ - @SuppressWarnings("unchecked") - public final Ix averageBigDecimal() { - return from(Interactive.averageBigDecimal((Iterable)it)); - } - /** - * Computes and signals the average value of the BigInteger source. - * The source may not send nulls. - *

Note that it uses forced cast of this sequence. If T != BigInteger this - * method is guaranteed to throw ClassCastException.

- * @return the observable for the average value - */ - - @SuppressWarnings("unchecked") - public final Ix averageBigInteger() { - return from(Interactive.averageBigInteger((Iterable)it)); - } - /** - * Computes and signals the average value of the Double source. - * The source may not send nulls. - * @return the observable for the average value - */ - - @SuppressWarnings("unchecked") - public final Ix averageDouble() { - return from(Interactive.averageDouble((Iterable)it)); - } - /** - * Computes and signals the average value of the Float source. - * The source may not send nulls. - * @return the observable for the average value - */ - - @SuppressWarnings("unchecked") - public final Ix averageFloat() { - return from(Interactive.averageFloat((Iterable)it)); - } - /** - * Computes and signals the average value of the integer source. - * The source may not send nulls. - * The intermediate aggregation used double values. - * @return the observable for the average value - */ - - @SuppressWarnings("unchecked") - public final Ix averageInt() { - return from(Interactive.averageInt((Iterable)it)); - - } - /** - * Computes and signals the average value of the Long source. - * The source may not send nulls. - * The intermediate aggregation used double values. - * @return the observable for the average value - */ - - @SuppressWarnings("unchecked") - public final Ix averageLong() { - return from(Interactive.averageLong((Iterable)it)); - } - /** - * Returns an iterable which buffers the source elements - * into bufferSize lists. - *

The returned iterator will throw an UnsupportedOperationException - * for its remove() method.

- * @param bufferSize the buffer size. - * @return the new iterable - */ - public final Ix> buffer(int bufferSize) { - return from(Interactive.buffer(it, bufferSize)); - } - - /** - * Collects all values from this sequence into a custom collection via the collector - * action and returns the collection as a single element. - * @param collectionSupplier the function that creates a collection for individual iterations - * @param collector the action that is called by the collection instance and the current - * element in the sequence - * @return the new iterable - * @since 0.92.3 - */ - public final Ix collect(Func0 collectionSupplier, Action2 collector) { - return from(new CollectIterable(this, collectionSupplier, collector)); - } - - /** - * Concatenate this iterable with the other iterable in a way, that calling the second iterator() - * only happens when there is no more element in the first iterator. - *

The returned iterator forwards all remove() calls - * to the current source (first or next). - * @param other the second iterable - * @return the new iterable - */ - public final Ix concatWith(Iterable other) { - return from(Interactive.concat(it, other)); - } - /** - * Concatenate this iterable with the sequence of array values. - * @param values the array values - * @return the created iterable builder - */ - public final Ix concatWith(final T... values) { - return concatWith(Interactive.toIterable(values)); - } - /** - * Creates an iterable builder which contains the concatenation - * of this iterable and the rest iterable provided. - * @param others the other iterables - * @return the created iterable - */ - @SuppressWarnings("unchecked") - public final Ix concatWithAll(Iterable> others) { - return from(Interactive.concat(Interactive.startWith(others, it))); - } - /** - * Returns an iterable which checks for the existence of the supplied - * value by comparing the elements of the source iterable using reference - * and equals(). The iterable then returns a single true or false. - * @param value the value to check - * @return the new iterable - */ - public final Ix contains(final Object value) { - return from(Interactive.contains(it, value)); - } - /** - * Counts the elements of the iterable source by using a 32 bit int. - *

The returned iterator will throw an UnsupportedOperationException - * for its remove() method.

- * @return the new iterable - */ - public final Ix count() { - return from(Interactive.count(it)); - } - /** - * Counts the elements of the iterable source by using a 64 bit long. - *

The returned iterator will throw an UnsupportedOperationException - * for its remove() method.

- * @return the new iterable - */ - public final Ix countLong() { - return from(Interactive.countLong(it)); - } - /** - * Convert the source materialized elements into normal iterator behavior. - *

The returned iterator will throw an UnsupportedOperationException - * for its remove() method.

- * @return the new iterable - */ - @SuppressWarnings("unchecked") - public final Ix dematerialize() { - return from(Interactive.dematerialize((Iterable>)it)); - } - /** - * Returns an iterable which filters its elements based if they vere ever seen before in - * the current iteration. - * Value equality is computed by reference equality and equals() - * @return the new iterable - */ - public final Ix distinct() { - return from(Interactive.distinct(it)); - } - /** - * Returns an iterable which filters its elements by an unique key - * in a way that when multiple source items produce the same key, only - * the first one ever seen gets relayed further on. - * Key equality is computed by reference equality and equals() - * @param the key element type - * @param keySelector the key selector for only-once filtering - * @return the new iterable - */ - public final Ix distinct(Func1 keySelector) { - return from(Interactive.distinct(it, keySelector, IxHelperFunctions.identity())); - } - /** - * Creates an iterable which ensures that subsequent values of T are not equal - * (reference and equals). - * @return the new iterable - */ - public final Ix distinctNext() { - return from(Interactive.distinctNext(it)); - } - /** - * Creates an iterable which ensures that subsequent values of - * T are not equal in respect to the extracted keys (reference and equals). - * @param the key type - * @param keySelector the function to extract the keys which will be compared - * @return the new iterable - */ - public final Ix distinctNext(final Func1 keySelector) { - return from(Interactive.distinctNext(it, keySelector)); - } - /** - * Returns an iterable which executes the given action after - * the stream completes. - *

The returned iterator forwards all remove() calls - * to the source.

- * @param action the action to invoke - * @return the new iterable - */ - public final Ix doOnCompleted(Action0 action) { - return from(Interactive.doOnCompleted(it, action)); - } - /** - * Construct a new iterable which will invoke the specified action - * before the source value gets relayed through it. - * Can be used to inject side-effects before returning a value. - *

The returned iterator forwards all remove() calls - * to the source.

- * @param action the action to invoke before each next() is returned. - * @return the new iterable - */ - public final Ix doOnNext(Action1 action) { - return from(Interactive.doOnNext(it, action)); - } - /** - * Returns an iterable which reiterates over and over again on source - * as long as the gate is true. The gate function is checked only - * when a pass over the source stream was completed. - * Note that using this operator on an empty iterable may result - * in a direct infinite loop in hasNext() or next() calls depending on the gate function. - *

The returned iterator forwards all remove() calls - * to the source.

- * @param gate the gate function to stop the repeat - * @return the new iterable - */ - - public final Ix doWhile( - final Func0 gate) { - return from(Interactive.doWhile(it, gate)); - } - /** - * Creates an iterable sequence which returns all elements from source - * followed by the supplied value as last. - *

The returned iterable forwards all {@code remove()} - * methods to the source iterable, except the last element where it - * throws UnsupportedOperationException.

- * @param value the value to append - * @return the new iterable - */ - public final Ix endWith(final T value) { - return from(Interactive.endWith(it, value)); - } - /** - * Creates an iterable which filters this iterable with the - * given predicate factory function. The predicate returned by the factory receives an index - * telling how many elements were processed thus far. - * Use this construct if you want to use some memorizing predicat function (e.g., filter by subsequent distinct, filter by first occurrences only) - * which need to be invoked per iterator() basis. - *

The returned iterator forwards all remove() calls - * to the source.

- * @param predicate the predicate function - * @return the new iterable - */ - public final Ix filter(final Func1 predicate) { - return from(Interactive.filter(it, predicate)); - } - /** - * Creates an iterable which filters this iterable with the - * given predicate factory function. The predicate returned by the factory receives an index - * telling how many elements were processed thus far. - * @param predicate the predicate - * @return the new iterable - */ - public final Ix filterIndexed(final Func2 predicate) { - return from(Interactive.filterIndexed(it, predicate)); - } - /** - * Returns the first element from the iterable sequence or - * throws a NoSuchElementException. - * @return the first element - */ - public final T first() { - return Interactive.first(it); - } - - /** - * Returns the first element from the sequence or the default - * value if this sequence is empty - * @param defaultValue the default value to return - * @return the first or default value - * @since 0.91.2 - */ - public final T firstOrDefault(T defaultValue) { - return Interactive.firstOrDefault(it, defaultValue); - } - - /** - * Creates an iterable which returns a stream of Us for each source Ts. - * The iterable stream of Us is returned by the supplied selector function. - *

The returned iterator forwards all remove() calls - * to the current source (which might not accept it). - * @param the output element type - * @param selector the selector for multiple Us for each T - * @return the new iterable - */ - public final Ix flatMap(final Func1> selector) { - return from(Interactive.flatMap(it, selector)); - } - /** - * Iterate over the source and submit each value to the - * given action. Basically, a for-each loop with pluggable - * action. - * This method is useful when the concrete values from the iterator - * are not needed but the iteration itself implies some side effects. - * @param action the action to invoke on with element - */ - public final void forEach( - final Action1 action) { - Interactive.forEach(it, action); - } - /** - * Creates an iterable which traverses the source iterable, - * and based on the key selector, groups values the elements into GroupedIterables, - * which can be interated over later on. - * The equivalence of the keys are determined via reference - * equality and equals() equality. - *

The returned iterator will throw an UnsupportedOperationException - * for its remove() method.

- * @param the result group element type - * @param keySelector the key selector - * @return the new iterable - */ - public final Ix> groupBy( - final Func1 keySelector) { - return from(Interactive.groupBy(it, keySelector, IxHelperFunctions.identity())); - } - /** - * Creates an iterable which traverses the source iterable, - * and based on the key selector, groups values extracted by valueSelector into GroupedIterables, - * which can be interated over later on. - * The equivalence of the keys are determined via reference - * equality and equals() equality. - *

The returned iterator will throw an UnsupportedOperationException - * for its remove() method.

- * @param the result group element type - * @param the result group keys - * @param keySelector the key selector - * @param valueSelector the value selector - * @return the new iterable - */ - public final Ix> groupBy( - final Func1 keySelector, - final Func1 valueSelector) { - return from(Interactive.groupBy(it, keySelector, valueSelector)); - } - /** - * Add the elements of the sequence into the supplied collection. - * @param a collection type - * @param out the output collection - * @return the same out value - */ - public final > U into(U out) { - Iterator it = iterator(); - try { - while (it.hasNext()) { - out.add(it.next()); - } - } finally { - Interactive.unsubscribe(it); - } - return out; - } - /** - * Returns a single true if the target iterable is empty. - * @return the new iterable - */ - public final Ix isEmpty() { - return from(Interactive.isEmpty(it)); - } - @Override - public final Iterator iterator() { - return it.iterator(); - } - /** - * Concatenates the source strings one after another and uses the given separator. - *

The returned iterator forwards all remove() calls - * to the source.

- * @param separator the separator to use - * @return the new iterable - */ - public final Ix join(String separator) { - return from(Interactive.join(it, separator)); - } - /** - * Returns the last element of the iterable or throws a - * NoSuchElementException if the iterable is empty. - * @return the last value - */ - public final T last() { - return Interactive.last(it); - } - - /** - * Returns the last element of this sequence or the default value if - * this sequence is empty. - * @param defaultValue the default value to return if this sequence is empty - * @return the last or default value - */ - public final T lastOrDefault(T defaultValue) { - return Interactive.lastOrDefault(it, defaultValue); - } - - /** - * Creates an iterable which is a transforms the source - * elements by using the selector function. - * The function receives the current element. - * @param the output element type - * @param selector the selector function - * @return the new iterable - */ - public final Ix map(final Func1 selector) { - return from(Interactive.map(it, selector)); - } - /** - * Creates an iterable which is a transforms the source - * elements by using the selector function. - * The function receives the current index and the current element. - *

The returned iterator forwards all remove() calls - * to the source.

- * @param the output element type - * @param selector the selector function - * @return the new iterable - */ - public final Ix mapIndexed(final Func2 selector) { - return from(Interactive.mapIndexed(it, selector)); - } - /** - * Transforms the sequence of the source iterable into an option sequence of - * Option.some(), Option.none() and Option.error() values, depending on - * what the source's hasNext() and next() produces. - * The returned iterator will throw an UnsupportedOperationException for its remove() method. - *

The returned iterator will throw an UnsupportedOperationException - * for its remove() method.

- * @return the new iterable - */ - public final Ix> materialize() { - return from(Interactive.materialize(it)); - } - /** - * Returns the maximum value of the given iterable source. - * @param the self comparable type - * @return the new iterable - */ - @SuppressWarnings("unchecked") - public final > Ix max() { - return from(Interactive.max((Iterable)it)); - } - /** - * Returns the maximum value of the given iterable source in respect to the supplied comparator. - * @param comparator the comparator to use - * @return the new iterable - */ - public final Ix max(Comparator comparator) { - return from(Interactive.max(it, comparator)); - } - /** - * Returns an iterator which will produce a single List of the maximum values encountered - * in the source stream based on the supplied key selector. - * @param the source element type, which must be self comparable - * @return the new iterable - */ - @SuppressWarnings("unchecked") - public final > Ix> maxBy() { - return from(Interactive.maxBy((Iterable)it)); - } - /** - * Returns an iterator which will produce a single List of the maximum values encountered - * in the source stream based on the supplied comparator. - * @param comparator the key comparator - * @return the new iterable - */ - public final Ix> maxBy(Comparator comparator) { - return from(Interactive.maxBy(it, comparator)); - } - /** - * Returns an iterator which will produce a single List of the maximum values encountered - * in the source stream based on the supplied key selector. - * @param the key type, which must be self-comparable - * @param keySelector the selector for keys - * @return the new iterable - */ - public final > Ix> mayBy(Func1 keySelector) { - return from(Interactive.maxBy(it, keySelector)); - } - /** - * Returns an iterator which will produce a single List of the minimum values encountered - * in the source stream based on the supplied key selector and comparator. - * @param the key type - * @param keySelector the selector for keys - * @param keyComparator the key comparator - * @return the new iterable - */ - public final Ix> mayBy(Func1 keySelector, Comparator keyComparator) { - return from(Interactive.maxBy(it, keySelector, keyComparator)); - } - /** - * Enumerates the source iterable once and caches its results. - * Any iterator party will basically drain this cache, e.g., - * reiterating over this iterable will produce no results. - * Note: the name is not a misspelling, see Memoization. - *

The returned iterator will throw an UnsupportedOperationException - * for its remove() method.

- * @param bufferSize the size of the buffering - * @return the new iterable - */ - public final Ix memoize(int bufferSize) { - return from(Interactive.memoize(it, bufferSize)); - } - /** - * The returned iterable ensures that the source iterable is only traversed once, regardless of - * how many iterator attaches to it and each iterator see only the values. - * Note: the name is not a misspelling, see Memoization. - *

The returned iterator will throw an UnsupportedOperationException - * for its remove() method.

- * @return the new iterable - */ - public final Ix memoizeAll() { - return from(Interactive.memoizeAll(it)); - } - /** - * Returns the maximum value of the given iterable source. - * @param the self comparable type - * @return the new iterable - */ - @SuppressWarnings("unchecked") - public final > Ix min() { - return from(Interactive.min((Iterable)it)); - } - /** - * Returns the minimum value of the given iterable source in respect to the supplied comparator. - *

The returned iterator will throw an UnsupportedOperationException - * for its remove() method.

- * @param comparator the comparator to use - * @return the new iterable - */ - public final Ix min(Comparator comparator) { - return from(Interactive.min(it, comparator)); - } - /** - * Returns an iterator which will produce a single List of the minimum values encountered - * in the source stream based on the supplied comparator. - * @param comparator the key comparator - * @return the new iterable - */ - public final Ix> minBy(Comparator comparator) { - return from(Interactive.minBy(it, comparator)); - } - /** - * Returns an iterator which will produce a single List of the minimum values encountered - * in the source stream based on the supplied key selector. - *

The returned iterator will throw an UnsupportedOperationException - * for its remove() method.

- * @param the key type, which must be self-comparable - * @param keySelector the selector for keys - * @return the new iterable - */ - public final > Ix> minBy(Func1 keySelector) { - return from(Interactive.minBy(it, keySelector)); - } - /** - * Returns an iterator which will produce a single List of the minimum values encountered - * in the source stream based on the supplied key selector and comparator. - *

The returned iterator will throw an UnsupportedOperationException - * for its remove() method.

- * @param the key type - * @param keySelector the selector for keys - * @param keyComparator the key comparator - * @return the new iterable - */ - public final Ix> minBy(Func1 keySelector, Comparator keyComparator) { - return from(Interactive.minBy(it, keySelector, keyComparator)); - } - /** - * Returns an iterator which will produce a single List of the minimum values encountered - * in the source stream based on the supplied key selector. - *

The returned iterator will throw an UnsupportedOperationException - * for its remove() method.

- * @param the source element type, which must be self comparable - * @return the new iterable - */ - @SuppressWarnings("unchecked") - public final > Ix> minxBy() { - return from(Interactive.minBy((Iterable)it)); - } - /** - * Casts the source iterable into a different typ by using a type token. - * If the source contains a wrong element, the next() - * will throw a ClassCastException. - *

The returned iterator forwards all remove() calls - * to the source.

- * @param the result element type - * @param token the type token - * @return the new iterable - */ - public final Ix ofType(final Class token) { - return from(Interactive.ofType(it, token)); - } - /** - * Returns an iterable which traverses the entire - * source iterable and creates an ordered list - * of elements. Once the source iterator completes, - * the elements are streamed to the output. - *

Note: the element type should be self comparable or a ClassCastException is thrown.

- * @param the source element type, which must be self comparable - * @return the new iterable - */ - @SuppressWarnings("unchecked") - public final > Ix orderBy() { - return from(Interactive.orderBy((Iterable)it)); - } - /** - * Returns an iterable which traverses the entire - * source iterable and creates an ordered list - * of elements. Once the source iterator completes, - * the elements are streamed to the output. - * @param comparator the value comparator - * @return the new iterable - */ - public final Ix orderBy(Comparator comparator) { - return from(Interactive.orderBy(it, comparator)); - } - /** - * Returns an iterable which traverses the entire - * source iterable and creates an ordered list - * of elements. Once the source iterator completes, - * the elements are streamed to the output. - * @param the key type for the ordering, must be self comparable - * @param keySelector the key selector for comparison - * @return the new iterable - */ - public final > Ix orderBy(Func1 keySelector) { - return from(Interactive.orderBy(it, keySelector)); - } - /** - * Returns an iterable which traverses the entire - * source iterable and creates an ordered list - * of elements. Once the source iterator completes, - * the elements are streamed to the output. - * @param the key type for the ordering - * @param keySelector the key selector for comparison - * @param keyComparator the key comparator function - * @return the new iterable - */ - public final Ix orderBy(Func1 keySelector, Comparator keyComparator) { - return from(Interactive.orderBy(it, keySelector, keyComparator)); - } - /** - * Runs this iterable and prints the values. - *

Is the same as using {@code this.run(Interactive.print())}.

- */ - public final void print() { - Interactive.forEach(it, Interactive.print()); - } - /** - * Runs this iterable and prints the values. - *

Is the same as using {@code this.run(Interactive.println())}.

- */ - public final void println() { - Interactive.forEach(it, Interactive.println()); - } - /** - * Applies the func function for a shared instance of the source, - * e.g., func.invoke(share(source)). - * @param the return types - * @param func invoke the function on the buffering iterable and return an iterator over it. - * @return the new iterable - */ - public final Ix prune(Func1, ? extends Iterable> func) { - return from(Interactive.prune(it, func)); - } - /** - * The returned iterable ensures that the source iterable is only traversed once, regardless of - * how many iterator attaches to it and each iterator see only the same cached values. - *

The returned iterator will throw an UnsupportedOperationException - * for remove() method of its first element, then it might throw for any - * subsequent element, depending on the source iterable.

- * @param the return types - * @param func invoke the function on the buffering iterable and return an iterator over it. - * @param initial the initial value to append to the output stream - * @return the new iterable - */ - public final Ix publish(final Func1, ? extends Iterable> func, - final U initial) { - return from(Interactive.publish(it, func, initial)); - } - /** - * The returned iterable ensures that the source iterable is only traversed once, regardless of - * how many iterator attaches to it and each iterator see only the values. - *

The returned iterator will throw an UnsupportedOperationException - * for its remove() method.

- * @param the return types - * @param func invoke the function on the buffering iterable and return an iterator over it. - * @return the new iterable - */ - public final Ix publish(final Func1, ? extends Iterable> func) { - return from(Interactive.publish(it, func)); - } - /** - * Reduces the values of this sequence into a single value by using a - * reducer function. - * @param reducer the reducer function that receives the first item or - * the result of the previous application of the function as the first parameter - * and the current item as the second parameter. - * @return the new Iterable - * @since 0.92.3 - */ - public final Ix reduce(Func2 reducer) { - return from(new ReduceIterable(this, reducer)); - } - /** - * Consumes the sequence and removes all items via the Iterator.remove(). - */ - public final void removeAll() { - Iterator it = iterator(); - try { - while (it.hasNext()) { - it.next(); - it.remove(); - } - } finally { - Interactive.unsubscribe(it); - } - } - /** - * The returned iterable ensures that the source iterable is only traversed once, regardless of - * how many iterator attaches to it and each iterator may only see one source element. - *

The returned iterator will throw an UnsupportedOperationException - * for its remove() method.

- * @param the return types - * @param func invoke the function on the buffering iterable and return an iterator over it. - * @return the new iterable - */ - public final Ix replay(final Func1, ? extends Iterable> func) { - return from(Interactive.replay(it, func)); - } - /** - * The returned iterable ensures that the source iterable is only traversed once, regardless of - * how many iterator attaches to it and each iterator see only the some cached values. - *

The returned iterator will throw an UnsupportedOperationException - * for its remove() method.

- * @param the return types - * @param func invoke the function on the buffering iterable and return an iterator over it. - * @param bufferSize the buffer size - * @return the new iterable - */ - public final Ix replay(final Func1, ? extends Iterable> func, - final int bufferSize) { - return from(Interactive.replay(it, func, bufferSize)); - } - /** - * Iterates over the given source without using its returned value. - * This method is useful when the concrete values from the iterator - * are not needed but the iteration itself implies some side effects. - */ - public final void run() { - Interactive.run(it); - } - /** - * Generates an iterable which acts like a running sum when iterating over the source iterable, e.g., - * For each element in T, it computes a value by using the current aggregation value and returns it. - * The first call to the aggregator function will receive a zero for its first argument. - * @param the destination element type - * @param aggregator the function which takes the current running aggregation value, the current element and produces a new aggregation value. - * @return the new iterable - */ - public final Ix scan(final Func2 aggregator) { - return from(Interactive.scan(it, aggregator)); - } - /** - * Generates an iterable which acts like a running sum when iterating over the source iterable, e.g., - * For each element in T, it computes a value by using the current aggregation value and returns it. - * The first call to the aggregator function will receive a zero for its first argument. - *

The returned iterator forwards all remove() calls - * to the source.

- * @param the destination element type - * @param seed the initial value of the running aggregation - * @param aggregator the function which takes the current running aggregation value, the current element and produces a new aggregation value. - * @return the new iterable - */ - public final Ix scan(final U seed, - final Func2 aggregator) { - return from(Interactive.scan(it, seed, aggregator)); - } - /** - * Returns an iterable which ensures the source iterable is - * only traversed once and clients may take values from each other, - * e.g., they share the same iterator. - * @return the new iterable - */ - public final Ix share() { - return from(Interactive.share(it)); - } - - /** - * Skips the specified amount of items at the beginning of the source sequence. - * @param num the number of elements to skip - * @return the new iterable - */ - public final Ix skip(final int num) { - return from(Interactive.skip(it, num)); - } - - /** - * Returns an iterable which skips the last num elements from the - * source iterable. - *

The returned iterator will throw an UnsupportedOperationException - * for its remove() method.

- * @param num the number of elements to skip at the end - * @return the new iterable - */ - public final Ix skipLast(final int num) { - return from(Interactive.skipLast(it, num)); - } - /** - * Returns an iterable which prefixes the source iterable values - * by a constant. - * It is equivalent to concat(singleton(value), source). - *

The returned iterator will throw an UnsupportedOperationException - * for its remove() method for the first element, and might - * throw for subsequent elements, depending on the source iterable.

- * @param value the value to prefix - * @return the new iterable. - */ - @SuppressWarnings("unchecked") - public final Ix startWith(T value) { - return from(Interactive.startWith(it, value)); - } - /** - * Returns each pair of subsequent elements as pairs. - *

The returned iterator will throw an UnsupportedOperationException - * for its remove() method.

- * @return the iterable builder - */ - public final Ix> subsequent() { - return from(Interactive.subsequent(it)); - } - /** - * Returns each pair of subsequent elements as pairs. - *

The returned iterator will throw an UnsupportedOperationException - * for its remove() method.

- * @param count the number of subsequent elements - * @return the iterable builder - */ - public final Ix> subsequent(int count) { - return from(Interactive.subsequent(it, count)) - .map(Ix.toBuilder()); - } - /** - * Computes and signals the sum of the values of the BigDecimal source. - * The source may not send nulls. - * @return the observable for the sum value - */ - - @SuppressWarnings("unchecked") - public final Ix sumBigDecimal() { - return from(Interactive.sumBigDecimal((Iterable)it)); - } - /** - * Computes and signals the sum of the values of the BigInteger source. - * The source may not send nulls. - * @return the observable for the sum value - */ - - @SuppressWarnings("unchecked") - public final Ix sumBigInteger() { - return from(Interactive.sumBigInteger((Iterable)it)); - } - - /** - * Computes and signals the sum of the values of the Double source. - * The source may not send nulls. - * @return the observable for the sum value - */ - - @SuppressWarnings("unchecked") - public final Ix sumDouble() { - return from(Interactive.sumDouble((Iterable)it)); - } - /** - * Computes and signals the sum of the values of the Float source. - * The source may not send nulls. - * @return the observable for the sum value - */ - - @SuppressWarnings("unchecked") - public final Ix sumFloat() { - return from(Interactive.sumFloat((Iterable)it)); - } - /** - * Computes and signals the sum of the values of the Integer source. - * The source may not send nulls. An empty source produces an empty sum - * @return the observable for the sum value - */ - - @SuppressWarnings("unchecked") - public final Ix sumInt() { - return from(Interactive.sumInt((Iterable)it)); - } - /** - * Computes and signals the sum of the values of the Integer source by using - * a double intermediate representation. - * The source may not send nulls. An empty source produces an empty sum - * @return the observable for the sum value - */ - - @SuppressWarnings("unchecked") - public final Ix sumIntAsDouble() { - return from(Interactive.sumIntAsDouble((Iterable)it)); - } - /** - * Computes and signals the sum of the values of the Long source. - * The source may not send nulls. - * @return the observable for the sum value - */ - - @SuppressWarnings("unchecked") - public final Ix sumLong() { - return from(Interactive.sumLong((Iterable)it)); - } - /** - * Computes and signals the sum of the values of the Long sourceby using - * a double intermediate representation. - * The source may not send nulls. - * @return the observable for the sum value - */ - - @SuppressWarnings("unchecked") - public final Ix sumLongAsDouble() { - return from(Interactive.sumLongAsDouble((Iterable)it)); - } - /** - * Returns the iterable which returns the first num element. - * from the source iterable. - *

The returned iterator forwards all remove() calls - * to the source.

- * @param num the number of items to take - * @return the new iterable - */ - public final Ix take(int num) { - return from(Interactive.take(it, num)); - } - /** - * Returns an iterable which takes only the last num elements from the - * source iterable. - *

The returned iterator will throw an UnsupportedOperationException - * for its remove() method.

- * @param num the number of elements to skip at the end - * @return the new iterable - */ - public final Ix takeLast(int num) { - return from(Interactive.takeLast(it, num)); - } - /** - * Returns an object array of all elements in this - * iterable. - * @return the object array - */ - public final Object[] toArray() { - return toList().toArray(); - } - /** - * Returns all elements from this iterable into either - * the given array or a new array if the size requires. - * @param a the output array - * @return the output array - */ - public final T[] toArray(T[] a) { - return toList().toArray(a); - } - /** - * Convinience method to create a hashmap from the elements. - * @param the key type - * @param keySelector the key selector - * @return the map - */ - public final Map toHashMap(Func1 keySelector) { - return toMap(keySelector, IxHelperFunctions.identity(), IxHelperFunctions.hashMapProvider()); - } - /** - * Convinience method to create a hash-multimap with list from the elements. - * @param the key type - * @param keySelector the key selector - * @return the multimap - */ - public final Map> toHashMultimap(Func1 keySelector) { - return toMultimap( - keySelector, - IxHelperFunctions.identity(), - IxHelperFunctions.>hashMapProvider(), - IxHelperFunctions.arrayListProvider()); - } - /** - * Iterates over and returns all elements in a list. - * @return the list of the values from this iterable - */ - public final List toList() { - List result = new ArrayList(); - into(result); - return result; - } - /** - * Convert the iterable values into a map representation. - *

If an element maps to the same key, the existing value will be overwritten.

- *

See Functions.hashMapProvider() and others for some standard map implementations.

- * @param the key type - * @param keySelector the function to extract a key from an element - * @param mapProvider the map provider - * @return the filled-in map. - */ - public final Map toMap( - Func1 keySelector, - Func0> mapProvider) { - return toMap(keySelector, IxHelperFunctions.identity(), mapProvider); - } - /** - * Convert the iterable values into a map representation. - *

If an element maps to the same key, the existing value will be overwritten.

- * @param the key type - * @param the value type - * @param keySelector the function to extract a key from an element - * @param valueSelector the function to extract a value from an element - * @param mapProvider the map provider - * @return the filled-in map. - */ - public final Map toMap( - Func1 keySelector, - Func1 valueSelector, - Func0> mapProvider) { - Map map = mapProvider.call(); - Iterator it = iterator(); - try { - while (it.hasNext()) { - T t = it.next(); - K key = keySelector.call(t); - V value = valueSelector.call(t); - map.put(key, value); - } - } finally { - Interactive.unsubscribe(it); - } - return map; - } - /** - * Convert the values into a multimap representation where each - * key can have multiple values. - *

See Functions.hashMapProvider(), Functions.arrayListProvider() - * and others for some standard map implementations.

- * @param the key type - * @param the value type - * @param the collection type - * @param keySelector the key selector - * @param valueSelector the value selector - * @param mapProvider the provider for the base map - * @param collectionProvider the provider for the value collection - * @return the multimap - */ - public final > Map toMultimap( - Func1 keySelector, - Func1 valueSelector, - Func0> mapProvider, - Func0 collectionProvider) { - Map result = mapProvider.call(); - Iterator it = iterator(); - try { - while (it.hasNext()) { - T t = it.next(); - K key = keySelector.call(t); - V value = valueSelector.call(t); - - C coll = result.get(key); - if (coll == null) { - coll = collectionProvider.call(); - result.put(key, coll); - } - coll.add(value); - } - } finally { - Interactive.unsubscribe(it); - } - return result; - } - /** - * Converts this iterable into an observable builder - * which uses the default scheduler of {@link rx.Observable} to emit values. - * @return the observable builder - */ - public final Observable toObservable() { - return Observable.from(it); - } - /** - * Converts this iterable into an observable builder - * which uses the supplied Scheduler to emit values. - * @param scheduler the scheduler - * @return the observable builder - */ - public final Observable toObservable(Scheduler scheduler) { - return Observable.from(it).subscribeOn(scheduler); - } - - /** - * Pairs each element from this and the oher iterable source and - * combines them into a new value by using the combiner - * function. - *

The returned iterator will throw an UnsupportedOperationException - * for its remove() method.

- * @param the right source type - * @param the result type - * @param right the right source - * @param combiner the combiner function - * @return the new iterable - */ - public final Ix zipWith(final Iterable right, - final Func2 combiner) { - return from(Interactive.zip(it, right, combiner)); - } -} +/* + * Copyright 2011-2016 David Karnok + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ix; + +public abstract class Ix implements Iterable { + +} diff --git a/src/main/java/ix/Pair.java b/src/main/java/ix/Pair.java deleted file mode 100644 index 081e6d1..0000000 --- a/src/main/java/ix/Pair.java +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright 2011-2016 David Karnok - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package ix; - -/** - * A pair of two objects. - * @param the first type - * @param the second type - */ -public final class Pair { - /** The first object. */ - public final T first; - /** The second object. */ - public final U second; - /** - * Construct a pair. - * @param first the first object - * @param second the second object - */ - public Pair(T first, U second) { - this.first = first; - this.second = second; - } - /** - * Construct a pair. - * @param the first type - * @param the second type - * @param first the first object - * @param second the second object - * @return the pair - */ - public static Pair of(T first, U second) { - return new Pair(first, second); - } - @Override - public boolean equals(Object obj) { - if (obj instanceof Pair) { - Pair that = (Pair)obj; - return - (this.first == that.first || (this.first != null && this.first.equals(that.first))) - && (this.second == that.second || (this.second != null && this.second.equals(that.second))); - } - return false; - } - @Override - public int hashCode() { - return (17 + (first != null ? first.hashCode() : 0)) * 31 + (second != null ? second.hashCode() : 0); - } - @Override - public String toString() { - return "(" + first + ", " + second + ")"; - } -} diff --git a/src/main/java/ix/exceptions/MultiIOException.java b/src/main/java/ix/exceptions/MultiIOException.java deleted file mode 100644 index 6b15dba..0000000 --- a/src/main/java/ix/exceptions/MultiIOException.java +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Copyright 2011-2016 David Karnok - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package ix.exceptions; - -import java.io.IOException; -import java.util.ArrayList; -import java.util.List; - -/** - * Exception that collects other IOException instances. - *

Note: unfortunately, we can't use Java 7's addSuppressed for - * this purpose as Reactive4Java is aimed at Java 6.

- */ -public class MultiIOException extends IOException { - /** */ - private static final long serialVersionUID = 7860115538280839361L; - /** The inner exceptions. */ - protected final List innerExceptions = new ArrayList(); - /** Default constructor with no message or cause. */ - public MultiIOException() { - super(); - } - /** - * Constructor with the error message. - * @param message the message - */ - public MultiIOException(String message) { - super(message); - } - /** - * Constructor with the cause. - * @param cause the cause - */ - public MultiIOException(Throwable cause) { - super(cause); - } - /** - * Constructor with the message and cause. - * @param message the message - * @param cause the cause - */ - public MultiIOException(String message, Throwable cause) { - super(message, cause); - } - /** - * Adds an exception to the inner exception list. - * @param ex the exception to add - */ - public void add(IOException ex) { - innerExceptions.add(ex); - } - /** - * @return t Returns the list of inner exceptions which can be freely modified. - */ - public List innerExceptions() { - return new ArrayList(innerExceptions); - } - /** - * Adds the exception to the given MultiIOException. If multi is null, a new - * messageless MultiIOException is created and returned. - * @param multi the target MultiIOException. If null, a new instance is created. - * @param ex the exception to add - * @return the multi value if non null or a new MultiIOException - */ - public static MultiIOException createOrAdd(MultiIOException multi, IOException ex) { - if (multi == null) { - multi = new MultiIOException(); - } - multi.add(ex); - return multi; - } -} diff --git a/src/main/java/ix/exceptions/TooManyElementsException.java b/src/main/java/ix/exceptions/TooManyElementsException.java deleted file mode 100644 index 1ef9e0d..0000000 --- a/src/main/java/ix/exceptions/TooManyElementsException.java +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright 2011-2016 David Karnok - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package ix.exceptions; - -/** - * Exception for cases when too many elements are contained - * within a collection or observable. Its the dual - * of NoSuchElementException. - */ -public class TooManyElementsException extends RuntimeException { - /** */ - private static final long serialVersionUID = 3390531861721818769L; - /** - * A message and cause-less constructor. - */ - public TooManyElementsException() { - super(); - } - - /** - * Construct the exception by using a message and a cause. - * @param message the message - * @param cause the cause - */ - public TooManyElementsException(String message, Throwable cause) { - super(message, cause); - } - - /** - * Construct the exception by using a message only. - * @param message the message - */ - public TooManyElementsException(String message) { - super(message); - } - - /** - * Construct the exception by using a cause only. - * @param cause the cause - */ - public TooManyElementsException(Throwable cause) { - super(cause); - } - -} diff --git a/src/main/java/ix/exceptions/package-info.java b/src/main/java/ix/exceptions/package-info.java deleted file mode 100644 index 7dc5a46..0000000 --- a/src/main/java/ix/exceptions/package-info.java +++ /dev/null @@ -1,19 +0,0 @@ -/* - * Copyright 2011-2016 David Karnok - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -/** - * Contains exception classes. - */ -package ix.exceptions; \ No newline at end of file diff --git a/src/main/java/ix/internal/operators/AggregateIterable.java b/src/main/java/ix/internal/operators/AggregateIterable.java deleted file mode 100644 index 4c97739..0000000 --- a/src/main/java/ix/internal/operators/AggregateIterable.java +++ /dev/null @@ -1,107 +0,0 @@ -/* - * Copyright 2011-2016 David Karnok - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package ix.internal.operators; - -import ix.internal.util.SingleContainer; - -import java.util.Iterator; -import java.util.NoSuchElementException; - -import rx.Notification; -import rx.functions.Func2; - -/** - * Aggregates the source values via a sum function and - * applies a divide function to return the final result. - * - * @param the source sequence element type - * @param the the accumulated type - * @param the result type - */ -public final class AggregateIterable implements Iterable { - /** The source sequence. */ - private final Iterable source; - /** The summing function. */ - private final Func2 sum; - /** The divider function. */ - private final Func2 divide; - - /** - * Constructor, initializes the fields. - * @param source the source sequence - * @param sum the sum function - * @param divide the division function - */ - public AggregateIterable(Iterable source, - Func2 sum, - Func2 divide) { - this.source = source; - this.sum = sum; - this.divide = divide; - } - - @Override - public Iterator iterator() { - return new Iterator() { - /** The source iterator. */ - final Iterator it = source.iterator(); - /** The single result container. */ - final SingleContainer> result = new SingleContainer>(); - /** We have finished the aggregation. */ - boolean done; - @Override - public boolean hasNext() { - if (!done) { - done = true; - if (result.isEmpty()) { - try { - U intermediate = null; - int count = 0; - try { - while (it.hasNext()) { - intermediate = sum.call(intermediate, it.next()); - count++; - } - } finally { - Interactive.unsubscribe(it); - } - if (count > 0) { - result.add(Interactive.some(divide.call(intermediate, count))); - } - } catch (Throwable t) { - result.add(Interactive.err(t)); - } - } - } - return !result.isEmpty(); - } - - @Override - public V next() { - if (hasNext()) { - return Interactive.value(result.take()); - } - throw new NoSuchElementException(); - } - - @Override - public void remove() { - throw new UnsupportedOperationException(); - } - - }; - } -} \ No newline at end of file diff --git a/src/main/java/ix/internal/operators/AllIterable.java b/src/main/java/ix/internal/operators/AllIterable.java deleted file mode 100644 index 3840c46..0000000 --- a/src/main/java/ix/internal/operators/AllIterable.java +++ /dev/null @@ -1,97 +0,0 @@ -/* - * Copyright 2011-2016 David Karnok - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package ix.internal.operators; - -import ix.internal.util.SingleContainer; - -import java.util.Iterator; -import java.util.NoSuchElementException; - -import rx.Notification; -import rx.functions.Func1; - -/** - * Returns an iterable which returns a single true if - * the predicate matches all elements in the source sequence - * or false otherwise. - * - * @param the source value type - */ -public final class AllIterable implements Iterable { - /** The source. */ - private final Iterable source; - /** The predicate. */ - private final Func1 predicate; - /** - * Constructor, initializes the fields. - * @param source the source sequence - * @param predicate the predicate function - */ - public AllIterable(Iterable source, - Func1 predicate) { - this.source = source; - this.predicate = predicate; - } - - @Override - public Iterator iterator() { - return new Iterator() { - /** The source iterator. */ - final Iterator it = source.iterator(); - /** The peek ahead container. */ - final SingleContainer> peek = new SingleContainer>(); - /** Completed. */ - boolean done; - @Override - public boolean hasNext() { - if (peek.isEmpty() && !done) { - try { - if (it.hasNext()) { - while (it.hasNext()) { - T value = it.next(); - if (!predicate.call(value)) { - peek.add(Interactive.some(false)); - return true; - } - } - peek.add(Interactive.some(true)); - } - done = true; - } catch (Throwable t) { - peek.add(Interactive.err(t)); - done = true; - } finally { - Interactive.unsubscribe(it); - } - } - return !peek.isEmpty(); - } - - @Override - public Boolean next() { - if (hasNext()) { - return Interactive.value(peek.take()); - } - throw new NoSuchElementException(); - } - - @Override - public void remove() { - throw new UnsupportedOperationException(); - } - }; - } -} \ No newline at end of file diff --git a/src/main/java/ix/internal/operators/AnyIterable.java b/src/main/java/ix/internal/operators/AnyIterable.java deleted file mode 100644 index 18a807d..0000000 --- a/src/main/java/ix/internal/operators/AnyIterable.java +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright 2011-2016 David Karnok - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package ix.internal.operators; - -import ix.internal.util.SingleContainer; - -import java.util.Iterator; -import java.util.NoSuchElementException; - -/** - * Iterable sequence that returns a single true if the source sequence contains any - * element. - * - * @param the element type - */ -public final class AnyIterable implements Iterable { - /** The source sequence. */ - private final Iterable source; - - public AnyIterable(Iterable source) { - this.source = source; - } - - @Override - public Iterator iterator() { - return new Iterator() { - /** The source's iterator. */ - Iterator it = source.iterator(); - final SingleContainer peek = new SingleContainer(); - /** Query once. */ - boolean once = true; - @Override - public boolean hasNext() { - if (once) { - once = false; - if (peek.isEmpty()) { - peek.add(it.hasNext()); - } - } - return !peek.isEmpty(); - } - - @Override - public Boolean next() { - if (hasNext()) { - return peek.take(); - } - throw new NoSuchElementException(); - } - - @Override - public void remove() { - throw new UnsupportedOperationException(); - } - - }; - } -} \ No newline at end of file diff --git a/src/main/java/ix/internal/operators/BufferIterable.java b/src/main/java/ix/internal/operators/BufferIterable.java deleted file mode 100644 index 6653375..0000000 --- a/src/main/java/ix/internal/operators/BufferIterable.java +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Copyright 2011-2016 David Karnok - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package ix.internal.operators; - -import ix.internal.util.SingleContainer; - -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; -import java.util.NoSuchElementException; - -import rx.Notification; - -/** - * Iterable sequence containing a list of subsequent values from the source sequence - * up to a given buffer size each. - * - * @param the value type - */ -public final class BufferIterable implements Iterable> { - /** The source sequence. */ - private final Iterable source; - /** The buffer size. */ - private final int bufferSize; - - public BufferIterable(Iterable source, int bufferSize) { - this.source = source; - this.bufferSize = bufferSize; - } - - @Override - public Iterator> iterator() { - return new Iterator>() { - /** The source iterator. */ - final Iterator it = source.iterator(); - /** The current buffer. */ - final SingleContainer>> peek = new SingleContainer>>(); - /** Did the source finish? */ - boolean done; - @Override - public boolean hasNext() { - if (peek.isEmpty() && !done) { - try { - if (it.hasNext()) { - try { - List buffer = new ArrayList(); - while (it.hasNext() && buffer.size() < bufferSize) { - buffer.add(it.next()); - } - if (buffer.size() > 0) { - peek.add(Interactive.some(buffer)); - } - } catch (Throwable t) { - done = true; - peek.add(Interactive.>err(t)); - } - } else { - done = true; - } - } finally { - Interactive.unsubscribe(it); - } - } - return !peek.isEmpty(); - } - - @Override - public List next() { - if (hasNext()) { - return Interactive.value(peek.take()); - } - throw new NoSuchElementException(); - } - - @Override - public void remove() { - throw new UnsupportedOperationException(); - } - }; - } -} \ No newline at end of file diff --git a/src/main/java/ix/internal/operators/CastIterable.java b/src/main/java/ix/internal/operators/CastIterable.java deleted file mode 100644 index 7180e68..0000000 --- a/src/main/java/ix/internal/operators/CastIterable.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright 2011-2016 David Karnok - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package ix.internal.operators; - -import java.util.Iterator; - -public final class CastIterable implements Iterable { - /** The source sequence. */ - private final Iterable source; - private final Class token; - - public CastIterable(Iterable source, Class token) { - this.source = source; - this.token = token; - } - - @Override - public Iterator iterator() { - return new Iterator() { - /** The source iterator. */ - final Iterator it = source.iterator(); - @Override - public boolean hasNext() { - return it.hasNext(); - } - - @Override - public T next() { - return token.cast(it.next()); - } - - @Override - public void remove() { - it.remove(); - } - - }; - } -} \ No newline at end of file diff --git a/src/main/java/ix/internal/operators/CollectIterable.java b/src/main/java/ix/internal/operators/CollectIterable.java deleted file mode 100644 index 7094d94..0000000 --- a/src/main/java/ix/internal/operators/CollectIterable.java +++ /dev/null @@ -1,97 +0,0 @@ -/* - * Copyright 2011-2016 David Karnok - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package ix.internal.operators; - -import java.util.*; - -import rx.functions.*; - -/** - * Collects source values into a custom collection and emits that single collection. - * @param the source value type - * @param the target collection type - * @since 0.92.3 - */ -public final class CollectIterable implements Iterable { - - final Iterable source; - - final Func0 collectionSupplier; - - final Action2 collector; - - public CollectIterable(Iterable source, Func0 collectionSupplier, Action2 collector) { - this.source = source; - this.collectionSupplier = collectionSupplier; - this.collector = collector; - } - - @Override - public Iterator iterator() { - C collection = collectionSupplier.call(); - - Iterator it = source.iterator(); - - return new CollectIterator(collection, it, collector); - } - - static final class CollectIterator implements Iterator { - final Action2 collector; - - C collection; - - Iterator it; - - boolean once; - - public CollectIterator(C collection, Iterator it, Action2 collector) { - this.collection = collection; - this.it = it; - this.collector = collector; - } - - @Override - public boolean hasNext() { - if (!once) { - once = true; - final C c = collection; - final Iterator o = it; - final Action2 a = collector; - while (o.hasNext()) { - a.call(c, o.next()); - } - return true; - } - return collection != null; - } - - @Override - public C next() { - if (hasNext()) { - C c = collection; - collection = null; - return c; - } - throw new NoSuchElementException(); - } - - @Override - public void remove() { - throw new UnsupportedOperationException(); - } - } -} diff --git a/src/main/java/ix/internal/operators/ConcatIterable.java b/src/main/java/ix/internal/operators/ConcatIterable.java deleted file mode 100644 index b155366..0000000 --- a/src/main/java/ix/internal/operators/ConcatIterable.java +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright 2011-2016 David Karnok - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package ix.internal.operators; - -import java.util.Iterator; -import java.util.NoSuchElementException; - -public final class ConcatIterable implements Iterable { - /** The source sequences. */ - private final Iterable> sources; - - public ConcatIterable(Iterable> sources) { - this.sources = sources; - } - - @Override - public Iterator iterator() { - final Iterator> si = sources.iterator(); - if (si.hasNext()) { - return new Iterator() { - /** The current iterable. */ - Iterator iter = si.next().iterator(); - /** Save the last iterator since hasNext might run forward into other iterators. */ - Iterator itForRemove; - @Override - public boolean hasNext() { - while (!iter.hasNext()) { - if (!si.hasNext()) { - return false; - } - iter = si.next().iterator(); - } - return true; - } - - @Override - public T next() { - if (!hasNext()) { - throw new NoSuchElementException(); - } - itForRemove = iter; - return iter.next(); - } - - @Override - public void remove() { - if (itForRemove == null) { - throw new IllegalStateException(); - } - itForRemove.remove(); - itForRemove = null; - } - }; - } - return Interactive.empty().iterator(); - } -} \ No newline at end of file diff --git a/src/main/java/ix/internal/operators/CountIterable.java b/src/main/java/ix/internal/operators/CountIterable.java deleted file mode 100644 index 9351e4c..0000000 --- a/src/main/java/ix/internal/operators/CountIterable.java +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Copyright 2011-2016 David Karnok - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package ix.internal.operators; - -import ix.internal.util.SingleContainer; - -import java.util.Iterator; -import java.util.NoSuchElementException; - -import rx.Notification; - -public final class CountIterable implements Iterable { - /** The source sequence. */ - private final Iterable source; - - public CountIterable(Iterable source) { - this.source = source; - } - - @Override - public Iterator iterator() { - final Iterator it = source.iterator(); - return new Iterator() { - /** The peek ahead container. */ - final SingleContainer> peek = new SingleContainer>(); - /** Computation already done. */ - boolean done; - @Override - public boolean hasNext() { - if (!done) { - if (peek.isEmpty()) { - int count = 0; - try { - while (it.hasNext()) { - it.next(); - count++; - } - peek.add(Interactive.some(count)); - } catch (Throwable t) { - peek.add(Interactive.err(t)); - } finally { - done = true; - Interactive.unsubscribe(it); - } - } - } - return !peek.isEmpty(); - } - - @Override - public Integer next() { - if (hasNext()) { - return Interactive.value(peek.take()); - } - throw new NoSuchElementException(); - } - - @Override - public void remove() { - throw new UnsupportedOperationException(); - } - - }; - } -} \ No newline at end of file diff --git a/src/main/java/ix/internal/operators/DeferIterable.java b/src/main/java/ix/internal/operators/DeferIterable.java deleted file mode 100644 index e2271a1..0000000 --- a/src/main/java/ix/internal/operators/DeferIterable.java +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright 2011-2016 David Karnok - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package ix.internal.operators; - -import java.util.Iterator; - -import rx.functions.Func0; - -public final class DeferIterable implements Iterable { - private final Func0> func; - - public DeferIterable(Func0> func) { - this.func = func; - } - - @Override - public Iterator iterator() { - return func.call().iterator(); - } -} \ No newline at end of file diff --git a/src/main/java/ix/internal/operators/DematerializeIterable.java b/src/main/java/ix/internal/operators/DematerializeIterable.java deleted file mode 100644 index 6ae6b81..0000000 --- a/src/main/java/ix/internal/operators/DematerializeIterable.java +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright 2011-2016 David Karnok - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package ix.internal.operators; - -import ix.internal.util.SingleContainer; - -import java.util.Iterator; -import java.util.NoSuchElementException; - -import rx.Notification; - -public final class DematerializeIterable implements Iterable { - /** The source sequence. */ - private final Iterable> source; - - public DematerializeIterable( - Iterable> source) { - this.source = source; - } - - @Override - public Iterator iterator() { - final Iterator> it = source.iterator(); - return new Iterator() { - final SingleContainer> peek = new SingleContainer>(); - @Override - public boolean hasNext() { - if (peek.isEmpty()) { - if (it.hasNext()) { - Notification o = it.next(); - if (o.isOnCompleted()) { - return false; - } - peek.add(o); - } - } - return !peek.isEmpty(); - } - - @Override - public T next() { - if (hasNext()) { - return Interactive.value(peek.take()); - } - throw new NoSuchElementException(); - } - - @Override - public void remove() { - throw new UnsupportedOperationException(); - } - - }; - } -} \ No newline at end of file diff --git a/src/main/java/ix/internal/operators/DoOnCompletedIterable.java b/src/main/java/ix/internal/operators/DoOnCompletedIterable.java deleted file mode 100644 index 5c1ce29..0000000 --- a/src/main/java/ix/internal/operators/DoOnCompletedIterable.java +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright 2011-2016 David Karnok - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package ix.internal.operators; - -import java.util.Iterator; -import java.util.NoSuchElementException; - -import rx.functions.Action0; - -public final class DoOnCompletedIterable implements Iterable { - private final Action0 action; - /** The source sequence. */ - private final Iterable source; - - public DoOnCompletedIterable(Action0 action, - Iterable source) { - this.action = action; - this.source = source; - } - - @Override - public Iterator iterator() { - return new Iterator() { - /** The iterator. */ - final Iterator it = source.iterator(); - /** After the last. */ - boolean last; - @Override - public boolean hasNext() { - if (!it.hasNext()) { - if (!last) { - last = true; - action.call(); - } - return false; - } - return true; - } - - @Override - public T next() { - if (hasNext()) { - return it.next(); - } - throw new NoSuchElementException(); - } - - @Override - public void remove() { - it.remove(); - } - - }; - } -} \ No newline at end of file diff --git a/src/main/java/ix/internal/operators/DoOnEachIterable.java b/src/main/java/ix/internal/operators/DoOnEachIterable.java deleted file mode 100644 index 72b5907..0000000 --- a/src/main/java/ix/internal/operators/DoOnEachIterable.java +++ /dev/null @@ -1,87 +0,0 @@ -/* - * Copyright 2011-2016 David Karnok - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package ix.internal.operators; - -import ix.internal.util.SingleContainer; - -import java.util.Iterator; -import java.util.NoSuchElementException; - -import rx.Notification; -import rx.functions.Action0; -import rx.functions.Action1; - -public final class DoOnEachIterable implements Iterable { - private final Action1 error; - private final Action0 finish; - /** The source sequence. */ - private final Iterable source; - - public DoOnEachIterable(Action1 error, - Action0 finish, Iterable source) { - this.error = error; - this.finish = finish; - this.source = source; - } - - @Override - public Iterator iterator() { - return new Iterator() { - /** The iterator. */ - final Iterator it = source.iterator(); - /** The peek ahead container. */ - final SingleContainer> peek = new SingleContainer>(); - /** Finish or error once. */ - boolean once = true; - @Override - public boolean hasNext() { - if (peek.isEmpty()) { - try { - if (it.hasNext()) { - peek.add(Interactive.some(it.next())); - } else { - if (once) { - once = false; - finish.call(); - } - } - } catch (Throwable t) { - peek.add(Interactive.err(t)); - } - } - return !peek.isEmpty(); - } - - @Override - public T next() { - if (it.hasNext()) { - Notification o = peek.take(); - if (o.isOnError() && once) { - once = false; - error.call(o.getThrowable()); - } - return Interactive.value(o); - } - throw new NoSuchElementException(); - } - - @Override - public void remove() { - it.remove(); - } - }; - } -} \ No newline at end of file diff --git a/src/main/java/ix/internal/operators/DoOnNextIterable.java b/src/main/java/ix/internal/operators/DoOnNextIterable.java deleted file mode 100644 index 25f34e5..0000000 --- a/src/main/java/ix/internal/operators/DoOnNextIterable.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright 2011-2016 David Karnok - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package ix.internal.operators; - -import java.util.Iterator; - -import rx.functions.Action1; - -public final class DoOnNextIterable implements Iterable { - /** The source sequence. */ - private final Iterable source; - private final Action1 action; - - public DoOnNextIterable(Iterable source, - Action1 action) { - this.source = source; - this.action = action; - } - - @Override - public Iterator iterator() { - return new Iterator() { - /** The source iterator. */ - final Iterator it = source.iterator(); - @Override - public boolean hasNext() { - return it.hasNext(); - } - @Override - public T next() { - T value = it.next(); - action.call(value); - return value; - } - @Override - public void remove() { - it.remove(); - } - }; - } -} \ No newline at end of file diff --git a/src/main/java/ix/internal/operators/DoWhileIterable.java b/src/main/java/ix/internal/operators/DoWhileIterable.java deleted file mode 100644 index 15365eb..0000000 --- a/src/main/java/ix/internal/operators/DoWhileIterable.java +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright 2011-2016 David Karnok - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package ix.internal.operators; - -import java.util.Iterator; -import java.util.NoSuchElementException; - -import rx.functions.Func0; - -public final class DoWhileIterable implements Iterable { - /** The source sequence. */ - private final Iterable source; - private final Func0 gate; - - public DoWhileIterable(Iterable source, Func0 gate) { - this.source = source; - this.gate = gate; - } - - @Override - public Iterator iterator() { - return new Iterator() { - /** is this the first pass? */ - Iterator it = source.iterator(); - @Override - public boolean hasNext() { - while (true) { - if (it.hasNext()) { - return true; - } - if (gate.call()) { - it = source.iterator(); - } else { - break; - } - } - return false; - } - @Override - public T next() { - if (hasNext()) { - return it.next(); - } - throw new NoSuchElementException(); - } - - @Override - public void remove() { - it.remove(); - } - }; - } -} \ No newline at end of file diff --git a/src/main/java/ix/internal/operators/EnumerationToIterator.java b/src/main/java/ix/internal/operators/EnumerationToIterator.java deleted file mode 100644 index 0b9a5bd..0000000 --- a/src/main/java/ix/internal/operators/EnumerationToIterator.java +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright 2011-2016 David Karnok - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package ix.internal.operators; - -import ix.Enumerator; -import ix.internal.util.SingleContainer; - -import java.util.Iterator; -import java.util.NoSuchElementException; - -import rx.Notification; - -public final class EnumerationToIterator implements Iterator { - /** The source enumerator. */ - private final Enumerator en; - /** The peek-ahead buffer. */ - final SingleContainer> peek = new SingleContainer>(); - /** Completion indicator. */ - boolean done; - - public EnumerationToIterator(Enumerator en) { - this.en = en; - } - - @Override - public boolean hasNext() { - if (!done && peek.isEmpty()) { - try { - if (en.next()) { - peek.add(Interactive.some(en.current())); - } else { - done = true; - } - } catch (Throwable t) { - done = true; - peek.add(Interactive.err(t)); - } - } - return peek.isEmpty(); - } - - @Override - public T next() { - if (hasNext()) { - return Interactive.value(peek.take()); - } - throw new NoSuchElementException(); - } - - @Override - public void remove() { - throw new UnsupportedOperationException(); - } -} \ No newline at end of file diff --git a/src/main/java/ix/internal/operators/ErrorIterable.java b/src/main/java/ix/internal/operators/ErrorIterable.java deleted file mode 100644 index 7693b6b..0000000 --- a/src/main/java/ix/internal/operators/ErrorIterable.java +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright 2011-2016 David Karnok - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package ix.internal.operators; - -import java.util.Iterator; -import java.util.NoSuchElementException; - -/** - * Iterable sequence which throws a specific exception when the first element is retrieved. - * - * @param the value type, ignored - */ -public final class ErrorIterable implements Iterable { - /** The exception to throw on the first element. */ - private final Throwable t; - /** - * Constructor, sets the exception. - * @param t the exception to throw - */ - public ErrorIterable(Throwable t) { - this.t = t; - } - - @Override - public Iterator iterator() { - return new Iterator() { - /** First call? */ - boolean first = true; - @Override - public boolean hasNext() { - return first; - } - - @Override - public T next() { - if (first) { - first = false; - if (t instanceof RuntimeException) { - throw (RuntimeException)t; - } - throw new RuntimeException(t); - } - throw new NoSuchElementException(); - } - - @Override - public void remove() { - throw new IllegalStateException(); - } - - }; - } -} \ No newline at end of file diff --git a/src/main/java/ix/internal/operators/FilterIndexedIterable.java b/src/main/java/ix/internal/operators/FilterIndexedIterable.java deleted file mode 100644 index aaca605..0000000 --- a/src/main/java/ix/internal/operators/FilterIndexedIterable.java +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Copyright 2011-2016 David Karnok - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package ix.internal.operators; - -import ix.internal.util.SingleContainer; - -import java.util.Iterator; -import java.util.NoSuchElementException; - -import rx.functions.Func0; -import rx.functions.Func2; - -public final class FilterIndexedIterable implements Iterable { - /** The source sequence. */ - private final Iterable source; - private final Func0> predicateFactory; - - public FilterIndexedIterable( - Iterable source, - Func0> predicateFactory) { - this.source = source; - this.predicateFactory = predicateFactory; - } - - @Override - public Iterator iterator() { - final Func2 predicate = predicateFactory.call(); - final Iterator it = source.iterator(); - return new Iterator() { - /** The current element count. */ - int count; - /** The temporary store for peeked elements. */ - final SingleContainer peek = new SingleContainer(); - @Override - public boolean hasNext() { - if (peek.isEmpty()) { - while (it.hasNext()) { - T value = it.next(); - if (predicate.call(count, value)) { - peek.add(value); - count++; - return true; - } - count++; - } - return false; - } - return true; - } - - @Override - public T next() { - if (hasNext()) { - return peek.take(); - } - throw new NoSuchElementException(); - } - - @Override - public void remove() { - it.remove(); - } - - }; - } -} \ No newline at end of file diff --git a/src/main/java/ix/internal/operators/FlatMapIterable.java b/src/main/java/ix/internal/operators/FlatMapIterable.java deleted file mode 100644 index b53be5c..0000000 --- a/src/main/java/ix/internal/operators/FlatMapIterable.java +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Copyright 2011-2016 David Karnok - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package ix.internal.operators; - -import java.util.Iterator; -import java.util.NoSuchElementException; - -import rx.functions.Func1; - -public final class FlatMapIterable implements Iterable { - private final Func1> selector; - /** The source sequence. */ - private final Iterable source; - - public FlatMapIterable( - Func1> selector, - Iterable source) { - this.selector = selector; - this.source = source; - } - - @Override - public Iterator iterator() { - final Iterator it = source.iterator(); - return new Iterator() { - /** The current selected iterator. */ - Iterator sel; - @Override - public boolean hasNext() { - if (sel == null || !sel.hasNext()) { - while (!Thread.currentThread().isInterrupted()) { - if (it.hasNext()) { - sel = selector.call(it.next()).iterator(); - if (sel.hasNext()) { - return true; - } - } else { - break; - } - } - return false; - } - return true; - } - - @Override - public U next() { - if (hasNext()) { - return sel.next(); - } - throw new NoSuchElementException(); - } - - @Override - public void remove() { - if (sel == null) { - throw new IllegalStateException(); - } - sel.remove(); - } - - }; - } -} \ No newline at end of file diff --git a/src/main/java/ix/internal/operators/GenerateIterable.java b/src/main/java/ix/internal/operators/GenerateIterable.java deleted file mode 100644 index c2b3602..0000000 --- a/src/main/java/ix/internal/operators/GenerateIterable.java +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright 2011-2016 David Karnok - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package ix.internal.operators; - -import java.util.Iterator; -import java.util.NoSuchElementException; - -import rx.functions.Func1; - -/** - * Iterable sequence similar to a for-loop which generates sequence of values by - * using callback functions. - * - * @param the value type - */ -public final class GenerateIterable implements Iterable { - /** The initial value. */ - private final T seed; - /** Function to generate the next value. */ - private final Func1 next; - /** Function to test for termination condition. */ - private final Func1 predicate; - - /** - * Constructor, sets the fields. - * @param seed the initial value - * @param next the function to generate the next value - * @param predicate function to test for termination - */ - public GenerateIterable(T seed, Func1 next, - Func1 predicate) { - this.seed = seed; - this.next = next; - this.predicate = predicate; - } - - @Override - public Iterator iterator() { - return new Iterator() { - T value = seed; - @Override - public boolean hasNext() { - return predicate.call(value); - } - - @Override - public T next() { - if (hasNext()) { - T current = value; - value = next.call(value); - return current; - } - throw new NoSuchElementException(); - } - - @Override - public void remove() { - throw new UnsupportedOperationException(); - } - - }; - } -} \ No newline at end of file diff --git a/src/main/java/ix/internal/operators/GenerateIterableTimed.java b/src/main/java/ix/internal/operators/GenerateIterableTimed.java deleted file mode 100644 index beae798..0000000 --- a/src/main/java/ix/internal/operators/GenerateIterableTimed.java +++ /dev/null @@ -1,91 +0,0 @@ -/* - * Copyright 2011-2016 David Karnok - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package ix.internal.operators; - -import java.util.Iterator; -import java.util.NoSuchElementException; -import java.util.concurrent.TimeUnit; - -import rx.functions.Func1; - -public final class GenerateIterableTimed implements Iterable { - private final Func1 predicate; - private final Func1 next; - private final T seed; - private final long initialDelay; - private final long betweenDelay; - private final TimeUnit unit; - - public GenerateIterableTimed(Func1 predicate, - Func1 next, T seed, long initialDelay, - long betweenDelay, TimeUnit unit) { - this.predicate = predicate; - this.next = next; - this.seed = seed; - this.initialDelay = initialDelay; - this.betweenDelay = betweenDelay; - this.unit = unit; - } - - @Override - public Iterator iterator() { - return new Iterator() { - T value = seed; - /** Keeps track of whether there should be an initial delay? */ - boolean shouldInitialWait = true; - /** Keeps track of whether there should be an initial delay? */ - boolean shouldBetweenWait; - @Override - public boolean hasNext() { - if (shouldInitialWait) { - shouldInitialWait = false; - try { - unit.sleep(initialDelay); - } catch (InterruptedException e) { - return false; // FIXME not soure about this - } - } else { - if (shouldBetweenWait) { - shouldBetweenWait = false; - try { - unit.sleep(betweenDelay); - } catch (InterruptedException e) { - return false; // FIXME not soure about this - } - } - } - return predicate.call(value); - } - - @Override - public T next() { - if (hasNext()) { - shouldBetweenWait = true; - T current = value; - value = next.call(value); - return current; - } - throw new NoSuchElementException(); - } - - @Override - public void remove() { - throw new UnsupportedOperationException(); - } - - }; - } -} \ No newline at end of file diff --git a/src/main/java/ix/internal/operators/Interactive.java b/src/main/java/ix/internal/operators/Interactive.java deleted file mode 100644 index dc812ef..0000000 --- a/src/main/java/ix/internal/operators/Interactive.java +++ /dev/null @@ -1,2867 +0,0 @@ -/* - * Copyright 2011-2016 David Karnok - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package ix.internal.operators; - -import ix.CloseableIterable; -import ix.CloseableIterator; -import ix.Enumerable; -import ix.Enumerator; -import ix.GroupedIterable; -import ix.Pair; -import ix.internal.util.IxHelperFunctions; -import ix.internal.util.LinkedBuffer; - -import java.io.Closeable; -import java.io.IOException; -import java.math.BigDecimal; -import java.math.BigInteger; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Comparator; -import java.util.HashSet; -import java.util.Iterator; -import java.util.LinkedHashMap; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; -import java.util.NoSuchElementException; -import java.util.Set; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicBoolean; - -import rx.Notification; -import rx.Scheduler; -import rx.Subscription; -import rx.exceptions.Exceptions; -import rx.functions.Action0; -import rx.functions.Action1; -import rx.functions.Actions; -import rx.functions.Func0; -import rx.functions.Func1; -import rx.functions.Func2; -import rx.schedulers.Schedulers; - -/** - * The interactive (i.e., Iterable based) counterparts - * of the Reactive operators. - *

The implementations of the operators are partially derived - * from the Reactive operators.

- * @see rx.Observable - */ -public final class Interactive { - /** - * Creates an iterable which traverses the source iterable and maintains a running sum value based - * on the sum function parameter. Once the source is depleted, it - * applies the divide function and returns its result. - * This operator is a general base for averaging (where {@code sum(u, t) => u + t}, {@code divide(u, index) => u / index}), - * summing (where {@code sum(u, t) => u + t}, and {@code divide(u, index) => u)}), - * minimum, maximum, etc. - * If the traversal of the source fails due an exception, that exception is reflected on the - * {@code next()} call of the returned iterator. - * The returned iterator will throw an UnsupportedOperationException - * for its remove() method. - * @param the source element type - * @param the intermediate aggregation type - * @param the resulting aggregation type - * @param source the source of Ts - * @param sum the function which takes the current intermediate value, - * the current source value and should produce a new intermediate value. - * for the first element of T, the U parameter will receive null - * @param divide the function which takes the last intermediate value and a total count of Ts seen and should return the final aggregation value. - * @return the new iterable - */ - public static Iterable aggregate( - final Iterable source, - final Func2 sum, - final Func2 divide) { - return new AggregateIterable(source, sum, divide); - } - /** - * Returns an iterable which contains true if all - * elements of the source iterable satisfy the predicate. - * The operator might return a false before fully iterating the source. - *

The returned iterator will throw an UnsupportedOperationException - * for its remove() method.

- * @param the source element type - * @param source the source of Ts - * @param predicate the predicate - * @return the new iterable - */ - public static Iterable all( - final Iterable source, - final Func1 predicate) { - return new AllIterable(source, predicate); - } - /** - * Tests if there is any element of the source that satisfies the given predicate function. - * @param the source element type - * @param source the source of Ts - * @param predicate the predicate tester function - * @return the new iterable - */ - - public static Iterable any( - final Iterable source, - final Func1 predicate) { - return any(filter(source, predicate)); - } - /** - * Determines if the given source has any elements at all. - *

The returned iterator will throw an UnsupportedOperationException - * for its remove() method.

- * @param the source element type, irrelevant here - * @param source the source of Ts - * @return the new iterable with a single true or false - */ - - public static Iterable any( - final Iterable source) { - return new AnyIterable(source); - } - /** - * Returns a pair of the maximum argument and value from the given sequence. - * @param the element type of the sequence - * @param the value type for the comparison, must be self comparable - * @param source the source sequence - * @param valueSelector the value selector function - * @return the pair of the first maximum element and value, null if the sequence was empty - */ - public static > Pair argAndMax( - Iterable source, - Func1 valueSelector) { - return argAndMax(source, valueSelector, IxHelperFunctions.comparator()); - } - /** - * Returns a pair of the maximum argument and value from the given sequence. - * @param the element type - * @param the value type - * @param source the source sequence of Ts - * @param valueSelector the selector to extract the value from T - * @param valueComparator the comparator to compare two values - * @return the first pair of max argument and value or null if the source sequence was empty - */ - public static Pair argAndMax( - Iterable source, - Func1 valueSelector, - Comparator valueComparator) { - T arg = null; - V max = null; - boolean hasElement = false; - Iterator it = source.iterator(); - try { - while (it.hasNext()) { - T item = it.next(); - V itemValue = valueSelector.call(item); - if (!hasElement || valueComparator.compare(max, itemValue) < 0) { - arg = item; - max = itemValue; - } - hasElement = true; - } - if (hasElement) { - return Pair.of(arg, max); - } - } finally { - unsubscribe(it); - } - return null; - } - /** - * Returns a pair of the maximum argument and value from the given sequence. - * @param the element type of the sequence - * @param the value type for the comparison, must be self comparable - * @param source the source sequence - * @param valueSelector the value selector function - * @return the pair of the first maximum element and value, null if the sequence was empty - */ - public static > Pair argAndMin( - Iterable source, - Func1 valueSelector) { - return argAndMin(source, valueSelector, IxHelperFunctions.comparator()); - } - /** - * Returns a pair of the minimum argument and value from the given sequence. - * @param the element type - * @param the value type - * @param source the source sequence of Ts - * @param valueSelector the selector to extract the value from T - * @param valueComparator the comparator to compare two values - * @return the first pair of min argument and value or null if the source sequence was empty - */ - public static Pair argAndMin( - Iterable source, - Func1 valueSelector, - final Comparator valueComparator) { - return argAndMax(source, valueSelector, new Comparator() { - @Override - public int compare(V o1, V o2) { - return valueComparator.compare(o2, o1); - } - }); - } - /** - * Returns an iterable which averages the source BigDecimal values. - *

The returned iterator will throw an UnsupportedOperationException - * for its remove() method.

- * @param source the source of BigDecimal values - * @return the new iterable - */ - - public static Iterable averageBigDecimal( - Iterable source) { - return aggregate(source, - new Func2() { - @Override - public BigDecimal call(BigDecimal param1, BigDecimal param2) { - return param1 != null ? param1.add(param2) : param2; - } - }, - new Func2() { - @Override - public BigDecimal call(BigDecimal param1, Integer param2) { - return param1.divide(new BigDecimal(param2), BigDecimal.ROUND_HALF_UP); - } - } - ); - } - /** - * Returns an iterable which averages the source BigInteger values. - *

The returned iterator will throw an UnsupportedOperationException - * for its remove() method.

- * @param source the source of BigInteger values - * @return the new iterable - */ - - public static Iterable averageBigInteger( - Iterable source) { - return aggregate(source, - new Func2() { - @Override - public BigInteger call(BigInteger param1, BigInteger param2) { - return param1 != null ? param1.add(param2) : param2; - } - }, - new Func2() { - @Override - public BigDecimal call(BigInteger param1, Integer param2) { - return new BigDecimal(param1).divide(new BigDecimal(param2), BigDecimal.ROUND_HALF_UP); - } - } - ); - } - /** - * Returns an iterable which averages the source Double values. - *

The returned iterator will throw an UnsupportedOperationException - * for its remove() method.

- * @param source the source of Double values - * @return the new iterable - */ - - public static Iterable averageDouble( - Iterable source) { - return aggregate(source, - new Func2() { - @Override - public Double call(Double param1, Double param2) { - return param1 != null ? param1 + param2 : param2.doubleValue(); - } - }, - new Func2() { - @Override - public Double call(Double param1, Integer param2) { - return param1 / param2; - } - } - ); - } - /** - * Returns an iterable which averages the source Float values. - *

The returned iterator will throw an UnsupportedOperationException - * for its remove() method.

- * @param source the source of Float values - * @return the new iterable - */ - - public static Iterable averageFloat( - Iterable source) { - return aggregate(source, - new Func2() { - @Override - public Float call(Float param1, Float param2) { - return param1 != null ? param1 + param2 : param2.floatValue(); - } - }, - new Func2() { - @Override - public Float call(Float param1, Integer param2) { - return param1 / param2; - } - } - ); - } - /** - * Returns an iterable which averages the source Integer values. - *

The returned iterator will throw an UnsupportedOperationException - * for its remove() method.

- * @param source the source of Integer values - * @return the new iterable - */ - - public static Iterable averageInt( - Iterable source) { - return aggregate(source, - new Func2() { - @Override - public Double call(Double param1, Integer param2) { - return param1 != null ? param1 + param2 : param2.doubleValue(); - } - }, - new Func2() { - @Override - public Double call(Double param1, Integer param2) { - return param1 / param2; - } - } - ); - } - /** - * Returns an iterable which averages the source Integer values. - * The returned iterator will throw an UnsupportedOperationException - * for its remove() method. - * @param source the source of Integer values - * @return the new iterable - */ - - public static Iterable averageLong( - Iterable source) { - return aggregate(source, - new Func2() { - @Override - public Double call(Double param1, Long param2) { - return param1 != null ? param1 + param2 : param2.doubleValue(); - } - }, - new Func2() { - @Override - public Double call(Double param1, Integer param2) { - return param1 / param2; - } - } - ); - } - /** - * Returns an iterable which buffers the source elements - * into bufferSize lists. - * FIXME what to do on empty source or last chunk? - *

The returned iterator will throw an UnsupportedOperationException - * for its remove() method.

- * @param the source element type - * @param source the source of Ts - * @param bufferSize the buffer size. - * @return the new iterable - */ - - public static Iterable> buffer( - final Iterable source, - final int bufferSize) { - if (bufferSize <= 0) { - throw new IllegalArgumentException("bufferSize <= 0"); - } - return new BufferIterable(source, bufferSize); - } - /** - * Concatenate the given iterable sources one - * after another in a way, that calling the second iterator() - * only happens when there is no more element in the first iterator. - *

The returned iterator forwards all remove() calls - * to the current source (e.g., you can remove the same elements from - * multiple collections with a single traversal on the concat result). - * @param the element type - * @param sources the list of iterables to concatenate - * @return a new iterable - */ - - public static Iterable concat( - final Iterable> sources) { - return new ConcatIterable(sources); - } - /** - * Concatenate the given iterable sources one - * after another in a way, that calling the second iterator() - * only happens when there is no more element in the first iterator. - *

The returned iterator forwards all remove() calls - * to the current source (first or next). - * @param the element type - * @param first the first iterable - * @param second the second iterable - * @return the new iterable - */ - - public static Iterable concat( - final Iterable first, - final Iterable second) { - List> list = new LinkedList>(); - list.add(first); - list.add(second); - return concat(list); - } - /** - * Returns an iterable which checks for the existence of the supplied - * value by comparing the elements of the source iterable using reference - * and equals(). The iterable then returns a single true or false. - * @param the source element type - * @param source the source - * @param value the value to check - * @return the new iterable - */ - - public static Iterable contains( - final Iterable source, final Object value) { - return any(source, new Func1() { - @Override - public Boolean call(T param1) { - return param1 == value || (param1 != null && param1.equals(value)); - } - }); - } - /** - * Counts the elements of the iterable source by using a 32 bit int. - *

The returned iterator will throw an UnsupportedOperationException - * for its remove() method.

- * @param the element type - * @param source the source iterable - * @return the new iterable - */ - - public static Iterable count( - final Iterable source) { - return new CountIterable(source); - } - /** - * Counts the elements of the iterable source by using a 64 bit long. - *

The returned iterator will throw an UnsupportedOperationException - * for its remove() method.

- * @param the element type - * @param source the source iterable - * @return the new iterable - */ - - public static Iterable countLong( - final Iterable source) { - return new LongCountIterable(source); - } - /** - * Defers the source iterable creation to registration time and - * calls the given func for the actual source. - * @param the element type - * @param func the function that returns an iterable. - * @return the new iterable - */ - - public static Iterable defer( - final Func0> func) { - return new DeferIterable(func); - } - /** - * Convert the source materialized elements into normal iterator behavior. - * The returned iterator will throw an UnsupportedOperationException for its remove() method. - *

The returned iterator will throw an UnsupportedOperationException - * for its remove() method.

- * @param the source element types - * @param source the source of T options - * @return the new iterable - */ - - public static Iterable dematerialize( - final Iterable> source) { - return new DematerializeIterable(source); - } - /** - * Returns an iterable which filters its elements based if they were ever seen before in - * the current iteration. - * Value equality is computed by reference equality and equals() - * @param the source element type - * @param source the source of Ts - * @return the new iterable - */ - - public static Iterable distinct( - final Iterable source) { - return distinct(source, IxHelperFunctions.identity(), IxHelperFunctions.identity()); - } - /** - * Returns an iterable which filters its elements by an unique key - * in a way that when multiple source items produce the same key, only - * the first one ever seen gets relayed further on. - * Key equality is computed by reference equality and equals() - * @param the source element type - * @param the key element type - * @param the output element type - * @param source the source of Ts - * @param keySelector the key selector for only-once filtering - * @param valueSelector the value select for the output of the first key cases - * @return the new iterable - */ - - public static Iterable distinct( - final Iterable source, - final Func1 keySelector, - final Func1 valueSelector) { - return map(filterIndexed(source, - new Func0>() { - @Override - public Func2 call() { - return new Func2() { - final Set memory = new HashSet(); - @Override - public Boolean call(Integer index, T param1) { - return memory.add(keySelector.call(param1)); - } - }; - } - }) - , new Func1() { - @Override - public V call(T param1) { - return valueSelector.call(param1); - } - }); - } - /** - * Creates an iterable which ensures that subsequent values of T are not equal (reference and equals). - * @param the element type - * @param source the source iterable - * @return the new iterable - */ - - public static Iterable distinctNext( - final Iterable source) { - return filterIndexed(source, - new Func0>() { - @Override - public Func2 call() { - return new Func2() { - /** Is this the first element? */ - boolean first = true; - /** The last seen element. */ - T last; - @Override - public Boolean call(Integer index, T param1) { - if (first) { - first = false; - last = param1; - return true; - } - if (last == param1 || (last != null && last.equals(param1))) { - last = param1; - return false; - } - last = param1; - return true; - } - }; - } - }); - } - /** - * Creates an iterable which ensures that subsequent values of - * T are not equal in respect to the extracted keys (reference and equals). - * @param the element type - * @param the key type - * @param source the source iterable - * @param keyExtractor the function to extract the keys which will be compared - * @return the new iterable - */ - - public static Iterable distinctNext( - final Iterable source, - final Func1 keyExtractor) { - return filterIndexed(source, - new Func0>() { - @Override - public Func2 call() { - return new Func2() { - /** Is this the first element? */ - boolean first = true; - /** The last seen element. */ - U last; - @Override - public Boolean call(Integer index, T param1) { - U key = keyExtractor.call(param1); - if (first) { - first = false; - last = key; - return true; - } - if (last == key || (last != null && last.equals(key))) { - last = key; - return false; - } - last = key; - return true; - } - }; - } - }); - } - /** - * Construct a new iterable which will invoke the specified action - * before the source value gets relayed through it. - * Can be used to inject side-effects before returning a value. - *

The returned iterator forwards all remove() calls - * to the source.

- * @param the returned element type - * @param source the source iterable - * @param action the action to invoke before each next() is returned. - * @return the new iterable - */ - - public static Iterable doOnNext( - final Iterable source, - final Action1 action) { - return new DoOnNextIterable(source, action); - } - /** - * Returns an iterable which reiterates over and over again on source - * as long as the gate is true. The gate function is checked only - * when a pass over the source stream was completed. - * Note that using this operator on an empty iterable may result - * in a direct infinite loop in hasNext() or next() calls depending on the gate function. - *

The returned iterator forwards all remove() calls - * to the source.

- * @param the source element type - * @param source the source of Ts - * @param gate the gate function to stop the repeat - * @return the new iterable - */ - - public static Iterable doWhile( - final Iterable source, - final Func0 gate) { - return new DoWhileIterable(source, gate); - } - /** - * Determines whether two iterables contain equal elements in the same - * order. More specifically, this method returns {@code true} if - * {@code iterable1} and {@code iterable2} contain the same number of - * elements and every element of {@code iterable1} is equal to the - * corresponding element of {@code iterable2}. - * @param iterable1 the first iterable - * @param iterable2 the second iterable - * @return true if both iterables are either empty or contain the same number and equal items - */ - public static boolean elementsEqual(Iterable iterable1, - Iterable iterable2) { - Iterator iterator1 = iterable1.iterator(); - Iterator iterator2 = iterable2.iterator(); - return elementsEqual(iterator1, iterator2); - } - /** - * Compares two iterators wether they contain the same element in terms of numbers - * and nullsafe Object.equals(). - * @param iterator1 the first iterator - * @param iterator2 the second interator - * @return true if they are equal - */ - public static boolean elementsEqual( - Iterator iterator1, - Iterator iterator2) { - try { - while (iterator1.hasNext()) { - if (!iterator2.hasNext()) { - return false; - } - Object o1 = iterator1.next(); - Object o2 = iterator2.next(); - if (!equal(o1, o2)) { - return false; - } - } - return !iterator2.hasNext(); - } finally { - unsubscribe(iterator1); - unsubscribe(iterator2); - } - } - /** - * Returns an empty iterable which will not produce elements. - * Its hasNext() returns always false, - * next() throws a NoSuchElementException - * and remove() throws an IllegalStateException. - * Note that the Collections.emptyIterable() static method is introduced by Java 7. - * @param the element type, irrelevant - * @return the iterable - */ - @SuppressWarnings("unchecked") - - public static Iterable empty() { - return (Iterable)EMPTY_ITERABLE; - } - /** - * Creates an iterable sequence which returns all elements from source - * followed by the supplied value as last. - *

The returned iterable forwards all {@code remove()} - * methods to the source iterable, except the last element where it - * throws UnsupportedOperationException.

- * @param the element type - * @param source the source sequence - * @param value the value to append - * @return the new iterable - */ - - public static Iterable endWith( - final Iterable source, T value) { - return concat(source, just(value)); - } - /** - * Compare two object in a null-safe manner. - * @param a the first object - * @param b the second object - * @return true if both are null or equal according to Object.equals - */ - private static boolean equal(Object a, Object b) { - return (a == b) || ((a != null) && a.equals(b)); - } - - /** - * Creates an onError notification. - * @param the value type - * @param t the throwable - * @return the notification - */ - static Notification err(Throwable t) { - return Notification.createOnError(t); - } - /** - * Returns an iterable which executes the given action after - * the stream completes. - *

The returned iterator forwards all remove() calls - * to the source.

- * @param the element type - * @param source the source of Ts - * @param action the action to invoke - * @return the new iterable - */ - - public static Iterable doOnCompleted( - final Iterable source, - final Action0 action) { - return new DoOnCompletedIterable(action, source); - } - /** - * Returns the first element from the iterable sequence or - * throws a NoSuchElementException. - * @param the value type - * @param src the source sequence - * @return the first element - */ - public static T first(Iterable src) { - Iterator itor = src.iterator(); - try { - return itor.next(); - } finally { - unsubscribe(itor); - } - } - - /** - * Returns the first element from the sequence or the default - * value if this sequence is empty - * @param the value type - * @param src the source sequence - * @param defaultValue the default value to return - * @return the first or default value - * @since 0.91.2 - */ - public static T firstOrDefault(Iterable src, T defaultValue) { - Iterator itor = src.iterator(); - try { - if (itor.hasNext()) { - return itor.next(); - } - return defaultValue; - } finally { - Interactive.unsubscribe(itor); - } - } - - - /** - * Returns an iterable which runs the source iterable and - * returns elements from the iterable returned by the function call. - * The difference from flatMap is that the {@code Iterable<U>}s are - * created before their concatenation starts. - * @param the source element type - * @param the output element type - * @param source the source - * @param selector the result selector - * @return the new iterable - */ - - public static Iterable flatMapAll( - final Iterable source, - final Func1> selector) { - return concat(map(source, selector)); - } - /** - * Iterate over the source and submit each value to the - * given action. Basically, a for-each loop with pluggable - * action. - * This method is useful when the concrete values from the iterator - * are not needed but the iteration itself implies some side effects. - * @param the element type of the iterable - * @param source the iterable - * @param action the action to invoke on with element - */ - public static void forEach( - final Iterable source, - Action1 action) { - Iterator iter = source.iterator(); - try { - while (iter.hasNext()) { - T t = iter.next(); - action.call(t); - } - } finally { - unsubscribe(iter); - } - } - /** - * A generator function which returns Ts based on the termination condition and the way it computes the next values. - * This is equivalent to: - *

-     * T value = seed;
-     * while (predicate(value)) {
-     *     yield value;
-     *     value = next(value);
-     * }
-     * 
- *

The returned iterator will throw an UnsupportedOperationException - * for its remove() method.

- * @param the element type - * @param seed the initial value - * @param predicate the predicate to terminate the process - * @param next the function that computes the next value. - * @return the new iterable - */ - - public static Iterable generate( - final T seed, - final Func1 predicate, - final Func1 next) { - return new GenerateIterable(seed, next, predicate); - } - /** - * A generator function which returns Ts based on the termination condition and the way it computes the next values, - * but the first T to be returned is preceded by an initialDelay amount of wait and each - * subsequent element is then generated after betweenDelay sleep. - * The sleeping is blocking the current thread which invokes the hasNext()/next() methods. - * This is equivalent to: - *

-     * T value = seed;
-     * sleep(initialDelay);
-     * if (predicate(value)) {
-     *     yield value;
-     * }
-     * value = next(value);
-     * sleep(betweenDelay);
-     * while (predicate(value)) {
-     *     yield value;
-     *     value = next(value);
-     *     sleep(betweenDelay);
-     * }
-     * 
- *

The returned iterator will throw an UnsupportedOperationException - * for its remove() method.

- * @param the element type - * @param seed the initial value - * @param predicate the predicate to terminate the process - * @param next the function that computes the next value. - * @param initialDelay the initial delay - * @param betweenDelay the between delay - * @param unit the time unit for initialDelay and betweenDelay - * @return the new iterable - */ - - public static Iterable generate( - final T seed, - final Func1 predicate, - final Func1 next, - final long initialDelay, - final long betweenDelay, - final TimeUnit unit) { - return new GenerateIterableTimed(predicate, next, seed, initialDelay, - betweenDelay, unit); - - } - /** - * Creates an iterable which traverses the source iterable, - * and based on the key selector, groups values of T into GroupedIterables, - * which can be iterated over later on. - * The equivalence of the keys are determined via reference - * equality and equals() equality. - *

The returned iterator will throw an UnsupportedOperationException - * for its remove() method.

- * @param the source element type - * @param the result group keys - * @param source the source of Ts - * @param keySelector the key selector - * @return the new iterable - */ - - public static Iterable> groupBy( - final Iterable source, - final Func1 keySelector - ) { - return groupBy(source, keySelector, IxHelperFunctions.identity()); - } - /** - * Creates an iterable which traverses the source iterable, - * and based on the key selector, groups values extracted by valueSelector into GroupedIterables, - * which can be iterated over later on. - * The equivalence of the keys are determined via reference - * equality and equals() equality. - *

The returned iterator will throw an UnsupportedOperationException - * for its remove() method.

- * @param the source element type - * @param the result group element type - * @param the result group keys - * @param source the source of Ts - * @param keySelector the key selector - * @param valueSelector the value selector - * @return the new iterable - */ - - public static Iterable> groupBy( - final Iterable source, - final Func1 keySelector, - final Func1 valueSelector) { - return distinct(new Iterable>() { - @Override - public Iterator> iterator() { - final Map> groups = new LinkedHashMap>(); - final Iterator it = source.iterator(); - return new Iterator>() { - Iterator> groupIt; - @Override - public boolean hasNext() { - return it.hasNext() || (groupIt != null && groupIt.hasNext()); - } - - @Override - public GroupedIterable next() { - if (hasNext()) { - if (groupIt == null) { - try { - while (it.hasNext()) { - T t = it.next(); - V v = keySelector.call(t); - U u = valueSelector.call(t); - GroupedIterable g = groups.get(v); - if (g == null) { - g = new GroupedIterable(v); - groups.put(v, g); - } - g.add(u); - } - } finally { - unsubscribe(it); - } - groupIt = groups.values().iterator(); - } - return groupIt.next(); - } - throw new NoSuchElementException(); - } - - @Override - public void remove() { - throw new UnsupportedOperationException(); - } - - }; - } - }, new Func1, V>() { - @Override - public V call(GroupedIterable param1) { - return param1.getKey(); - } - - }, IxHelperFunctions.>identity()); - } - /** - * Returns an iterable which invokes the given next - * action for each element and the finish action when - * the source completes. - * @param the source element type - * @param source the source of Ts - * @param next the action to invoke on each element - * @param finish the action to invoke after the last element - * @return the new iterable - */ - - public static Iterable doOnEach( - final Iterable source, - Action1 next, - Action0 finish) { - return doOnEach(source, next, Actions.empty(), finish); - } - /** - * Returns an iterable which invokes the given next - * action for each element and error when an exception is thrown. - * @param the source element type - * @param source the source of Ts - * @param next the action to invoke on each element - * @param error the error action to invoke for an error - * @return the new iterable - */ - - public static Iterable doOnEach( - final Iterable source, - final Action1 next, - final Action1 error) { - return doOnEach(source, next, error, Actions.empty()); - } - /** - * Returns an iterable which invokes the given next - * action for each element and the finish action when - * the source completes and error when an exception is thrown. - *

The returned iterator forwards all remove() calls - * to the source.

- * @param the source element type - * @param source the source of Ts - * @param next the action to invoke on each element - * @param error the error action to invoke for an error - * @param finish the action to invoke after the last element - * @return the new iterable - */ - - public static Iterable doOnEach( - final Iterable source, - final Action1 next, - final Action1 error, - final Action0 finish) { - return new DoOnEachIterable(error, finish, source); - } - /** - * Returns a single true if the target iterable is empty. - * @param source source iterable with any type - * @return the new iterable - */ - - public static Iterable isEmpty( - final Iterable source) { - return map(any(source), IxHelperFunctions.negate()); - } - /** - * Concatenates the source strings one after another and uses the given separator. - *

The returned iterator forwards all remove() calls - * to the source.

- * @param source the source - * @param separator the separator to use - * @return the new iterable - */ - - public static Iterable join( - final Iterable source, - final String separator) { - return aggregate(source, - new Func2() { - @Override - public StringBuilder call(StringBuilder param1, Object param2) { - if (param1 == null) { - param1 = new StringBuilder(); - } else { - param1.append(separator); - } - param1.append(param2); - return param1; - } - }, - new Func2() { - @Override - public String call(StringBuilder param1, Integer param2) { - return param1.toString(); - } - } - ); - } - /** - * Returns the last element of the iterable or throws a NoSuchElementException if the iterable is empty. - * @param the source element type - * @param source the source of Ts - * @return the last value - */ - public static T last( - final Iterable source) { - Iterator it = source.iterator(); - try { - if (it.hasNext()) { - T t; - - do { - t = it.next(); - } while (it.hasNext()); - - return t; - } - } finally { - unsubscribe(it); - } - throw new NoSuchElementException(); - } - - /** - * Returns the last element of this sequence or the default value if - * this sequence is empty. - * @param the source element type - * @param source the source of Ts - * @param defaultValue the default value to return if this sequence is empty - * @return the last value - */ - public static T lastOrDefault( - final Iterable source, T defaultValue) { - Iterator it = source.iterator(); - try { - if (it.hasNext()) { - T t; - - do { - t = it.next(); - } while (it.hasNext()); - - return t; - } - return defaultValue; - } finally { - unsubscribe(it); - } - } - /** - * Creates an iterable which is a transforms the source - * elements by using the selector function. - * The function receives the current index and the current element. - * @param the source element type - * @param the output element type - * @param source the source iterable - * @param selector the selector function - * @return the new iterable - */ - - public static Iterable map( - final Iterable source, - final Func1 selector) { - return mapIndexed(source, new Func2() { - @Override - public U call(Integer param1, T param2) { - return selector.call(param2); - } - }); - } - /** - * Creates an iterable which is a transforms the source - * elements by using the selector function. - * The function receives the current index and the current element. - *

The returned iterator forwards all remove() calls - * to the source.

- * @param the source element type - * @param the output element type - * @param source the source iterable - * @param selector the selector function - * @return the new iterable - */ - - public static Iterable mapIndexed( - final Iterable source, - final Func2 selector) { - return new MapIndexedIterable(source, selector); - } - /** - * Transforms the sequence of the source iterable into an option sequence of - * Notification.some(), Notification.none() and Notification.error() values, depending on - * what the source's hasNext() and next() produces. - * The returned iterator will throw an UnsupportedOperationException for its remove() method. - *

The returned iterator will throw an UnsupportedOperationException - * for its remove() method.

- * @param the source element type - * @param source the source of at least Ts. - * @return the new iterable - */ - - public static Iterable> materialize( - final Iterable source) { - return new MaterializeIterable(source); - } - /** - * Returns the maximum value of the given iterable source. - * @param the element type, which must be self comparable - * @param source the source elements - * @return the new iterable - */ - - public static > Iterable max( - final Iterable source) { - return aggregate(source, IxHelperFunctions.max(), - IxHelperFunctions.identityFirst()); - } - /** - * Returns the maximum value of the given iterable source in respect to the supplied comparator. - * @param the element type, which must be self comparable - * @param source the source elements - * @param comparator the comparator to use - * @return the new iterable - */ - - public static Iterable max( - final Iterable source, - final Comparator comparator) { - return aggregate(source, IxHelperFunctions.max(comparator), IxHelperFunctions.identityFirst()); - } - /** - * Returns an iterator which will produce a single List of the maximum values encountered - * in the source stream based on the supplied key selector. - * @param the source element type, which must be self comparable - * @param source the source of Ts - * @return the new iterable - */ - - public static > Iterable> maxBy( - final Iterable source) { - return minMax(source, IxHelperFunctions.identity(), IxHelperFunctions.comparator(), true); - } - /** - * Returns an iterator which will produce a single List of the maximum values encountered - * in the source stream based on the supplied comparator. - * @param the source element type - * @param source the source of Ts - * @param comparator the key comparator - * @return the new iterable - */ - - public static Iterable> maxBy( - final Iterable source, - final Comparator comparator) { - return minMax(source, IxHelperFunctions.identity(), comparator, true); - } - /** - * Returns an iterator which will produce a single List of the maximum values encountered - * in the source stream based on the supplied key selector. - * @param the source element type - * @param the key type, which must be self-comparable - * @param source the source of Ts - * @param keySelector the selector for keys - * @return the new iterable - */ - - public static > Iterable> maxBy( - final Iterable source, - final Func1 keySelector) { - return minMax(source, keySelector, IxHelperFunctions.comparator(), true); - } - /** - * Returns an iterator which will produce a single List of the minimum values encountered - * in the source stream based on the supplied key selector and comparator. - * @param the source element type - * @param the key type - * @param source the source of Ts - * @param keySelector the selector for keys - * @param keyComparator the key comparator - * @return the new iterable - */ - - public static Iterable> maxBy( - final Iterable source, - final Func1 keySelector, - final Comparator keyComparator) { - return minMax(source, keySelector, keyComparator, true); - } - /** - * Enumerates the source iterable once and caches its results. - * Any iterator party will basically drain this cache, e.g., - * reiterating over this iterable will produce no results. - * Note: the name is not a misspelling, see Memoization. - * FIXME not sure about the buffer sizes. - *

The returned iterator will throw an UnsupportedOperationException - * for its remove() method.

- * @param the source element type - * @param source the source of Ts - * @param bufferSize the size of the buffering - * @return the new iterable - */ - - public static Iterable memoize( - final Iterable source, - final int bufferSize) { - if (bufferSize < 0) { - throw new IllegalArgumentException("bufferSize < 0"); - } - return new MemoizeIterable(source, bufferSize); - } - /** - * The returned iterable ensures that the source iterable is only traversed once, regardless of - * how many iterator attaches to it and each iterator see only the values. - * Note: the name is not a misspelling, see Memoization. - *

The returned iterator will throw an UnsupportedOperationException - * for its remove() method.

- * @param the source element type - * @param source the source of Ts - * @return the new iterable - */ - - public static Iterable memoizeAll( - final Iterable source) { - final Iterator it = source.iterator(); - final LinkedBuffer buffer = new LinkedBuffer(); - return new MemoizeAllIterable(it, buffer); - } - /** - * Merges a bunch of iterable streams where each of the iterable will run by - * a scheduler and their events are merged together in a single stream. - * The returned iterator throws an UnsupportedOperationException in its remove() method. - * @param the element type - * @param sources the iterable of source iterables. - * @return the new iterable - */ - - public static Iterable merge( - final Iterable> sources) { - return merge(sources, scheduler()); - } - /** - * Merges a bunch of iterable streams where each of the iterable will run by - * a scheduler and their events are merged together in a single stream. - * The returned iterator throws an UnsupportedOperationException in its remove() method. - *

The returned iterator will throw an UnsupportedOperationException - * for its remove() method.

- * @param the element type - * @param sources the iterable of source iterables. - * @param scheduler the scheduler for running each inner iterable in parallel - * @return the new iterable - */ - - public static Iterable merge( - final Iterable> sources, - final Scheduler scheduler) { - return new MergeIterable(scheduler, sources); - } - /** - * Merges two iterable streams. - *

The returned iterator will throw an UnsupportedOperationException - * for its remove() method.

- * @param the element type - * @param first the first iterable - * @param second the second iterable - * @return the resulting stream of Ts - */ - - public static Iterable merge( - final Iterable first, - final Iterable second) { - List> list = new ArrayList>(2); - list.add(first); - list.add(second); - return merge(list); - } - /** - * Returns the minimum value of the given iterable source. - *

The returned iterator will throw an UnsupportedOperationException - * for its remove() method.

- * @param the element type, which must be self comparable - * @param source the source elements - * @return the new iterable - */ - - public static > Iterable min( - final Iterable source) { - return aggregate(source, IxHelperFunctions.min(), IxHelperFunctions.identityFirst()); - } - /** - * Returns the minimum value of the given iterable source in respect to the supplied comparator. - *

The returned iterator will throw an UnsupportedOperationException - * for its remove() method.

- * @param the element type, which must be self comparable - * @param source the source elements - * @param comparator the comparator to use - * @return the new iterable - */ - - public static Iterable min( - final Iterable source, - final Comparator comparator) { - return aggregate(source, IxHelperFunctions.min(comparator), IxHelperFunctions.identityFirst()); - } - /** - * Returns an iterator which will produce a single List of the minimum values encountered - * in the source stream based on the supplied key selector. - *

The returned iterator will throw an UnsupportedOperationException - * for its remove() method.

- * @param the source element type, which must be self comparable - * @param source the source of Ts - * @return the new iterable - */ - - public static > Iterable> minBy( - final Iterable source) { - return minMax(source, IxHelperFunctions.identity(), IxHelperFunctions.comparator(), false); - } - /** - * Returns an iterator which will produce a single List of the minimum values encountered - * in the source stream based on the supplied comparator. - * @param the source element type - * @param source the source of Ts - * @param comparator the key comparator - * @return the new iterable - */ - - public static Iterable> minBy( - final Iterable source, - final Comparator comparator) { - return minMax(source, IxHelperFunctions.identity(), comparator, false); - } - /** - * Returns an iterator which will produce a single List of the minimum values encountered - * in the source stream based on the supplied key selector. - *

The returned iterator will throw an UnsupportedOperationException - * for its remove() method.

- * @param the source element type - * @param the key type, which must be self-comparable - * @param source the source of Ts - * @param keySelector the selector for keys - * @return the new iterable - */ - - public static > Iterable> minBy( - final Iterable source, - final Func1 keySelector) { - return minMax(source, keySelector, IxHelperFunctions.comparator(), false); - } - /** - * Returns an iterator which will produce a single List of the minimum values encountered - * in the source stream based on the supplied key selector and comparator. - *

The returned iterator will throw an UnsupportedOperationException - * for its remove() method.

- * @param the source element type - * @param the key type - * @param source the source of Ts - * @param keySelector the selector for keys - * @param keyComparator the key comparator - * @return the new iterable - */ - - public static Iterable> minBy( - final Iterable source, - final Func1 keySelector, - final Comparator keyComparator) { - return minMax(source, keySelector, keyComparator, false); - } - /** - * Returns an iterator which will produce a single List of the minimum values encountered - * in the source stream based on the supplied key selector and comparator. - *

The returned iterator will throw an UnsupportedOperationException - * for its remove() method.

- * @param the source element type - * @param the key type - * @param source the source of Ts - * @param keySelector the selector for keys - * @param keyComparator the key comparator - * @param max should the computation return the minimums or the maximums - * @return the new iterable - */ - - static Iterable> minMax( - final Iterable source, - final Func1 keySelector, - final Comparator keyComparator, - final boolean max) { - return new MinMaxIterable(keySelector, source, max, keyComparator); - } - /** - * Wraps the given source sequence into a CloseableIterable instance - * where the inner CloseableIterator.close() method calls the supplied action. - * @param the element type - * @param src the source sequence - * @param close the close action. - * @return the new closeable iterable - */ - public static CloseableIterable newCloseableIterable( - final Iterable src, - final Action0 close - ) { - return new CloseableIterable() { - @Override - public CloseableIterator iterator() { - return newCloseableIterator(src.iterator(), close); - } - }; - } - /** - * Wraps the given source sequence into a CloseableIterable instance - * where the inner CloseableIterator.close() method calls the supplied action. - * @param the element type - * @param src the source sequence - * @param close the close action. - * @return the new closeable iterable - */ - - public static CloseableIterable newCloseableIterable( - final Iterable src, - final Action1> close - ) { - return new CloseableIterable() { - @Override - public CloseableIterator iterator() { - return newCloseableIterator(src.iterator(), close); - } - }; - } - /** - * Wraps the given source sequence into a CloseableIterable instance - * where the inner CloseableIterator.close() method calls the supplied closeable object. - * @param the element type - * @param src the source sequence - * @param close the closeable object. - * @return the new closeable iterable - */ - - public static CloseableIterable newCloseableIterable( - final Iterable src, - final Closeable close - ) { - return new CloseableIterable() { - @Override - public CloseableIterator iterator() { - return newCloseableIterator(src.iterator(), close); - } - }; - } - /** - * Wraps the supplied iterator into a CloseableIterator which calls the supplied - * close action. - * @param the element type - * @param src the source iterator - * @param close the close action - * @return the new closeable iterator - */ - - public static CloseableIterator newCloseableIterator( - final Iterator src, - final Action0 close - ) { - return new CloseableIterator() { - final AtomicBoolean once = new AtomicBoolean(); - @Override - public boolean hasNext() { - return src.hasNext(); - } - - @Override - public boolean isUnsubscribed() { - return once.get(); - } - - @Override - public T next() { - return src.next(); - } - - @Override - public void remove() { - src.remove(); - } - @Override - public void unsubscribe() { - if (once.compareAndSet(false, true)) { - close.call(); - } - } - }; - } - /** - * Wraps the supplied iterator into a CloseableIterator which calls the supplied - * close action with the given source iterator object. - * @param the element type - * @param src the source iterator - * @param close the close action - * @return the new closeable iterator - */ - - public static CloseableIterator newCloseableIterator( - final Iterator src, - final Action1> close - ) { - return new CloseableIterator() { - final AtomicBoolean once = new AtomicBoolean(); - @Override - public boolean hasNext() { - return src.hasNext(); - } - - @Override - public boolean isUnsubscribed() { - return once.get(); - } - - @Override - public T next() { - return src.next(); - } - - @Override - public void remove() { - src.remove(); - } - @Override - public void unsubscribe() { - if (once.compareAndSet(false, true)) { - close.call(src); - } - } - }; - } - /** - * Wraps the supplied iterator into a CloseableIterator which calls the supplied - * closeable instance. - * @param the element type - * @param src the source iterator - * @param close the closeable instance - * @return the new closeable iterator - */ - public static CloseableIterator newCloseableIterator( - final Iterator src, - final Closeable close - ) { - return new CloseableIterator() { - final AtomicBoolean once = new AtomicBoolean(); - @Override - public boolean hasNext() { - return src.hasNext(); - } - - @Override - public boolean isUnsubscribed() { - return once.get(); - } - - @Override - public T next() { - return src.next(); - } - - @Override - public void remove() { - src.remove(); - } - @Override - public void unsubscribe() { - if (once.compareAndSet(false, true)) { - try { - close.close(); - } catch (IOException ex) { - //ignored - } - } - } - - }; - } - /** - * Creates a new iterable sequence by wrapping the given function to - * provide the iterator. - * @param the element type - * @param the iterator type - * @param body the body function returning an iterator - * @return the iterable sequence - */ - public static > Iterable newIterable( - final Func0 body) { - return new Iterable() { - @Override - public Iterator iterator() { - return body.call(); - } - }; - } - /** - * A functional way of creating a new iterator from the supplied - * hasNext and next callbacks. - *

The returned iterator throws a UnsupportedOperationException - * in its remove method.

- * @param the element type - * @param hasNext function that returns true if more elements are available. - * @param next function that returns the next element - * @return the created iterator - */ - public static Iterator newIterator( - final Func0 hasNext, - final Func0 next) { - return new Iterator() { - @Override - public boolean hasNext() { - return hasNext.call(); - } - @Override - public T next() { - return next.call(); - } - @Override - public void remove() { - throw new UnsupportedOperationException(); - } - }; - } - /** - * Constructs an iterator instance by wrapping the supplied functions - * into the same-named iterator methods. - * @param the element type - * @param hasNext function that returns true if more elements are available. - * @param next function that returns the next element - * @param remove function to remove the current element - * @return the created iterator - */ - public static Iterator newIterator( - final Func0 hasNext, - final Func0 next, - final Action0 remove - ) { - return new Iterator() { - @Override - public boolean hasNext() { - return hasNext(); - } - @Override - public T next() { - return next.call(); - } - @Override - public void remove() { - remove.call(); - } - }; - } - /** - * Creates an onCompleted notification. - * @param the value type - * @return the notification - */ - static Notification none() { - return Notification.createOnCompleted(); - } - /** - * Casts the source iterable into a different type by using a type token. - * If the source contains a wrong element, the next() - * will throw a ClassCastException. - *

The returned iterator forwards all remove() calls - * to the source.

- * @param the result element type - * @param source the arbitrary source - * @param token the type token - * @return the new iterable - */ - - public static Iterable ofType( - final Iterable source, - final Class token) { - return new CastIterable(source, token); - } - /** - * Creates an iterable which if iterates over the source and encounters an exception, - * the iteration is continued on the new iterable returned by the handler function. - *

The returned iterator forwards all remove() calls - * to the source.

- * @param the element type - * @param source the source iterable. - * @param handler the exception handler. - * @return the new iterable - */ - - public static Iterable onErrorResumeNext( - final Iterable source, - final Func1> handler) { - return new OnErrorResumeNextIterable(source, handler); - } - /** - * Creates an iterable which if iterates over the source and encounters an exception, it simply stops the iteration, consuming the exception. - * @param the element type - * @param source the source iterable. - * @return the new iterable - */ - - public static Iterable onErrorTerminate( - final Iterable source) { - Iterable e = empty(); - return onErrorResumeNext(source, IxHelperFunctions.constant(e)); - } - /** - * Returns an iterable which traverses the entire - * source iterable and creates an ordered list - * of elements. Once the source iterator completes, - * the elements are streamed to the output. - * @param the source element type, must be self comparable - * @param source the source of Ts - * @return the new iterable - */ - - public static > Iterable orderBy( - final Iterable source - ) { - return orderBy(source, IxHelperFunctions.identity(), IxHelperFunctions.comparator()); - } - /** - * Returns an iterable which traverses the entire - * source iterable and creates an ordered list - * of elements. Once the source iterator completes, - * the elements are streamed to the output. - * @param the source element type, must be self comparable - * @param source the source of Ts - * @param comparator the value comparator - * @return the new iterable - */ - - public static Iterable orderBy( - final Iterable source, - final Comparator comparator - ) { - return orderBy(source, IxHelperFunctions.identity(), comparator); - } - /** - * Returns an iterable which traverses the entire - * source iterable and creates an ordered list - * of elements. Once the source iterator completes, - * the elements are streamed to the output. - * @param the source element type - * @param the key type for the ordering, must be self comparable - * @param source the source of Ts - * @param keySelector the key selector for comparison - * @return the new iterable - */ - - public static > Iterable orderBy( - final Iterable source, - final Func1 keySelector - ) { - return orderBy(source, keySelector, IxHelperFunctions.comparator()); - } - /** - * Returns an iterable which traverses the entire - * source iterable and creates an ordered list - * of elements. Once the source iterator completes, - * the elements are streamed to the output. - * @param the source element type - * @param the key type for the ordering - * @param source the source of Ts - * @param keySelector the key selector for comparison - * @param keyComparator the key comparator function - * @return the new iterable - */ - - public static Iterable orderBy( - final Iterable source, - final Func1 keySelector, - final Comparator keyComparator - ) { - return new OrderByIterable(source, keyComparator, keySelector); - } - /** - * Creates an observer with debugging purposes. - * It prints the submitted values to STDOUT separated by commas and line-broken by 80 characters, the exceptions to STDERR - * and prints an empty newline when it receives a finish(). - * @param the value type - * @return the observer - */ - - public static Action1 print() { - return print(", ", 80); - } - /** - * Creates an observer with debugging purposes. - * It prints the submitted values to STDOUT, the exceptions to STDERR - * and prints an empty newline when it receives a finish(). - * @param the value type - * @param separator the separator to use between subsequent values - * @param maxLineLength how many characters to print into each line - * @return the observer - */ - - public static Action1 print(final String separator, final int maxLineLength) { - return new PrintAction1(separator, maxLineLength); - } - /** - * Creates an action for debugging purposes. - * It prints the submitted values to STDOUT with a line break. - * @param the value type - * @return the observer - */ - - public static Action1 println() { - return new Action1() { - @Override - public void call(T value) { - System.out.println(value); - } - }; - } - /** - * Creates an action for debugging purposes. - * It prints the submitted values to STDOUT with a line break. - * @param the value type - * @param prefix the prefix to use when printing - * @return the action - */ - - public static Action1 println(final String prefix) { - return new Action1() { - @Override - public void call(T value) { - System.out.print(prefix); - System.out.println(value); - } - }; - } - /** - * Applies the func function for a shared instance of the source, - * e.g., func.call(share(source)). - * @param the source element type - * @param the return types - * @param source the source of Ts - * @param func invoke the function on the buffering iterable and return an iterator over it. - * @return the new iterable - */ - - public static Iterable prune( - final Iterable source, - final Func1, ? extends Iterable> func) { - return func.call(share(source)); - } - /** - * The returned iterable ensures that the source iterable is only traversed once, regardless of - * how many iterator attaches to it and each iterator see only the same cached values. - *

The returned iterator will throw an UnsupportedOperationException - * for remove() method of its first element, then it might throw for any - * subsequent element, depending on the source iterable.

- * @param the source element type - * @param the return types - * @param source the source of Ts - * @param func invoke the function on the buffering iterable and return an iterator over it. - * @param initial the initial value to append to the output stream - * @return the new iterable - */ - @SuppressWarnings("unchecked") - - public static Iterable publish( - final Iterable source, - final Func1, ? extends Iterable> func, - final U initial) { - return startWith(func.call(memoizeAll(source)), initial); - } - /** - * The returned iterable ensures that the source iterable is only traversed once, regardless of - * how many iterator attaches to it and each iterator see only the values. - *

The returned iterator will throw an UnsupportedOperationException - * for its remove() method.

- * @param the source element type - * @param the return types - * @param source the source of Ts - * @param func invoke the function on the buffering iterable and return an iterator over it. - * @return the new iterable - * TODO check - */ - - public static Iterable publish( - final Iterable source, - final Func1, ? extends Iterable> func) { - return func.call(memoizeAll(source)); - } - /** - * Creates an integer iterator which returns numbers from the start position in the count size. - *

The returned iterator will throw an UnsupportedOperationException - * for its remove() method.

- * @param start the starting value. - * @param count the number of elements to return, negative count means counting down from the start. - * @return the iterator. - */ - - public static Iterable range(final int start, final int count) { - return new RangeIterable(start, count); - } - /** - * Creates an long iterator which returns numbers from the start position in the count size. - *

The returned iterator will throw an UnsupportedOperationException - * for its remove() method.

- * @param start the starting value. - * @param count the number of elements to return, negative count means counting down from the start. - * @return the iterator. - */ - - public static Iterable range(final long start, final long count) { - return new LongRangeIterable(start, count); - } - /** - * Relays the source iterable's values until the gate returns false. - * @param the source element type - * @param source the source of Ts - * @param gate the gate to stop the relaying - * @return the new iterable - */ - - public static Iterable relayWhile( - final Iterable source, - final Func0 gate) { - return filterIndexed(source, new Func0>() { - @Override - public Func2 call() { - return new Func2() { - /** The activity checker which turns to false once the gate returns false. */ - boolean active = true; - @Override - public Boolean call(Integer param1, T param2) { - active &= gate.call(); - return active; - } - }; - } - }); - } - /** - * Creates an iterable sequence which returns the given value indefinitely. - *

(E.g., having the hasNext() always return true and the next() always return the value.

- *

The returned iterable does not support the {@code remove()} method.

- * @param the value type - * @param value the value to repeat - * @return the iterable - */ - public static Iterable repeat(final T value) { - return new RepeatIterable(value); - } - /** - * Returns an iterable which repeats the given single value the specified number of times. - *

The returned iterable does not support the {@code remove()} method.

- * @param the value type - * @param value the value to repeat - * @param count the repeat amount - * @return the iterable - */ - public static Iterable repeat(final T value, final int count) { - return new RepeatCountIterable(count, value); - } - /** - * The returned iterable ensures that the source iterable is only traversed once, regardless of - * how many iterator attaches to it and each iterator may only see one source element. - *

The returned iterator will throw an UnsupportedOperationException - * for its remove() method.

- * @param the source element type - * @param the return types - * @param source the source of Ts - * @param func invoke the function on the buffering iterable and return an iterator over it. - * @return the new iterable - */ - - public static Iterable replay( - final Iterable source, - final Func1, ? extends Iterable> func) { - return func.call(memoize(source, 0)); - } - /** - * The returned iterable ensures that the source iterable is only traversed once, regardless of - * how many iterator attaches to it and each iterator see only the some cached values. - *

The returned iterator will throw an UnsupportedOperationException - * for its remove() method.

- * @param the source element type - * @param the return types - * @param source the source of Ts - * @param func invoke the function on the buffering iterable and return an iterator over it. - * @param bufferSize the buffer size - * @return the new iterable - */ - - public static Iterable replay( - final Iterable source, - final Func1, ? extends Iterable> func, - final int bufferSize) { - return func.call(memoize(source, bufferSize)); - } - /** - * Creates an iterable which resumes with the next iterable from the sources when one throws an exception or completes normally. - *

The returned iterator forwards all remove() calls - * to the source.

- * @param the source element type - * @param sources the list of sources to try one after another - * @return the new iterable - */ - - public static Iterable onErrorResumeNext( - final Iterable> sources) { - return new OnErrorResumeNext(sources); - } - /** - * Creates an iterable which resumes with the next iterable from the sources when one throws an exception. - * @param the source element type - * @param first the first source - * @param second the second source - * @return the new iterable - */ - - public static Iterable onErrorResumeNext( - final Iterable first, - final Iterable second) { - List> list = new ArrayList>(2); - list.add(first); - list.add(second); - return onErrorResumeNext(list); - } - /** - * Creates an iterator which attempts to re-iterate the source if it threw an exception. - *

-     * while (count-- > 0) {
-     * 	  try {
-     *        for (T t : source) {
-     *            yield t;
-     *        }
-     *        break;
-     *    } catch (Throwable t) {
-     *        if (count <= 0) {
-     *            throw t;
-     *        }
-     *    }
-     * }
-     * 
- *

The returned iterator forwards all remove() calls - * to the source.

- * @param the source type - * @param source the source of Ts - * @param count the number of retry attempts - * @return the new iterable - */ - - public static Iterable retry( - final Iterable source, - final int count) { - return new RetryIterable(count, source); - } - /** - * Iterates over the given source without using its returned value. - * This method is useful when the concrete values from the iterator - * are not needed but the iteration itself implies some side effects. - * @param source the source iterable to run through - */ - public static void run( - final Iterable source) { - forEach(source, Actions.empty()); - } - /** - * Generates an iterable which acts like a running sum when iterating over the source iterable, e.g., - * For each element in T, it computes a value by using the current aggregation value and returns it. - * The first call to the aggregator function will receive a zero for its first argument. - * @param the source element type - * @param the destination element type - * @param source the source of Ts - * @param aggregator the function which takes the current running aggregation value, the current element and produces a new aggregation value. - * @return the new iterable - * TODO rework - */ - - public static Iterable scan( - final Iterable source, - final Func2 aggregator) { - return scan(source, null, aggregator); - } - /** - * Generates an iterable which acts like a running sum when iterating over the source iterable, e.g., - * For each element in T, it computes a value by using the current aggregation value and returns it. - * The first call to the aggregator function will receive a zero for its first argument. - *

The returned iterator forwards all remove() calls - * to the source.

- * @param the source element type - * @param the destination element type - * @param source the source of Ts - * @param seed the initial value of the running aggregation - * @param aggregator the function which takes the current running aggregation value, the current element and produces a new aggregation value. - * @return the new iterable - */ - - public static Iterable scan( - final Iterable source, - final U seed, - final Func2 aggregator) { - return new ScanIterable(source, aggregator, seed); - } - /** - * @return the current default pool used by the Observables methods - */ - - static Scheduler scheduler() { - return Schedulers.computation(); - } - /** - * Creates an iterable which returns a stream of Us for each source Ts. - * The iterable stream of Us is returned by the supplied selector function. - *

The returned iterator forwards all remove() calls - * to the current source (which might not accept it). - * @param the source element type - * @param the output element type - * @param source the source - * @param selector the selector for multiple Us for each T - * @return the new iterable - */ - - public static Iterable flatMap( - final Iterable source, - final Func1> selector) { - return new FlatMapIterable(selector, source); - } - /** - * Returns an iterable which ensures the source iterable is - * only traversed once and clients may take values from each other, - * e.g., they share the same iterator. - * @param the source element type - * @param source the source iterable - * @return the new iterable - */ - - public static Iterable share( - final Iterable source) { - return new ShareIterable(source); - } - /** - * Shares the source sequence within the specified - * selector function where each iterator can fetch - * the next element from the source. - * @param the source element type - * @param the result element type - * @param source the source sequence - * @param selector the selector function - * @return the new iterable - * TODO Builder - */ - - public static Iterable share( - final Iterable source, - final Func1, ? extends Iterable> selector - ) { - return new ShareSelectorIterable(source, selector); - } - /** - * Creates an iterable which returns only a single element. - *

The returned iterator will throw an UnsupportedOperationException - * for its remove() method.

- * @param the element type - * @param value the value to return - * @return the new iterable - */ - - public static Iterable just(final T value) { - return new JustIterable(value); - } - /** - * Immediately returns the number of elements in {@code iterable}. - * @param iterable the input sequence - * @return the number of elements in the sequence - */ - public static int size(Iterable iterable) { - return first(count(iterable)); - } - - /** - * Skips the specified amount of items at the beginning of the source sequence. - * @param the element type - * @param source the source iterable - * @param num the number of elements to skip - * @return the new iterable - */ - public static Iterable skip(final Iterable source, final int num) { - return new Skip(source, num); - } - - /** - * Returns an iterable which skips the last num elements from the - * source iterable. - *

The returned iterator will throw an UnsupportedOperationException - * for its remove() method.

- * @param the element type - * @param source the source iterable - * @param num the number of elements to skip at the end - * @return the new iterable - */ - - public static Iterable skipLast( - final Iterable source, - final int num) { - return new SkipLastIterable(source, num); - } - /** - * Creates an onNext notification. - * @param the value type - * @param value the value to wrap - * @return the notification - */ - static Notification some(T value) { - return Notification.createOnNext(value); - } - /** - * Returns an iterable which prefixes the source iterable values - * by a constant. - * It is equivalent to concat(singleton(value), source). - *

The returned iterator will throw an UnsupportedOperationException - * for its remove() method for the first element, and might - * throw for subsequent elements, depending on the source iterable.

- * @param the element type - * @param source the source iterable - * @param value the value to prefix - * @return the new iterable. - */ - - public static Iterable startWith( - Iterable source, - final T... value) { - return concat(Arrays.asList(value), source); - } - /** - * Creates an iterable which returns two subsequent items from the source - * iterable as pairs of values. If the {@code source} contains zero or one elements, this - * iterable will be empty. - *

The returned iterator will throw an UnsupportedOperationException - * for its remove() method.

- * @param the element type - * @param source the source iterable - * @return the new iterable - */ - public static Iterable> subsequent(final Iterable source) { - return new SubsequentIterable(source); - } - /** - * Creates an iterable which returns {@code count} subsequent items from the source - * iterable as sequence of values. - * If the {@code source} contains less than {@code count} elements, this - * iterable will be empty. - *

The returned iterator will throw an UnsupportedOperationException - * for its remove() method.

- * @param the element type - * @param source the source iterable - * @param count the element count - * @return the new iterable - */ - public static Iterable> subsequent( - final Iterable source, - final int count) { - if (count <= 0) { - throw new IllegalArgumentException("Count must be > 0"); - } - if (count == 1) { - return map(source, new Func1>() { - @Override - public Iterable call(T param1) { - return just(param1); - } - }); - } - return new SubsequentCountIterable(source, count); - } - /** - * Sum the source of Integer values and return it as a single element. - *

The returned iterator will throw an UnsupportedOperationException - * for its remove() method.

- * @param source the source - * @return the new iterable - */ - - public static Iterable sumBigDecimal( - Iterable source) { - return aggregate(source, - IxHelperFunctions.sumBigDecimal(), IxHelperFunctions.identityFirst() - ); - } - /** - * Sum the source of Integer values and return it as a single element. - *

The returned iterator will throw an UnsupportedOperationException - * for its remove() method.

- * @param source the source - * @return the new iterable - */ - - public static Iterable sumBigInteger( - Iterable source) { - return aggregate(source, - IxHelperFunctions.sumBigInteger(), IxHelperFunctions.identityFirst() - ); - } - /** - * Sum the source of Double values and returns it as a single element. - *

The returned iterator will throw an UnsupportedOperationException - * for its remove() method.

- * @param source the source - * @return the new iterable - */ - - public static Iterable sumDouble( - Iterable source) { - return aggregate(source, - IxHelperFunctions.sumDouble(), IxHelperFunctions.identityFirst() - ); - } - /** - * Sum the source of Float values and returns it as a single element. - * @param source the source - * @return the new iterable - */ - - public static Iterable sumFloat( - Iterable source) { - return aggregate(source, - IxHelperFunctions.sumFloat(), IxHelperFunctions.identityFirst() - ); - } - /** - * Sum the source of Integer values and returns it as a single element. - * @param source the source - * @return the new iterable - */ - - public static Iterable sumInt( - Iterable source) { - return aggregate(source, - IxHelperFunctions.sumInteger(), IxHelperFunctions.identityFirst() - ); - } - /** - * Computes and signals the sum of the values of the Integer source by using - * a double intermediate representation. - * The source may not send nulls. An empty source produces an empty sum - * @param source the source of integers to aggregate. - * @return the observable for the sum value - */ - - public static Iterable sumIntAsDouble( - final Iterable source) { - return aggregate(source, - new Func2() { - @Override - public Double call(Double param1, Integer param2) { - return param1 + param2; - } - }, - IxHelperFunctions.identityFirst() - ); - } - /** - * Sum the source of Long values and returns it as a single element. - * @param source the source - * @return the new iterable - */ - - public static Iterable sumLong( - Iterable source) { - return aggregate(source, - IxHelperFunctions.sumLong(), IxHelperFunctions.identityFirst() - ); - } - /** - * Computes and signals the sum of the values of the Long sourceby using - * a double intermediate representation. - * The source may not send nulls. - * @param source the source of longs to aggregate. - * @return the observable for the sum value - */ - - public static Iterable sumLongAsDouble( - final Iterable source) { - return aggregate(source, - new Func2() { - @Override - public Double call(Double param1, Long param2) { - return param1 + param2; - } - }, - IxHelperFunctions.identityFirst() - ); - } - /** - * Returns an iterable, which will query the selector for a key, then - * queries the map for an Iterable. The returned iterator will - * then traverse that Iterable. If the map does not contain an - * element, az empty iterable is used. - * @param the key type - * @param the output type - * @param selector the key selector - * @param options the available options in - * @return the new iterable - */ - - public static Iterable switchCase( - final Func0 selector, - final Map> options) { - return new SwitchCaseIterable(selector, options); - - } - /** - * Returns the iterable which returns the first num element. - * from the source iterable. - *

The returned iterator forwards all remove() calls - * to the source.

- * @param the source element type - * @param source the source of Ts - * @param num the number of items to take - * @return the new iterable - */ - - public static Iterable take( - final Iterable source, - final int num) { - return new TakeIterable(num, source); - } - /** - * Returns an iterable which takes only the last num elements from the - * source iterable. - *

The returned iterator will throw an UnsupportedOperationException - * for its remove() method.

- * @param the element type - * @param source the source iterable - * @param num the number of elements to skip at the end - * @return the new iterable - */ - - public static Iterable takeLast( - final Iterable source, - final int num) { - return new TakeLastIterable(source, num); - } - /** - * Returns an iterator which will throw the given - * Throwable exception when the client invokes - * next() the first time. Any subsequent - * next() call will simply throw a NoSuchElementException. - * Calling remove() will always throw a IllegalStateException. - * If the given Throwable instance extends a RuntimeException, it is throws - * as is, but when the throwable is a checked exception, it is wrapped - * into a RuntimeException. - * @param the element type, irrelevant - * @param t the exception to throw - * @return the new iterable - */ - - public static Iterable error( - final Throwable t) { - return new ErrorIterable(t); - } - /** - * Convert the source Iterable into the Enumerable semantics. - * @param the source element type - * @param e the iterable - * @return the new enumerable - */ - - public static Enumerable toEnumerable( - final Iterable e) { - return new Enumerable() { - @Override - - public Enumerator enumerator() { - return toEnumerator(e.iterator()); - } - }; - } - /** - * Convert the given iterator to the Enumerator semantics. - * @param the element type - * @param it the source iterator - * @return the new enumerator - */ - - public static Enumerator toEnumerator( - final Iterator it) { - return new IteratorToEnumerator(it); - } - /** - * Convert the source enumerable into the Iterable semantics. - * @param the source element type - * @param e the enumerable - * @return the new iterable - */ - - public static Iterable toIterable( - final Enumerable e) { - return new Iterable() { - @Override - public Iterator iterator() { - return toIterator(e.enumerator()); - } - }; - } - /** - * Takes the input elements and returns an iterable which - * traverses the array. The supplied array is - * shared by the iterator. Any changes to the array will be - * reflected by the iterator - *

The resulting {@code Iterable} does not support {@code remove()}.

- * @param the element type - * @param ts the input array - * @return the iterable for the array - */ - - public static Iterable toIterable(final T... ts) { - return new Iterable() { - @Override - public Iterator iterator() { - return new Iterator() { - /** The current location. */ - int index; - /** The lenght. */ - final int size = ts.length; - @Override - public boolean hasNext() { - return index < size; - } - @Override - public T next() { - if (hasNext()) { - return ts[index++]; - } - throw new NoSuchElementException(); - } - @Override - public void remove() { - throw new UnsupportedOperationException(); - } - }; - } - }; - } - /** - * Takes the input elements and returns an iterable which - * traverses the array between the two indexes. The supplied array is - * shared by the iterator. Any changes to the array will be - * reflected by the iterator. - *

The resulting {@code Iterable} does not support {@code remove()}.

- * @param the element type - * @param from the starting index inclusive - * @param to the end index exclusive - * @param ts the input array - * @return the iterable for the array - */ - - public static Iterable toIterablePart( - final int from, - final int to, - final T... ts) { - return new PartialIterable(from, ts, to); - } - /** - * Convert the given enumerator to the Iterator semantics. - *

The returned iterator will throw an UnsupportedOperationException - * for its remove() method.

- * @param the element type - * @param en the source enumerator - * @return the new iterator - */ - - public static Iterator toIterator( - final Enumerator en) { - return new EnumerationToIterator(en); - } - /** - * Call unsubscribe on the iterator if it implements the Subscription interface. - * @param iter the iterator to unsubscribe - */ - public static void unsubscribe(Iterator iter) { - if (iter instanceof Subscription) { - ((Subscription)iter).unsubscribe(); - } - } - /** - * Returns an iterable which is associated with a closeable handler. - * Once the source iterable is completed, it invokes the Closeable.close() on the handler. - *

The returned iterator forwards all remove() calls - * to the source.

- * @param the source element type - * @param the closeable type - * @param resource the function which returns a resource token - * @param usage the function which gives an iterable for a resource token. - * @return the new iterable - */ - - public static Iterable using( - final Func0 resource, - final Func1> usage) { - return new UsingIterable(resource, usage); - } - /** - * Extracts the notification value, exception or throws NoSuchElementException. - * @param the value type - * @param notif the notification to extract from - * @return the value - */ - static T value(Notification notif) { - if (notif.isOnNext()) { - return notif.getValue(); - } else - if (notif.isOnError()) { - Exceptions.propagate(notif.getThrowable()); - } - throw new NoSuchElementException(); - } - /** - * Creates an iterable which filters the source iterable with the - * given predicate factory function. The predicate returned by the factory receives an index - * telling how many elements were processed thus far. - * Use this construct if you want to use some memorizing predicate function (e.g., filter by subsequent distinct, filter by first occurrences only) - * which need to be invoked per iterator() basis. - *

The returned iterator forwards all remove() calls - * to the source.

- * @param the element type - * @param source the source iterable - * @param predicateFactory the predicate factory which should return a new predicate function for each iterator. - * @return the new iterable - */ - - public static Iterable filterIndexed( - final Iterable source, - final Func0> predicateFactory) { - return new FilterIndexedIterable(source, predicateFactory); - } - /** - * Creates an iterable which filters the source iterable with the - * given predicate function. The predicate receives the value and - * must return a boolean whether to accept that entry. - * @param the element type - * @param source the source iterable - * @param predicate the predicate function - * @return the new iterable - */ - - public static Iterable filter( - final Iterable source, - final Func1 predicate) { - return filterIndexed(source, IxHelperFunctions.constant0(new Func2() { - @Override - public Boolean call(Integer param1, T param2) { - return predicate.call(param2); - } - })); - } - /** - * Creates an iterable which filters the source iterable with the - * given predicate factory function. The predicate returned by the factory receives an index - * telling how many elements were processed thus far. - * @param the element type - * @param source the source iterable - * @param predicate the predicate - * @return the new iterable - */ - - public static Iterable filterIndexed( - final Iterable source, - final Func2 predicate) { - return filterIndexed(source, IxHelperFunctions.constant0(predicate)); - } - /** - * Pairs each element from both iterable sources and - * combines them into a new value by using the combiner - * function. - *

The returned iterator will throw an UnsupportedOperationException - * for its remove() method.

- * @param the left source type - * @param the right source type - * @param the result type - * @param left the left source - * @param right the right source - * @param combiner the combiner function - * @return the new iterable - */ - - public static Iterable zip( - final Iterable left, - final Iterable right, - final Func2 combiner) { - return new ZipIterable(left, right, combiner); - } - /** The common empty iterator. */ - private static final Iterator EMPTY_ITERATOR = new Iterator() { - @Override - public boolean hasNext() { - return false; - } - @Override - public Object next() { - throw new NoSuchElementException(); - } - @Override - public void remove() { - throw new IllegalStateException(); - } - }; - /** The common empty iterable. */ - private static final Iterable EMPTY_ITERABLE = new Iterable() { - @Override - public Iterator iterator() { - return EMPTY_ITERATOR; - } - }; - - // TODO IBuffer publish(Iterable) - - // TODO memoize(Iterable) - - // TODO memoize(Iterable, Func) - - // TODO memoize(Iterable, int, Func) - - // TODO throwException(Func) - - // TODO catchException(Iterable>) - - // TODO catchException(Iterable, Iterable) - - // TODO retry(Iterable) - - // TODO resumeOnError(Iterable...) - - // TODO ifThen(Func, Iterable) - - // TODO ifThen(Func, Iterable, Iterable) - - // TODO whileDo(Func, Iterable) - - // TODO switchCase(Func, Map>, Iterable) - - // TODO selectMany(Iterable, Iterable) - - // TODO forEach(Iterable, Action) - - // TODO forEach(Iterable, Action) - - // TODO invoke(Iterable, Observer) - - // TODO buffer(Iterable, int, int) - - // TODO ignoreValues(Iterable) - - // TODO distinct(Iterable, Func2) - - // TODO distinct(Iterable, Func, Func) - - // TODO distinctNext(Iterable, Func, Func, Func>) - - // TODO repeat(Iterable) - - // TODO repeat(Iterable, count) - - /** Utility class. */ - private Interactive() { - // utility class - } -} diff --git a/src/main/java/ix/internal/operators/IteratorToEnumerator.java b/src/main/java/ix/internal/operators/IteratorToEnumerator.java deleted file mode 100644 index 2c03de0..0000000 --- a/src/main/java/ix/internal/operators/IteratorToEnumerator.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright 2011-2016 David Karnok - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package ix.internal.operators; - -import ix.Enumerator; - -import java.util.Iterator; -import java.util.NoSuchElementException; - -public final class IteratorToEnumerator implements Enumerator { - /** The source sequence. */ - private final Iterator it; - /** The current value. */ - T value; - /** The current value is set. */ - boolean hasValue; - - public IteratorToEnumerator(Iterator it) { - this.it = it; - } - - @Override - public T current() { - if (hasValue) { - return value; - } - throw new NoSuchElementException(); - } - - @Override - public boolean next() { - if (it.hasNext()) { - value = it.next(); - hasValue = true; - return false; - } - hasValue = false; - return false; - } -} \ No newline at end of file diff --git a/src/main/java/ix/internal/operators/JustIterable.java b/src/main/java/ix/internal/operators/JustIterable.java deleted file mode 100644 index a43e71f..0000000 --- a/src/main/java/ix/internal/operators/JustIterable.java +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright 2011-2016 David Karnok - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package ix.internal.operators; - -import java.util.Iterator; -import java.util.NoSuchElementException; - -/** - * Iterable sequence with a specific single value. - * - * @param the value type - */ -public final class JustIterable implements Iterable { - /** The value to return. */ - private final T value; - /** - * Constructor with the single value. - * @param value the value - */ - public JustIterable(T value) { - this.value = value; - } - - @Override - public Iterator iterator() { - return new Iterator() { - /** Return the only element? */ - boolean first = true; - @Override - public boolean hasNext() { - return first; - } - - @Override - public T next() { - if (first) { - first = false; - return value; - } - throw new NoSuchElementException(); - } - - @Override - public void remove() { - throw new UnsupportedOperationException(); - } - - }; - } -} \ No newline at end of file diff --git a/src/main/java/ix/internal/operators/LongCountIterable.java b/src/main/java/ix/internal/operators/LongCountIterable.java deleted file mode 100644 index 86978b5..0000000 --- a/src/main/java/ix/internal/operators/LongCountIterable.java +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Copyright 2011-2016 David Karnok - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package ix.internal.operators; - -import ix.internal.util.SingleContainer; - -import java.util.Iterator; -import java.util.NoSuchElementException; - -import rx.Notification; - -public final class LongCountIterable implements Iterable { - /** The source sequence. */ - private final Iterable source; - - public LongCountIterable(Iterable source) { - this.source = source; - } - - @Override - public Iterator iterator() { - final Iterator it = source.iterator(); - return new Iterator() { - /** The peek ahead container. */ - final SingleContainer> peek = new SingleContainer>(); - /** Computation already done. */ - boolean done; - @Override - public boolean hasNext() { - if (!done) { - if (peek.isEmpty()) { - long count = 0; - try { - while (it.hasNext()) { - it.next(); - count++; - } - peek.add(Interactive.some(count)); - } catch (Throwable t) { - peek.add(Interactive.err(t)); - } finally { - done = true; - Interactive.unsubscribe(it); - } - } - } - return !peek.isEmpty(); - } - - @Override - public Long next() { - if (hasNext()) { - return Interactive.value(peek.take()); - } - throw new NoSuchElementException(); - } - - @Override - public void remove() { - throw new UnsupportedOperationException(); - } - - }; - } -} \ No newline at end of file diff --git a/src/main/java/ix/internal/operators/LongRangeIterable.java b/src/main/java/ix/internal/operators/LongRangeIterable.java deleted file mode 100644 index 09ad5d9..0000000 --- a/src/main/java/ix/internal/operators/LongRangeIterable.java +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright 2011-2016 David Karnok - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package ix.internal.operators; - -import java.util.Iterator; -import java.util.NoSuchElementException; - -/** - * Iterable sequence with long values from a start value producing count values. - */ -public final class LongRangeIterable implements Iterable { - /** The start value. */ - private final long start; - /** The number of elements to return. */ - private final long count; - /** - * Constructor, sets the fields. - * @param start the start value - * @param count number of values - */ - public LongRangeIterable(long start, long count) { - this.start = start; - this.count = count; - } - - @Override - public Iterator iterator() { - return new Iterator() { - long current = start; - @Override - public boolean hasNext() { - return current < start + count; - } - @Override - public Long next() { - if (hasNext()) { - return current++; - } - throw new NoSuchElementException(); - } - @Override - public void remove() { - throw new UnsupportedOperationException(); - } - }; - } -} \ No newline at end of file diff --git a/src/main/java/ix/internal/operators/MapIndexedIterable.java b/src/main/java/ix/internal/operators/MapIndexedIterable.java deleted file mode 100644 index 49b9444..0000000 --- a/src/main/java/ix/internal/operators/MapIndexedIterable.java +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright 2011-2016 David Karnok - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package ix.internal.operators; - -import java.util.Iterator; - -import rx.functions.Func2; - -public final class MapIndexedIterable implements Iterable { - /** The source sequence. */ - private final Iterable source; - private final Func2 selector; - - public MapIndexedIterable(Iterable source, - Func2 selector) { - this.source = source; - this.selector = selector; - } - - @Override - public Iterator iterator() { - final Iterator it = source.iterator(); - return new Iterator() { - /** The current counter. */ - int count; - @Override - public boolean hasNext() { - return it.hasNext(); - } - - @Override - public U next() { - return selector.call(count++, it.next()); - } - - @Override - public void remove() { - it.remove(); - } - - }; - } -} \ No newline at end of file diff --git a/src/main/java/ix/internal/operators/MaterializeIterable.java b/src/main/java/ix/internal/operators/MaterializeIterable.java deleted file mode 100644 index 523fe1a..0000000 --- a/src/main/java/ix/internal/operators/MaterializeIterable.java +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Copyright 2011-2016 David Karnok - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package ix.internal.operators; - -import ix.internal.util.SingleContainer; - -import java.util.Iterator; -import java.util.NoSuchElementException; - -import rx.Notification; - -public final class MaterializeIterable implements Iterable> { - /** The source sequence. */ - private final Iterable source; - - public MaterializeIterable(Iterable source) { - this.source = source; - } - - @Override - public Iterator> iterator() { - final Iterator it = source.iterator(); - return new Iterator>() { - /** The peeked value or exception. */ - final SingleContainer> peek = new SingleContainer>(); - /** The source iterator threw an exception. */ - boolean broken; - @Override - public boolean hasNext() { - if (!broken) { - try { - if (peek.isEmpty()) { - if (it.hasNext()) { - T t = it.next(); - peek.add(Interactive.some(t)); - } else { - peek.add(Interactive.none()); - broken = true; - } - } - } catch (Throwable t) { - broken = true; - peek.add(Interactive.err(t)); - } - } - return !peek.isEmpty(); - } - - @Override - public Notification next() { - if (hasNext()) { - return peek.take(); - } - throw new NoSuchElementException(); - } - - @Override - public void remove() { - throw new UnsupportedOperationException(); - } - - }; - } -} \ No newline at end of file diff --git a/src/main/java/ix/internal/operators/MemoizeAllIterable.java b/src/main/java/ix/internal/operators/MemoizeAllIterable.java deleted file mode 100644 index 99aa87e..0000000 --- a/src/main/java/ix/internal/operators/MemoizeAllIterable.java +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Copyright 2011-2016 David Karnok - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package ix.internal.operators; - -import ix.internal.util.LinkedBuffer; - -import java.util.Iterator; -import java.util.NoSuchElementException; - -public final class MemoizeAllIterable implements Iterable { - /** The source sequence. */ - private final Iterator it; - private final LinkedBuffer buffer; - - public MemoizeAllIterable(Iterator it, - LinkedBuffer buffer) { - this.it = it; - this.buffer = buffer; - } - - @Override - public Iterator iterator() { - return new Iterator() { - /** The element count. */ - int count = 0; - /** The current node pointer. */ - LinkedBuffer.N pointer = buffer.head; - @Override - public boolean hasNext() { - return count < buffer.size || it.hasNext(); - } - - @Override - public T next() { - if (hasNext()) { - if (count < buffer.size) { - T value = pointer.next.value; - pointer = pointer.next; - count++; - return value; - } else { - T value = it.next(); - buffer.add(value); - count++; - pointer = pointer.next; - return value; - } - } - throw new NoSuchElementException(); - } - - @Override - public void remove() { - throw new UnsupportedOperationException(); - } - - }; - } -} \ No newline at end of file diff --git a/src/main/java/ix/internal/operators/MemoizeIterable.java b/src/main/java/ix/internal/operators/MemoizeIterable.java deleted file mode 100644 index 29114f1..0000000 --- a/src/main/java/ix/internal/operators/MemoizeIterable.java +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Copyright 2011-2016 David Karnok - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package ix.internal.operators; - -import ix.internal.util.CircularBuffer; - -import java.util.Iterator; -import java.util.NoSuchElementException; - -/** - * Memoizes the source sequence with a given buffer size. - * - * @param the element type - */ -public final class MemoizeIterable implements Iterable { - /** The buffer size. */ - private final int bufferSize; - /** The source iterator. */ - Iterator it; - /** The ring buffer of the memory. */ - final CircularBuffer buffer; - /** - * Constructor, sets the buffer size and takes an iterator from source. - * @param source the source iterable - * @param bufferSize the buffer size - */ - public MemoizeIterable(Iterable source, int bufferSize) { - this.bufferSize = bufferSize; - it = source.iterator(); - buffer = new CircularBuffer(bufferSize); - } - - @Override - public Iterator iterator() { - return new Iterator() { - int myHead; - - @Override - public boolean hasNext() { - return buffer.tail() > Math.max(myHead, buffer.head()) || it.hasNext(); - } - - @Override - public T next() { - if (hasNext()) { - if (buffer.tail() == myHead) { - T value = it.next(); - if (bufferSize > 0) { - buffer.add(value); - } - myHead++; - return value; - } else { - myHead = Math.max(myHead, buffer.head()); - T value = buffer.get(myHead); - myHead++; - return value; - } - } - throw new NoSuchElementException(); - } - - @Override - public void remove() { - throw new UnsupportedOperationException(); - } - }; - } -} \ No newline at end of file diff --git a/src/main/java/ix/internal/operators/MergeIterable.java b/src/main/java/ix/internal/operators/MergeIterable.java deleted file mode 100644 index f2e5087..0000000 --- a/src/main/java/ix/internal/operators/MergeIterable.java +++ /dev/null @@ -1,127 +0,0 @@ -/* - * Copyright 2011-2016 David Karnok - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package ix.internal.operators; - -import ix.internal.util.SingleContainer; - -import java.util.Iterator; -import java.util.NoSuchElementException; -import java.util.concurrent.BlockingQueue; -import java.util.concurrent.LinkedBlockingQueue; -import java.util.concurrent.atomic.AtomicInteger; - -import rx.Notification; -import rx.Scheduler; -import rx.functions.Action0; -import rx.internal.util.SubscriptionList; - -public final class MergeIterable implements Iterable { - private final Scheduler scheduler; - /** The source sequences. */ - private final Iterable> sources; - - public MergeIterable(Scheduler scheduler, - Iterable> sources) { - this.scheduler = scheduler; - this.sources = sources; - } - - @Override - public Iterator iterator() { - final BlockingQueue> queue = new LinkedBlockingQueue>(); - final AtomicInteger wip = new AtomicInteger(1); - final SubscriptionList handlers = new SubscriptionList(); - final Scheduler.Worker worker = scheduler.createWorker(); - handlers.add(worker); - for (final Iterable iter : sources) { - Action0 r = new Action0() { - @Override - public void call() { - try { - final Iterator fiter = iter.iterator(); - try { - while (fiter.hasNext()) { - T t = fiter.next(); - if (!Thread.currentThread().isInterrupted()) { - queue.add(Interactive.some(t)); - } - } - } finally { - Interactive.unsubscribe(fiter); - } - if (wip.decrementAndGet() == 0) { - if (!Thread.currentThread().isInterrupted()) { - queue.add(Interactive.none()); - } - } - } catch (Throwable t) { - queue.add(Interactive.err(t)); - } - } - }; - wip.incrementAndGet(); - handlers.add(worker.schedule(r)); - } - if (wip.decrementAndGet() == 0) { - queue.add(Interactive.none()); - } - return new Iterator() { - final SingleContainer> peek = new SingleContainer>(); - /** Are we broken? */ - boolean broken; - @Override - public boolean hasNext() { - if (!broken) { - if (peek.isEmpty()) { - try { - Notification t = queue.take(); - if (t.isOnNext()) { - peek.add(t); - } else - if (t.isOnError()) { - peek.add(t); - broken = true; - } - } catch (InterruptedException ex) { - Thread.currentThread().interrupt(); - return false; // FIXME not sure about this - } - } - } - return !peek.isEmpty(); - } - - @Override - public T next() { - if (hasNext()) { - try { - return Interactive.value(peek.take()); - } catch (RuntimeException ex) { - handlers.unsubscribe(); - throw ex; - } - } - throw new NoSuchElementException(); - } - - @Override - public void remove() { - throw new UnsupportedOperationException(); - } - - }; - } -} \ No newline at end of file diff --git a/src/main/java/ix/internal/operators/MinMaxIterable.java b/src/main/java/ix/internal/operators/MinMaxIterable.java deleted file mode 100644 index cd5803e..0000000 --- a/src/main/java/ix/internal/operators/MinMaxIterable.java +++ /dev/null @@ -1,128 +0,0 @@ -/* - * Copyright 2011-2016 David Karnok - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package ix.internal.operators; - -import ix.internal.util.SingleContainer; - -import java.util.ArrayList; -import java.util.Comparator; -import java.util.Iterator; -import java.util.List; -import java.util.NoSuchElementException; - -import rx.Notification; -import rx.functions.Func1; - -/** - * Iterable sequence that returns the minimum or maximum of the source sequence - * according to a key selector and key comparator. - * - * @param the source value type - * @param the key value type - */ -public final class MinMaxIterable implements Iterable> { - /** Returns a key for a value. */ - private final Func1 keySelector; - /** The source sequence. */ - private final Iterable source; - /** Find the maximum? */ - private final boolean max; - /** Compares two keys. */ - private final Comparator keyComparator; - - /** - * Constructor, initializes the fields. - * @param keySelector the key selector function - * @param source the source sequenec - * @param max find the maximum? - * @param keyComparator the key comparator function - */ - public MinMaxIterable(Func1 keySelector, - Iterable source, boolean max, - Comparator keyComparator) { - this.keySelector = keySelector; - this.source = source; - this.max = max; - this.keyComparator = keyComparator; - } - - @Override - public Iterator> iterator() { - return new Iterator>() { - /** The source iterator. */ - final Iterator it = source.iterator(); - /** The single result container. */ - final SingleContainer>> result = new SingleContainer>>(); - /** We have finished the aggregation. */ - boolean done; - @Override - public boolean hasNext() { - if (!done) { - done = true; - if (result.isEmpty()) { - try { - List intermediate = null; - U lastKey = null; - try { - while (it.hasNext()) { - T value = it.next(); - U key = keySelector.call(value); - if (intermediate == null) { - intermediate = new ArrayList(); - lastKey = key; - intermediate.add(value); - } else { - int c = keyComparator.compare(lastKey, key); - if ((c < 0 && max) || (c > 0 && !max)) { - intermediate = new ArrayList(); - lastKey = key; - c = 0; - } - if (c == 0) { - intermediate.add(value); - } - } - } - } finally { - Interactive.unsubscribe(it); - } - if (intermediate != null) { - result.add(Interactive.some(intermediate)); - } - } catch (Throwable t) { - result.add(Interactive.>err(t)); - } - } - } - return !result.isEmpty(); - } - - @Override - public List next() { - if (hasNext()) { - return Interactive.value(result.take()); - } - throw new NoSuchElementException(); - } - - @Override - public void remove() { - throw new UnsupportedOperationException(); - } - - }; - } -} \ No newline at end of file diff --git a/src/main/java/ix/internal/operators/OnErrorResumeNext.java b/src/main/java/ix/internal/operators/OnErrorResumeNext.java deleted file mode 100644 index 59df97a..0000000 --- a/src/main/java/ix/internal/operators/OnErrorResumeNext.java +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Copyright 2011-2016 David Karnok - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package ix.internal.operators; - -import ix.internal.util.SingleContainer; - -import java.util.Iterator; -import java.util.NoSuchElementException; - -import rx.Notification; - -public final class OnErrorResumeNext implements Iterable { - /** The source sequences. */ - private final Iterable> sources; - - public OnErrorResumeNext( - Iterable> sources) { - this.sources = sources; - } - - @Override - public Iterator iterator() { - final Iterator> iter0 = sources.iterator(); - if (iter0.hasNext()) { - return new Iterator() { - /** The current iterator. */ - Iterator it = iter0.next().iterator(); - /** The memorized iterator for the remove call. */ - Iterator itForRemove = null; - /** The peek ahead container. */ - final SingleContainer> peek = new SingleContainer>(); - @Override - public boolean hasNext() { - if (peek.isEmpty()) { - while (!Thread.currentThread().isInterrupted()) { - try { - if (it.hasNext()) { - peek.add(Interactive.some(it.next())); - break; - } else { - if (iter0.hasNext()) { - it = iter0.next().iterator(); - } else { - break; - } - } - } catch (Throwable t) { - if (iter0.hasNext()) { - it = iter0.next().iterator(); - } else { - peek.add(Interactive.err(t)); - break; - } - } - } - } - return !peek.isEmpty(); - } - - @Override - public T next() { - if (hasNext()) { - itForRemove = it; - return Interactive.value(peek.take()); - } - throw new NoSuchElementException(); - } - - @Override - public void remove() { - if (itForRemove == null) { - throw new IllegalStateException(); - } - itForRemove.remove(); - itForRemove = null; - } - }; - } - return Interactive.empty().iterator(); - } -} \ No newline at end of file diff --git a/src/main/java/ix/internal/operators/OnErrorResumeNextIterable.java b/src/main/java/ix/internal/operators/OnErrorResumeNextIterable.java deleted file mode 100644 index ab703c1..0000000 --- a/src/main/java/ix/internal/operators/OnErrorResumeNextIterable.java +++ /dev/null @@ -1,93 +0,0 @@ -/* - * Copyright 2011-2016 David Karnok - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package ix.internal.operators; - -import ix.internal.util.SingleContainer; - -import java.util.Iterator; -import java.util.NoSuchElementException; - -import rx.exceptions.Exceptions; -import rx.functions.Func1; - -public final class OnErrorResumeNextIterable implements - Iterable { - /** The source sequence. */ - private final Iterable source; - private final Func1> handler; - - public OnErrorResumeNextIterable( - Iterable source, - Func1> handler) { - this.source = source; - this.handler = handler; - } - - @Override - public Iterator iterator() { - return new Iterator() { - /** The current iterator. */ - Iterator it = source.iterator(); - /** The last iterator used by next(). */ - Iterator itForRemove; - /** The peek ahead container. */ - final SingleContainer peek = new SingleContainer(); - /** Indicate that we switched to the handler. */ - boolean usingHandler; - @Override - public boolean hasNext() { - if (peek.isEmpty()) { - while (!Thread.currentThread().isInterrupted()) { - try { - if (it.hasNext()) { - itForRemove = it; - peek.add(it.next()); - } - break; - } catch (Throwable t) { - if (!usingHandler) { - Interactive.unsubscribe(it); - it = handler.call(t).iterator(); - usingHandler = true; - } else { - Exceptions.propagate(t); - } - } - } - } - return !peek.isEmpty(); - } - - @Override - public T next() { - if (hasNext()) { - return peek.take(); - } - throw new NoSuchElementException(); - } - - @Override - public void remove() { - if (itForRemove == null) { - throw new IllegalStateException(); - } - itForRemove.remove(); - itForRemove = null; - } - - }; - } -} \ No newline at end of file diff --git a/src/main/java/ix/internal/operators/OrderByIterable.java b/src/main/java/ix/internal/operators/OrderByIterable.java deleted file mode 100644 index e96c1bc..0000000 --- a/src/main/java/ix/internal/operators/OrderByIterable.java +++ /dev/null @@ -1,103 +0,0 @@ -/* - * Copyright 2011-2016 David Karnok - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package ix.internal.operators; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.Comparator; -import java.util.Iterator; -import java.util.List; -import java.util.NoSuchElementException; - -import rx.functions.Func1; - -/** - * Iterable sequence which sorts the source (finite) sequence accoring to the given - * key selector and key comparator functions. - * - * @param the source type - * @param the key type - */ -public final class OrderByIterable implements Iterable { - /** The source sequence. */ - private final Iterable source; - /** The key comparator function. */ - private final Comparator keyComparator; - /** The key selector function. */ - private final Func1 keySelector; - /** - * Constructor, initializes the fields. - * @param source the source sequence - * @param keyComparator the key comparator function - * @param keySelector the key selector function - */ - public OrderByIterable(Iterable source, - Comparator keyComparator, - Func1 keySelector) { - this.source = source; - this.keyComparator = keyComparator; - this.keySelector = keySelector; - } - - @Override - public Iterator iterator() { - return new Iterator() { - /** The buffer. */ - List buffer; - /** The source iterator. */ - final Iterator it = source.iterator(); - /** The buffer iterator. */ - Iterator bufIterator; - @Override - public boolean hasNext() { - if (buffer == null) { - buffer = new ArrayList(); - try { - while (it.hasNext()) { - buffer.add(it.next()); - } - } finally { - Interactive.unsubscribe(it); - } - Collections.sort(buffer, new Comparator() { - @Override - public int compare(T o1, T o2) { - U key1 = keySelector.call(o1); - U key2 = keySelector.call(o2); - return keyComparator.compare(key1, key2); - } - }); - bufIterator = buffer.iterator(); - } - return bufIterator.hasNext(); - } - - @Override - public T next() { - if (hasNext()) { - return bufIterator.next(); - } - throw new NoSuchElementException(); - } - - @Override - public void remove() { - throw new UnsupportedOperationException(); - } - - }; - } -} \ No newline at end of file diff --git a/src/main/java/ix/internal/operators/PartialIterable.java b/src/main/java/ix/internal/operators/PartialIterable.java deleted file mode 100644 index cbd3d4a..0000000 --- a/src/main/java/ix/internal/operators/PartialIterable.java +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright 2011-2016 David Karnok - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package ix.internal.operators; - -import java.util.Iterator; -import java.util.NoSuchElementException; - -/** - * Iterable sequence which returns values from a range in an array of items. - * - * @param the value type - */ -public final class PartialIterable implements Iterable { - /** The source index, inclusive. */ - private final int from; - /** The array of values. */ - private final T[] ts; - /** The destination index, exclusive. */ - private final int to; - /** - * Constructor, initalizes the fields. - * @param from the source index, inclusive - * @param ts the array of values - * @param to the destination index, exclusive - */ - public PartialIterable(int from, T[] ts, int to) { - this.from = from; - this.ts = ts; - this.to = to; - } - - @Override - public Iterator iterator() { - return new Iterator() { - /** The current location. */ - int index = from; - /** The lenght. */ - final int size = ts.length; - @Override - public boolean hasNext() { - return index < size && index < to; - } - @Override - public T next() { - if (hasNext()) { - return ts[index++]; - } - throw new NoSuchElementException(); - } - @Override - public void remove() { - throw new UnsupportedOperationException(); - } - }; - } -} \ No newline at end of file diff --git a/src/main/java/ix/internal/operators/PrintAction1.java b/src/main/java/ix/internal/operators/PrintAction1.java deleted file mode 100644 index c7debe8..0000000 --- a/src/main/java/ix/internal/operators/PrintAction1.java +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright 2011-2016 David Karnok - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package ix.internal.operators; - -import rx.functions.Action1; -/** - * Helper action that prints elements to the console. - * - * @param the source value type - */ -public final class PrintAction1 implements Action1 { - /** The separator between elements. */ - private final String separator; - /** The maximum length of a line. */ - private final int maxLineLength; - /** Indicator for the first element. */ - boolean first = true; - /** The current line length. */ - int len; - - /** - * Constructor, initializes the fields. - * @param separator the separator between elements - * @param maxLineLength the maximum lenght of a line - */ - public PrintAction1(String separator, int maxLineLength) { - this.separator = separator; - this.maxLineLength = maxLineLength; - } - - @Override - public void call(T value) { - String s = String.valueOf(value); - if (first) { - first = false; - System.out.print(s); - len = s.length(); - } else { - if (len + separator.length() + s.length() > maxLineLength) { - if (len == 0) { - System.out.print(separator); - System.out.print(s); - len = s.length() + separator.length(); - } else { - System.out.println(separator); - System.out.print(s); - len = s.length(); - } - } else { - System.out.print(separator); - System.out.print(s); - len += s.length() + separator.length(); - } - } - } -} \ No newline at end of file diff --git a/src/main/java/ix/internal/operators/RangeIterable.java b/src/main/java/ix/internal/operators/RangeIterable.java deleted file mode 100644 index 7241649..0000000 --- a/src/main/java/ix/internal/operators/RangeIterable.java +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright 2011-2016 David Karnok - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package ix.internal.operators; - -import java.util.Iterator; -import java.util.NoSuchElementException; - -/** - * Iterable sequence of integer values from a start value and count values. - */ -public final class RangeIterable implements Iterable { - /** The start value. */ - private final int start; - /** The number of values. */ - private final int count; - /** - * Constructor, initializes the fields. - * @param start the start value - * @param count the number of elements - */ - public RangeIterable(int start, int count) { - this.start = start; - this.count = count; - } - - @Override - public Iterator iterator() { - return new Iterator() { - int current = start; - @Override - public boolean hasNext() { - return current < start + count; - } - @Override - public Integer next() { - if (hasNext()) { - return current++; - } - throw new NoSuchElementException(); - } - @Override - public void remove() { - throw new UnsupportedOperationException(); - } - }; - } -} \ No newline at end of file diff --git a/src/main/java/ix/internal/operators/ReduceIterable.java b/src/main/java/ix/internal/operators/ReduceIterable.java deleted file mode 100644 index 75de92e..0000000 --- a/src/main/java/ix/internal/operators/ReduceIterable.java +++ /dev/null @@ -1,100 +0,0 @@ -/* - * Copyright 2011-2016 David Karnok - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package ix.internal.operators; - -import java.util.*; - -import rx.functions.*; - -/** - * Combines subsequent values into a single value that is then returned. - * @param the source value type - * @since 0.92.3 - */ -public final class ReduceIterable implements Iterable { - - final Iterable source; - - final Func2 reducer; - - public ReduceIterable(Iterable source, Func2 reducer) { - this.source = source; - this.reducer = reducer; - } - - @Override - public Iterator iterator() { - Iterator it = source.iterator(); - - return new ReduceIterator(it, reducer); - } - - static final class ReduceIterator implements Iterator { - final Func2 reducer; - - Iterator it; - - boolean once; - - boolean hasValue; - - T result; - - public ReduceIterator(Iterator it, Func2 reducer) { - this.it = it; - this.reducer = reducer; - } - - @Override - public boolean hasNext() { - if (!once) { - once = true; - - final Iterator o = it; - final Func2 f = reducer; - - if (o.hasNext()) { - T r = o.next(); - - while (o.hasNext()) { - r = f.call(r, o.next()); - } - - result = r; - hasValue = true; - } - } - return hasValue; - } - - @Override - public T next() { - if (hasNext()) { - T c = result; - result = null; - hasValue = false; - return c; - } - throw new NoSuchElementException(); - } - - @Override - public void remove() { - throw new UnsupportedOperationException(); - } - } -} diff --git a/src/main/java/ix/internal/operators/RepeatCountIterable.java b/src/main/java/ix/internal/operators/RepeatCountIterable.java deleted file mode 100644 index 15ae55d..0000000 --- a/src/main/java/ix/internal/operators/RepeatCountIterable.java +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright 2011-2016 David Karnok - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package ix.internal.operators; - -import java.util.Iterator; -import java.util.NoSuchElementException; - -/** - * Iterable sequence which repeates the same value a certain number of times. - * - * @param the value type - */ -public final class RepeatCountIterable implements Iterable { - /** The repeat count. */ - private final int count; - /** The value to repeat. */ - private final T value; - - /** - * Constructor, initializes the fields. - * @param count the repeat count - * @param value the value to repeat - */ - public RepeatCountIterable(int count, T value) { - this.count = count; - this.value = value; - } - - @Override - public Iterator iterator() { - return new Iterator() { - int index; - @Override - public boolean hasNext() { - return index < count; - } - @Override - public T next() { - if (hasNext()) { - index++; - return value; - } - throw new NoSuchElementException(); - } - @Override - public void remove() { - throw new UnsupportedOperationException(); - } - }; - } -} \ No newline at end of file diff --git a/src/main/java/ix/internal/operators/RepeatIterable.java b/src/main/java/ix/internal/operators/RepeatIterable.java deleted file mode 100644 index c6aecbb..0000000 --- a/src/main/java/ix/internal/operators/RepeatIterable.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright 2011-2016 David Karnok - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package ix.internal.operators; - -import java.util.Iterator; - -/** - * Iterable sequence which repeates the same value indefinitely. - * - * @param the value type - */ -public final class RepeatIterable implements Iterable { - /** The value to repeat. */ - private final T value; - /** - * Constructor, sets the value. - * @param value the value to repeat - */ - public RepeatIterable(T value) { - this.value = value; - } - - @Override - public Iterator iterator() { - return new Iterator() { - @Override - public boolean hasNext() { - return true; - } - @Override - public T next() { - return value; - } - @Override - public void remove() { - throw new UnsupportedOperationException(); - } - }; - } -} \ No newline at end of file diff --git a/src/main/java/ix/internal/operators/RetryIterable.java b/src/main/java/ix/internal/operators/RetryIterable.java deleted file mode 100644 index 5f1b157..0000000 --- a/src/main/java/ix/internal/operators/RetryIterable.java +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Copyright 2011-2016 David Karnok - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package ix.internal.operators; - -import ix.internal.util.SingleContainer; - -import java.util.Iterator; -import java.util.NoSuchElementException; - -import rx.Notification; - -public final class RetryIterable implements Iterable { - private final int count; - /** The source sequence. */ - private final Iterable source; - - public RetryIterable(int count, Iterable source) { - this.count = count; - this.source = source; - } - - @Override - public Iterator iterator() { - return new Iterator() { - /** The retry count. */ - int retries = count; - /** The peek store. */ - final SingleContainer> peek = new SingleContainer>(); - /** The current iterator. */ - Iterator it = source.iterator(); - @Override - public boolean hasNext() { - if (peek.isEmpty()) { - while (it.hasNext()) { - try { - peek.add(Interactive.some(it.next())); - break; - } catch (Throwable t) { - if (retries-- > 0) { - it = source.iterator(); - } else { - peek.add(Interactive.err(t)); - break; - } - } - } - } - return !peek.isEmpty(); - } - - @Override - public T next() { - if (hasNext()) { - return Interactive.value(peek.take()); - } - throw new NoSuchElementException(); - } - - @Override - public void remove() { - it.remove(); - } - - }; - } -} \ No newline at end of file diff --git a/src/main/java/ix/internal/operators/ScanIterable.java b/src/main/java/ix/internal/operators/ScanIterable.java deleted file mode 100644 index 5023cdd..0000000 --- a/src/main/java/ix/internal/operators/ScanIterable.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright 2011-2016 David Karnok - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package ix.internal.operators; - -import java.util.Iterator; - -import rx.functions.Func2; - -public final class ScanIterable implements Iterable { - /** The source sequence. */ - private final Iterable source; - private final Func2 aggregator; - private final U seed; - - public ScanIterable(Iterable source, - Func2 aggregator, U seed) { - this.source = source; - this.aggregator = aggregator; - this.seed = seed; - } - - @Override - public Iterator iterator() { - final Iterator it = source.iterator(); - return new Iterator() { - /** The current value. */ - U current = seed; - - @Override - public boolean hasNext() { - return it.hasNext(); - } - - @Override - public U next() { - current = aggregator.call(current, it.next()); - return current; - } - - @Override - public void remove() { - it.remove(); - } - }; - } -} \ No newline at end of file diff --git a/src/main/java/ix/internal/operators/ShareIterable.java b/src/main/java/ix/internal/operators/ShareIterable.java deleted file mode 100644 index e1c2b24..0000000 --- a/src/main/java/ix/internal/operators/ShareIterable.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright 2011-2016 David Karnok - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package ix.internal.operators; - -import java.util.Iterator; - -public final class ShareIterable implements Iterable { - /** The source sequence. */ - private final Iterable source; - Iterator it; - - public ShareIterable(Iterable source) { - this.source = source; - } - - @Override - public Iterator iterator() { - if (it == null) { - it = source.iterator(); - } - return it; - } -} \ No newline at end of file diff --git a/src/main/java/ix/internal/operators/ShareSelectorIterable.java b/src/main/java/ix/internal/operators/ShareSelectorIterable.java deleted file mode 100644 index 7beeab8..0000000 --- a/src/main/java/ix/internal/operators/ShareSelectorIterable.java +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright 2011-2016 David Karnok - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package ix.internal.operators; - -import java.util.Iterator; - -import rx.functions.Func1; - -public final class ShareSelectorIterable implements Iterable { - /** The source sequence. */ - private final Iterable source; - private final Func1, ? extends Iterable> selector; - - public ShareSelectorIterable(Iterable source, - Func1, ? extends Iterable> selector) { - this.source = source; - this.selector = selector; - } - - @Override - public Iterator iterator() { - return selector.call(Interactive.share(source)).iterator(); - } -} \ No newline at end of file diff --git a/src/main/java/ix/internal/operators/Skip.java b/src/main/java/ix/internal/operators/Skip.java deleted file mode 100644 index ef768a4..0000000 --- a/src/main/java/ix/internal/operators/Skip.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright 2011-2016 David Karnok - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package ix.internal.operators; - -import java.util.*; - -public final class Skip implements Iterable { - final Iterable source; - - final int num; - - public Skip(Iterable source, int num) { - this.source = source; - this.num = num; - } - - @Override - public Iterator iterator() { - @SuppressWarnings("unchecked") - Iterator it = (Iterator)source.iterator(); - - int i = num; - - while (i > 0) { - if (!it.hasNext()) { - return Collections.emptyList().iterator(); - } - it.next(); - i--; - } - - return it; - } -} diff --git a/src/main/java/ix/internal/operators/SkipLastIterable.java b/src/main/java/ix/internal/operators/SkipLastIterable.java deleted file mode 100644 index 1bcb7a9..0000000 --- a/src/main/java/ix/internal/operators/SkipLastIterable.java +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright 2011-2016 David Karnok - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package ix.internal.operators; - -import ix.internal.util.CircularBuffer; - -import java.util.Iterator; -import java.util.NoSuchElementException; - -import rx.Notification; - -public final class SkipLastIterable implements Iterable { - /** The source sequence. */ - private final Iterable source; - private final int num; - - public SkipLastIterable(Iterable source, int num) { - this.source = source; - this.num = num; - } - - @Override - public Iterator iterator() { - return new Iterator() { - /** The source iterator. */ - final Iterator it = source.iterator(); - /** The temporary buffer. */ - final CircularBuffer> buffer = new CircularBuffer>(num); - @Override - public boolean hasNext() { - try { - while (buffer.size() < num && it.hasNext()) { - buffer.add(Interactive.some(it.next())); - } - } catch (Throwable t) { - buffer.add(Interactive.err(t)); - } finally { - Interactive.unsubscribe(it); - } - return buffer.size() == num && it.hasNext(); - } - - @Override - public T next() { - if (hasNext()) { - return Interactive.value(buffer.take()); - } - throw new NoSuchElementException(); - } - - @Override - public void remove() { - throw new UnsupportedOperationException(); - } - - }; - } -} \ No newline at end of file diff --git a/src/main/java/ix/internal/operators/SubsequentCountIterable.java b/src/main/java/ix/internal/operators/SubsequentCountIterable.java deleted file mode 100644 index c1cb3eb..0000000 --- a/src/main/java/ix/internal/operators/SubsequentCountIterable.java +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright 2011-2016 David Karnok - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package ix.internal.operators; - -import java.util.ArrayList; -import java.util.Iterator; -import java.util.LinkedList; -import java.util.NoSuchElementException; - -public final class SubsequentCountIterable implements - Iterable> { - /** The source sequence. */ - private final Iterable source; - private final int count; - - public SubsequentCountIterable(Iterable source, int count) { - this.source = source; - this.count = count; - } - - @Override - public Iterator> iterator() { - // get the first count-1 elements - final LinkedList ll = new LinkedList(); - final Iterator it = source.iterator(); - int cnt = 0; - try { - while (it.hasNext() && cnt < count - 1) { - ll.add(it.next()); - cnt++; - } - } finally { - Interactive.unsubscribe(it); - } - if (cnt < count - 1) { - return Interactive.>empty().iterator(); - } - return new Iterator>() { - @Override - public boolean hasNext() { - return it.hasNext(); - } - @Override - public Iterable next() { - if (hasNext()) { - ll.add(it.next()); - ll.removeFirst(); - return new ArrayList(ll); - } - throw new NoSuchElementException(); - } - @Override - public void remove() { - throw new UnsupportedOperationException(); - } - }; - } -} \ No newline at end of file diff --git a/src/main/java/ix/internal/operators/SubsequentIterable.java b/src/main/java/ix/internal/operators/SubsequentIterable.java deleted file mode 100644 index 87d5fef..0000000 --- a/src/main/java/ix/internal/operators/SubsequentIterable.java +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright 2011-2016 David Karnok - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package ix.internal.operators; - -import ix.Pair; - -import java.util.Iterator; -import java.util.NoSuchElementException; - -public final class SubsequentIterable implements - Iterable> { - /** The source sequence. */ - private final Iterable source; - - public SubsequentIterable(Iterable source) { - this.source = source; - } - - @Override - public Iterator> iterator() { - final Iterator it = source.iterator(); - if (!it.hasNext()) { - return Interactive.>empty().iterator(); - } - final T flast = it.next(); - return new Iterator>() { - /** The last source value. */ - T last = flast; - @Override - public boolean hasNext() { - return it.hasNext(); - } - @Override - public Pair next() { - if (hasNext()) { - T curr = it.next(); - Pair ret = Pair.of(last, curr); - last = curr; - return ret; - } - throw new NoSuchElementException(); - } - @Override - public void remove() { - throw new UnsupportedOperationException(); - } - }; - } -} \ No newline at end of file diff --git a/src/main/java/ix/internal/operators/SwitchCaseIterable.java b/src/main/java/ix/internal/operators/SwitchCaseIterable.java deleted file mode 100644 index 9b6789b..0000000 --- a/src/main/java/ix/internal/operators/SwitchCaseIterable.java +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright 2011-2016 David Karnok - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package ix.internal.operators; - -import java.util.Iterator; -import java.util.Map; - -import rx.functions.Func0; - -public final class SwitchCaseIterable implements Iterable { - private final Func0 selector; - private final Map> options; - - public SwitchCaseIterable(Func0 selector, Map> options) { - this.selector = selector; - this.options = options; - } - - @Override - public Iterator iterator() { - Iterable it = options.get(selector.call()); - return it != null ? it.iterator() : Interactive.empty().iterator(); - } -} \ No newline at end of file diff --git a/src/main/java/ix/internal/operators/TakeIterable.java b/src/main/java/ix/internal/operators/TakeIterable.java deleted file mode 100644 index 30271de..0000000 --- a/src/main/java/ix/internal/operators/TakeIterable.java +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright 2011-2016 David Karnok - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package ix.internal.operators; - -import java.util.Iterator; -import java.util.NoSuchElementException; - -/** - * Iterable sequence that takes the first elements of the source sequence. - * - * @param the value type - */ -public final class TakeIterable implements Iterable { - /** The number of items to take. */ - private final int num; - /** The source sequence. */ - private final Iterable source; - /** - * Constructor, initializes the fields. - * @param num the number of items to take - * @param source the source sequence - */ - public TakeIterable(int num, Iterable source) { - this.num = num; - this.source = source; - } - - @Override - public Iterator iterator() { - return new Iterator() { - /** The counter. */ - int count; - /** The source iterator. */ - final Iterator it = source.iterator(); - @Override - public boolean hasNext() { - return count < num && it.hasNext(); - } - - @Override - public T next() { - if (hasNext()) { - count++; - return it.next(); - } - throw new NoSuchElementException(); - } - - @Override - public void remove() { - it.remove(); - } - }; - } -} \ No newline at end of file diff --git a/src/main/java/ix/internal/operators/TakeLastIterable.java b/src/main/java/ix/internal/operators/TakeLastIterable.java deleted file mode 100644 index 5c039d2..0000000 --- a/src/main/java/ix/internal/operators/TakeLastIterable.java +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright 2011-2016 David Karnok - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package ix.internal.operators; - -import ix.internal.util.CircularBuffer; - -import java.util.Iterator; -import java.util.NoSuchElementException; - -import rx.Notification; - -public final class TakeLastIterable implements Iterable { - /** The source sequence. */ - private final Iterable source; - private final int num; - - public TakeLastIterable(Iterable source, int num) { - this.source = source; - this.num = num; - } - - @Override - public Iterator iterator() { - return new Iterator() { - /** The source iterator. */ - final Iterator it = source.iterator(); - /** The temporary buffer. */ - final CircularBuffer> buffer = new CircularBuffer>(num); - @Override - public boolean hasNext() { - try { - while (it.hasNext()) { - buffer.add(Interactive.some(it.next())); - } - } catch (Throwable t) { - buffer.add(Interactive.err(t)); - } finally { - Interactive.unsubscribe(it); - } - return !buffer.isEmpty(); - } - - @Override - public T next() { - if (hasNext()) { - return Interactive.value(buffer.take()); - } - throw new NoSuchElementException(); - } - - @Override - public void remove() { - throw new UnsupportedOperationException(); - } - - }; - } -} \ No newline at end of file diff --git a/src/main/java/ix/internal/operators/ToIterable.java b/src/main/java/ix/internal/operators/ToIterable.java deleted file mode 100644 index 006c409..0000000 --- a/src/main/java/ix/internal/operators/ToIterable.java +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Copyright 2011-2016 David Karnok - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package ix.internal.operators; - -import ix.internal.util.ObservableToIterableAdapter; -import ix.internal.util.ObserverToIteratorSink; -import ix.internal.util.SingleOption; - -import java.util.concurrent.BlockingQueue; -import java.util.concurrent.LinkedBlockingQueue; - -import rx.Notification; -import rx.Observable; -import rx.Subscription; - -/** - * Convert the given observable instance into a classical iterable instance. - *

The resulting iterable does not support the {@code remove()} method.

- * @param the element type to iterate - */ -public final class ToIterable extends ObservableToIterableAdapter { - /** - * Constructor. - * @param observable the observable to convert - */ - public ToIterable(Observable observable) { - super(observable); - } - - @Override - protected ObserverToIteratorSink run(Subscription handle) { - return new ObserverToIteratorSink(handle) { - /** The queue. */ - final BlockingQueue> queue = new LinkedBlockingQueue>(); - @Override - public void onNext(T value) { - queue.add(Notification.createOnNext(value)); - } - - @Override - public void onError(Throwable ex) { - done(); - - queue.add(Notification.createOnError(ex)); - } - - @Override - public void onCompleted() { - done(); - - queue.add(Notification.createOnCompleted()); - } - - @Override - public boolean tryNext(SingleOption out) { - try { - Notification o = queue.take(); - - if (o.isOnCompleted()) { - return false; - } - out.addOption(o); - } catch (InterruptedException ex) { - out.addError(ex); - } - return true; - } - - }; - } -} diff --git a/src/main/java/ix/internal/operators/UsingIterable.java b/src/main/java/ix/internal/operators/UsingIterable.java deleted file mode 100644 index 864fe36..0000000 --- a/src/main/java/ix/internal/operators/UsingIterable.java +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Copyright 2011-2016 David Karnok - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package ix.internal.operators; - -import ix.CloseableIterator; - -import java.io.Closeable; -import java.io.IOException; -import java.util.Iterator; -import java.util.NoSuchElementException; -import java.util.concurrent.atomic.AtomicBoolean; - -import rx.functions.Func0; -import rx.functions.Func1; - -public final class UsingIterable implements Iterable { - private final Func0 resource; - private final Func1> usage; - - public UsingIterable(Func0 resource, - Func1> usage) { - this.resource = resource; - this.usage = usage; - } - - @Override - public Iterator iterator() { - final U c = resource.call(); - return new CloseableIterator() { - /** The iterator. */ - final Iterator it = usage.call(c).iterator(); - /** Run once the it has no more elements. */ - final AtomicBoolean once = new AtomicBoolean(); - @Override - public boolean hasNext() { - if (it.hasNext()) { - return true; - } - unsubscribe(); - return false; - } - - @Override - public boolean isUnsubscribed() { - return once.get(); - } - - @Override - public T next() { - if (hasNext()) { - return it.next(); - } - throw new NoSuchElementException(); - } - @Override - public void remove() { - it.remove(); - } - @Override - public void unsubscribe() { - if (once.compareAndSet(false, true)) { - try { - c.close(); - } catch (IOException ex) { - // ignored - } - } - } - }; - } -} \ No newline at end of file diff --git a/src/main/java/ix/internal/operators/ZipIterable.java b/src/main/java/ix/internal/operators/ZipIterable.java deleted file mode 100644 index 75239aa..0000000 --- a/src/main/java/ix/internal/operators/ZipIterable.java +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Copyright 2011-2016 David Karnok - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package ix.internal.operators; - -import ix.internal.util.SingleContainer; - -import java.util.Iterator; -import java.util.NoSuchElementException; - -import rx.Notification; -import rx.functions.Func2; - -/** - * Iterable sequence containing the zipped values of two other sequences. - * - * @param the first source value type - * @param the second source value type - * @param the result value type - */ -public final class ZipIterable implements Iterable { - /** The first source sequence. */ - private final Iterable left; - /** The second source sequence. */ - private final Iterable right; - /** The function that combines values from the two sources. */ - private final Func2 combiner; - - /** - * Constructor, initializes the fields. - * @param left the first sequence - * @param right the second sequence - * @param combiner the combinator function - */ - public ZipIterable(Iterable left, Iterable right, - Func2 combiner - ) { - this.right = right; - this.combiner = combiner; - this.left = left; - } - - @Override - public Iterator iterator() { - return new Iterator() { - /** The left iterator. */ - final Iterator ts = left.iterator(); - /** The right iterator. */ - final Iterator us = right.iterator(); - /** The peek-ahead container. */ - final SingleContainer> peek = new SingleContainer>(); - @Override - public boolean hasNext() { - if (peek.isEmpty()) { - try { - if (ts.hasNext() && us.hasNext()) { - peek.add(Interactive.some(combiner.call(ts.next(), us.next()))); - } - } catch (Throwable t) { - peek.add(Interactive.err(t)); - } - } - return !peek.isEmpty(); - } - @Override - public V next() { - if (hasNext()) { - return Interactive.value(peek.take()); - } - throw new NoSuchElementException(); - } - @Override - public void remove() { - throw new UnsupportedOperationException(); - } - }; - } -} \ No newline at end of file diff --git a/src/main/java/ix/internal/operators/package-info.java b/src/main/java/ix/internal/operators/package-info.java deleted file mode 100644 index 083a4f8..0000000 --- a/src/main/java/ix/internal/operators/package-info.java +++ /dev/null @@ -1,19 +0,0 @@ -/* - * Copyright 2011-2016 David Karnok - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -/** - * Contains operator implementations. - */ -package ix.internal.operators; \ No newline at end of file diff --git a/src/main/java/ix/internal/util/CircularBuffer.java b/src/main/java/ix/internal/util/CircularBuffer.java deleted file mode 100644 index 90497c4..0000000 --- a/src/main/java/ix/internal/util/CircularBuffer.java +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Copyright 2011-2016 David Karnok - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package ix.internal.util; - -import java.util.NoSuchElementException; - -/** - * A simple circular buffer with absolute indices. - * @param the contained element type - */ -public class CircularBuffer { - /** The buffer. */ - final Object[] buffer; - /** The head pointer. */ - int head; - /** The tail pointer. */ - int tail; - /** - * Construct a new circular buffer. - * @param size the buffer size - */ - public CircularBuffer(int size) { - buffer = new Object[size]; - } - /** - * Add a new value to the buffer. - * If the buffer would overflow, it automatically removes the current head element. - * @param value the value - */ - public void add(T value) { - buffer[(tail++) % buffer.length] = value; - if (size() > buffer.length) { - head++; - } - } - /** - * Retrieve a buffer element based on an absolute index. - * @param index the absolute index - * @return the value - */ - @SuppressWarnings("unchecked") - public T get(int index) { - if (index < head) { - throw new IllegalArgumentException("read before head"); - } - if (index >= tail) { - throw new IllegalArgumentException("read after tail"); - } - return (T)buffer[index % buffer.length]; - } - /** - * @return Takes the head of the buffer. - */ - @SuppressWarnings("unchecked") - public T take() { - if (tail == head) { - throw new NoSuchElementException(); - } - int idx = head++ % buffer.length; - T value = (T)buffer[idx]; - buffer[idx] = null; - return value; - } - /** @return is the buffer empty? */ - public boolean isEmpty() { - return head == tail; - } - /** @return the current size of the buffer. */ - public int size() { - return tail - head; - } - /** @return the current head index. */ - public int head() { - return head; - } - /** @return the current tail index. */ - public int tail() { - return tail; - } -} diff --git a/src/main/java/ix/internal/util/IxHelperFunctions.java b/src/main/java/ix/internal/util/IxHelperFunctions.java deleted file mode 100644 index f29da91..0000000 --- a/src/main/java/ix/internal/util/IxHelperFunctions.java +++ /dev/null @@ -1,548 +0,0 @@ -/* - * Copyright 2011-2016 David Karnok - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package ix.internal.util; - -import java.math.BigDecimal; -import java.math.BigInteger; -import java.util.ArrayList; -import java.util.Comparator; -import java.util.HashMap; -import java.util.HashSet; -import java.util.LinkedHashMap; -import java.util.LinkedList; -import java.util.TreeMap; -import java.util.TreeSet; -import java.util.concurrent.ConcurrentHashMap; - -import rx.functions.Func0; -import rx.functions.Func1; -import rx.functions.Func2; - -/** - * Helper class with function types. - */ -public final class IxHelperFunctions { - /** - * Creates a function which returns always the same value. - * @param the parameter type, irrelevant - * @param the value type to return - * @param value the value to return - * @return the function - */ - public static Func1 constant(final Result value) { - return new Func1() { - @Override - public Result call(Param1 param1) { - return value; - } - }; - } - /** - * Creates a function which returns always the same value. - * @param the value type to return - * @param value the value to return - * @return the function - */ - public static Func0 constant0(final T value) { - return new Func0() { - @Override - public T call() { - return value; - } - }; - } - - /** - * Returns a function which returns the greater of its parameters. - * If only one of the parameters is null, the other parameter is returned. - * If both parameters are null, null is returned. - * @param the parameter types, which must be self-comparable - * @return the function - */ - public static > Func2 max() { - return new Func2() { - @Override - public T call(T param1, T param2) { - if (param1 == null || param2 == null) { - if (param2 == null) { - return param1; - } - return param2; - } - return param1.compareTo(param2) < 0 ? param2 : param1; - } - }; - } - /** - * Returns a function which returns the smaller of its parameters. - * If only one of the parameters is null, the other parameter is returned. - * If both parameters are null, null is returned. - * @param the parameter types, which must be self-comparable - * @return the function - */ - public static > Func2 min() { - return new Func2() { - @Override - public T call(T param1, T param2) { - if (param1 == null || param2 == null) { - if (param2 == null) { - return param1; - } - return param2; - } - return param1.compareTo(param2) > 0 ? param2 : param1; - } - }; - } - /** A helper function which returns its first parameter. */ - private static final Func2 IDENTITY_FIRST = new Func2() { - @Override - public Object call(Object param1, Object param2) { - return param1; - } - }; - /** A helper function which returns its second parameter. */ - private static final Func2 IDENTITY_SECOND = new Func2() { - @Override - public Object call(Object param1, Object param2) { - return param2; - } - }; - /** - * Returns a helper function of two parameters which always returns its first parameter. - * @param the result and the first parameter type - * @param the second parameter type, irrelevant - * @return the function - */ - @SuppressWarnings("unchecked") - public static Func2 identityFirst() { - return (Func2)IDENTITY_FIRST; - } - /** - * Returns a helper function of two parameters which always returns its second parameter. - * @param the result and the second parameter type - * @param the first parameter type, irrelevant - * @return the function - */ - @SuppressWarnings("unchecked") - public static Func2 identitySecond() { - return (Func2)IDENTITY_SECOND; - } - /** - * Returns a function which returns the greater of its parameters in respect to the supplied Comparator. - * If only one of the parameters is null, the other parameter is returned. - * If both parameters are null, null is returned. - * @param the parameter types, which must be self-comparable - * @param comparator the value comparator - * @return the function - */ - public static Func2 max( - final Comparator comparator) { - return new Func2() { - @Override - public T call(T param1, T param2) { - if (param1 == null || param2 == null) { - if (param2 == null) { - return param1; - } - return param2; - } - return comparator.compare(param1, param2) < 0 ? param2 : param1; - } - }; - } - /** - * Returns a function which returns the smaller of its parameters in respect to the supplied Comparator. - * If only one of the parameters is null, the other parameter is returned. - * If both parameters are null, null is returned. - * @param the parameter types, which must be self-comparable - * @param comparator the value comparator - * @return the function - */ - public static Func2 min( - final Comparator comparator) { - return new Func2() { - @Override - public T call(T param1, T param2) { - if (param1 == null || param2 == null) { - if (param2 == null) { - return param1; - } - return param2; - } - return comparator.compare(param1, param2) > 0 ? param2 : param1; - } - }; - } - /** - * Returns a convenience comparator which basically compares - * objects which implement the Comparable - * interface. The comparator is null safe in the manner, - * that nulls are always less than any non-nulls. - * To have a comparator which places nulls last, use the comparator0() method. - * @param the element types to compare - * @return the comparator - * @see IxHelperFunctions#comparator0() - */ - public static > Comparator comparator() { - return new Comparator() { - @Override - public int compare(T o1, T o2) { - if (o1 == null) { - if (o2 == null) { - return 0; - } - return -1; - } - if (o2 == null) { - return 1; - } - return o1.compareTo(o2); - } - }; - } - /** - * Returns a convenience comparator which basically compares objects which implement the Comparable - * interface. The comparator is null safe in the manner, that nulls are always greater than any non-nulls. - * To have a comparator which places nulls first, use the comparator() method. - * @param the element types to compare - * @return the comparator - */ - public static > Comparator comparator0() { - return new Comparator() { - @Override - public int compare(T o1, T o2) { - if (o1 == null) { - if (o2 == null) { - return 0; - } - return 1; - } - if (o2 == null) { - return -1; - } - return o1.compareTo(o2); - } - }; - } - /** - * Creates a new comparator which reverses the order of the comparison. - * @param the element type, which must be self comparable - * @return the new comparator - */ - public static > Comparator comparatorReverse() { - return new Comparator() { - @Override - public int compare(T o1, T o2) { - return o2.compareTo(o1); - } - }; - } - /** - * Creates a new comparator which reverses the order produced by the given - * normal comparator. - * @param the element type - * @param normal the normal comparator - * @return the new comparator - */ - public static Comparator comparatorReverse( - final Comparator normal) { - return new Comparator() { - @Override - public int compare(T o1, T o2) { - return normal.compare(o2, o1); - } - }; - } - /** Function to sum integers in aggregators. */ - static final Func2 SUM_INTEGER = new Func2() { - @Override - public Integer call(Integer param1, Integer param2) { - return param1 != null ? param1 + param2 : param2; - } - }; - /** Function to sum integers in aggregators. */ - static final Func2 SUM_FLOAT = new Func2() { - @Override - public Float call(Float param1, Float param2) { - return param1 != null ? param1 + param2 : param2; - } - }; - /** Function to sum integers in aggregators. */ - static final Func2 SUM_DOUBLE = new Func2() { - @Override - public Double call(Double param1, Double param2) { - return param1 != null ? param1 + param2 : param2; - } - }; - /** Function to sum integers in aggregators. */ - static final Func2 SUM_LONG = new Func2() { - @Override - public Long call(Long param1, Long param2) { - return param1 != null ? param1 + param2 : param2; - } - }; - /** Function to sum integers in aggregators. */ - static final Func2 SUM_BIGINTEGER = new Func2() { - @Override - public BigInteger call(BigInteger param1, BigInteger param2) { - return param1 != null ? param1.add(param2) : param2; - } - }; - /** Function to sum integers in aggregators. */ - static final Func2 SUM_BIGDECIMAL = new Func2() { - @Override - public BigDecimal call(BigDecimal param1, BigDecimal param2) { - return param1 != null ? param1.add(param2) : param2; - } - }; - /** - * Retuns a function that adds two BigDecimal numbers and - * returns a new one. - *

If the first parameter is null, it returns the second parameter.

- * @return Function to sum integers in aggregators. - */ - public static Func2 sumBigDecimal() { - return SUM_BIGDECIMAL; - } - /** - * Retuns a function that adds two BigInteger numbers and - * returns a new one. - *

If the first parameter is null, it returns the second parameter.

- * @return Function to sum integers in aggregators. - */ - public static Func2 sumBigInteger() { - return SUM_BIGINTEGER; - } - /** - * Retuns a function that adds two Double number and - * returns a new one. - *

If the first parameter is null, it returns the second parameter.

- * @return Function to sum integers in aggregators. - */ - public static Func2 sumDouble() { - return SUM_DOUBLE; - } - /** - * Retuns a function that adds two Float number and - * returns a new one. - *

If the first parameter is null, it returns the second parameter.

- * @return Function to sum integers in aggregators. - */ - public static Func2 sumFloat() { - return SUM_FLOAT; - } - /** - * Retuns a function that adds two Integer number and - * returns a new one. - *

If the first parameter is null, it returns the second parameter.

- * @return Function to sum integers in aggregators. - */ - public static Func2 sumInteger() { - return SUM_INTEGER; - } - /** - * Retuns a function that adds two Long number and - * returns a new one. - *

If the first parameter is null, it returns the second parameter.

- * @return Function to sum integers in aggregators. - */ - public static Func2 sumLong() { - return SUM_LONG; - } - /** - * A list creator factory. - * @param the value type - * @return a function which creates a new empty instance of the given concrete list implementation. - */ - public static Func0> arrayListProvider() { - return new Func0>() { - @Override - public ArrayList call() { - return new ArrayList(); - } - }; - } - /** - * A list creator factory for Func1 that ignores the parameter. - * @param the value type - * @param the function parameter type, ignored - * @return a function which creates a new empty instance of - * the given concrete list implementation. - */ - public static Func1> arrayListProvider1() { - return new Func1>() { - @Override - public ArrayList call(U ignored) { - return new ArrayList(); - } - }; - } - /** - * A list creator factory. - * @param the value type - * @return a function which creates a new empty instance of the given concrete list implementation. - */ - public static Func0> linkedListProvider() { - return new Func0>() { - @Override - public LinkedList call() { - return new LinkedList(); - } - }; - } - /** - * A map creator factory. - * @param the key type - * @param the value type - * @return a function which creates a new empty instance of the given concrete map implementation. - */ - public static Func0> hashMapProvider() { - return new Func0>() { - @Override - public HashMap call() { - return new HashMap(); - } - }; - } - /** - * A map creator factory. - * @param the key type - * @param the value type - * @return a function which creates a new empty instance of the given concrete map implementation. - */ - public static Func0> treeMapProvider() { - return new Func0>() { - @Override - public TreeMap call() { - return new TreeMap(); - } - }; - } - /** - * A map creator factory. - * @param the key type - * @param the value type - * @param keyComparator the key comparator function - * @return a function which creates a new empty instance of the given concrete map implementation. - */ - public static Func0> treeMapProvider(final Comparator keyComparator) { - return new Func0>() { - @Override - public TreeMap call() { - return new TreeMap(keyComparator); - } - }; - } - /** - * A map creator factory. - * @param the key type - * @param the value type - * @return a function which creates a new empty instance of the given concrete map implementation. - */ - public static Func0> linkedHashMapProvider() { - return new Func0>() { - @Override - public LinkedHashMap call() { - return new LinkedHashMap(); - } - }; - } - /** - * A map creator factory. - * @param the key type - * @param the value type - * @return a function which creates a new empty instance of the given concrete map implementation. - */ - public static Func0> concurrentHashMapProvider() { - return new Func0>() { - @Override - public ConcurrentHashMap call() { - return new ConcurrentHashMap(); - } - }; - } - /** - * A set creation provider. - * @param the element type - * @return the function which creates an empty instance of the set - */ - public static Func0> hashSetProvider() { - return new Func0>() { - @Override - public HashSet call() { - return new HashSet(); - } - }; - } - /** - * A set creation provider. - * @param the element type - * @return the function which creates an empty instance of the set - */ - public static Func0> treeSetProvider() { - return new Func0>() { - @Override - public TreeSet call() { - return new TreeSet(); - } - }; - } - /** - * A set creation provider. - * @param the element type - * @param elementComparator the custom element comparator - * @return the function which creates an empty instance of the set - */ - public static Func0> treeSetProvider(final Comparator elementComparator) { - return new Func0>() { - @Override - public TreeSet call() { - return new TreeSet(elementComparator); - } - }; - } - /** - * @return Returns a function that negates the incoming boolean value. - */ - public static Func1 negate() { - return new Func1() { - @Override - public Boolean call(Boolean param1) { - return param1 == Boolean.TRUE ? Boolean.FALSE : Boolean.TRUE; - } - }; - } - /** A function that returns its parameter. */ - private static final Func1 IDENTITY = new Func1() { - @Override - public Object call(Object t1) { - return t1; - }; - }; - /** - * @param the input and result type - * @return a function which returns the single parameter value as its result. - */ - @SuppressWarnings("unchecked") - public static Func1 identity() { - return (Func1)IDENTITY; - } - /** Utility class. */ - private IxHelperFunctions() { - } -} diff --git a/src/main/java/ix/internal/util/LinkedBuffer.java b/src/main/java/ix/internal/util/LinkedBuffer.java deleted file mode 100644 index d468581..0000000 --- a/src/main/java/ix/internal/util/LinkedBuffer.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright 2011-2016 David Karnok - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package ix.internal.util; - -/** - * A linked buffer, which can be only filled and queried. - * @param the element type - */ -public final class LinkedBuffer { - /** - * The node. - * @param the element type - */ - public static class N { - /** The element value. */ - public T value; - /** The next node. */ - public LinkedBuffer.N next; - } - /** The head pointer. */ - public final LinkedBuffer.N head = new LinkedBuffer.N(); - /** The tail pointer. */ - public LinkedBuffer.N tail = head; - /** The size. */ - public int size; - /** - * Add a new value. - * @param value the new value - */ - public void add(T value) { - LinkedBuffer.N n = new LinkedBuffer.N(); - n.value = value; - tail.next = n; - tail = n; - size++; - } -} \ No newline at end of file diff --git a/src/main/java/ix/internal/util/ObservableToIterableAdapter.java b/src/main/java/ix/internal/util/ObservableToIterableAdapter.java deleted file mode 100644 index 544a785..0000000 --- a/src/main/java/ix/internal/util/ObservableToIterableAdapter.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright 2011-2016 David Karnok - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package ix.internal.util; - -import ix.CloseableIterable; -import ix.CloseableIterator; -import rx.Observable; -import rx.Subscription; -import rx.subscriptions.CompositeSubscription; - -/** - * Base class to help receive values from an observable sequence - * through customizable iterator and observer. - * @param the observed element type - * @param the iterated element type - */ -public abstract class ObservableToIterableAdapter -implements CloseableIterable { - /** The observable instance. */ - protected final Observable observable; - /** - * Constructor, saves the source observable. - * @param observable the source observable - */ - public ObservableToIterableAdapter(Observable observable) { - this.observable = observable; - } - @Override - public CloseableIterator iterator() { - CompositeSubscription handle = new CompositeSubscription(); - ObserverToIteratorSink it = run(handle); - Subscription c = observable.subscribe(it); - // this won't add C if the handle is already closed - handle.add(c); - return it; - } - /** - * The factory method to return an iterator and hand over the close handle - * to the original registration to the source. - * @param handle the close handle - * @return the closeable iterator - */ - protected abstract ObserverToIteratorSink run(Subscription handle); -} diff --git a/src/main/java/ix/internal/util/ObserverToIteratorSink.java b/src/main/java/ix/internal/util/ObserverToIteratorSink.java deleted file mode 100644 index 171edec..0000000 --- a/src/main/java/ix/internal/util/ObserverToIteratorSink.java +++ /dev/null @@ -1,95 +0,0 @@ -/* - * Copyright 2011-2016 David Karnok - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package ix.internal.util; - -import rx.Observer; -import ix.CloseableIterator; - -import java.util.NoSuchElementException; - -import rx.Subscription; - -/** - * Base class to help transition from reactive to interactive - * world. - * @param the observed type - * @param the returned value type - */ -public abstract class ObserverToIteratorSink implements Observer, - CloseableIterator { - /** Indicate that the stream has finished. */ - protected boolean done; - /** The original handle to the observer registration. */ - protected final Subscription handle; - /** The current value. */ - protected final SingleOption current = new SingleOption(); - /** - * Constructor, saves the handle. - * @param handle the handle to close when the stream finishes. - */ - public ObserverToIteratorSink(Subscription handle) { - this.handle = handle; - } - @Override - public boolean hasNext() { - if (!done) { - if (current.isEmpty()) { - if (!tryNext(current)) { - done = true; - unsubscribe(); - return false; - } - } - return true; - } - return false; - } - - @Override - public U next() { - if (hasNext()) { - if (current.hasError()) { - done = true; - unsubscribe(); - } - return current.take(); - } - throw new NoSuchElementException(); - } - - @Override - public void remove() { - throw new UnsupportedOperationException(); - } - @Override - public void unsubscribe() { - handle.unsubscribe(); - } - @Override - public boolean isUnsubscribed() { - return handle.isUnsubscribed(); - } - /** Closes this iterator and suppresses exceptions. */ - protected void done() { - unsubscribe(); - } - /** - * Try to get the next value. - * @param out the output where to put the value - * @return true if value was available - */ - public abstract boolean tryNext(SingleOption out); -} diff --git a/src/main/java/ix/internal/util/SingleContainer.java b/src/main/java/ix/internal/util/SingleContainer.java deleted file mode 100644 index 652f169..0000000 --- a/src/main/java/ix/internal/util/SingleContainer.java +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright 2011-2016 David Karnok - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package ix.internal.util; - -/** - * Helper class that stores a single element. - * The caller may add a new element only when the container is empty and - * the caller may take the contained element if there is one. - * Use the isEmpty() to check for the status - * The add and take methods might throw IllegalStateException, - * which should indicate a library bug. - * Typically used by the Interactive methods to help them conform with the Iterable contract, - * e.g., hasNext() is idempotent, but next() might - * be called without hasNext() to be called at all. - * The container is not thread-safe. - * @param the contained element type - */ -public class SingleContainer { - /** The currently stored value. */ - T value; - /** The state. */ - boolean empty = true; - /** - * Add a new value. Might throw an IllegalStateException when the container already has a value. - * @param value the new value - */ - public void add(T value) { - if (empty) { - this.value = value; - empty = false; - } else { - throw new IllegalStateException("occupied"); - } - } - /** - * @return the content or throws an IllegalStateException when the container is empty. - */ - public T take() { - if (!empty) { - T v = value; - value = null; - empty = true; - return v; - } - throw new IllegalStateException("empty"); - } - /** - * @return true if there is nothing contained - */ - public boolean isEmpty() { - return empty; - } -} diff --git a/src/main/java/ix/internal/util/SingleOption.java b/src/main/java/ix/internal/util/SingleOption.java deleted file mode 100644 index 034c771..0000000 --- a/src/main/java/ix/internal/util/SingleOption.java +++ /dev/null @@ -1,150 +0,0 @@ -/* - * Copyright 2011-2016 David Karnok - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package ix.internal.util; - -import rx.Notification; -import rx.exceptions.Exceptions; - -/** - * Container that may contain a single value or an exception, but not both. - *

The caller may add a single value or exception to this - * container. Any subsequent add attempt results in IllegalStateException. - *

The caller may retrieve the value or exception from this container, - * which is then removed from the container; the caller may add - * a new value or exception. If the caller attempts to remove - * a value or exception after a value, it will result in IllegalStateException.

- *

The class is not thread safe.

- * @param the contained value type - */ -public final class SingleOption { - /** Indicator for having a value or error. */ - protected boolean hasContent; - /** The contained value. */ - protected T value; - /** The stored exception. */ - protected Throwable error; - /** - * Add a new value to the container. - * The container must be empty. - * @param value the value to add - */ - public void add(T value) { - ensureEmpty(); - hasContent = true; - this.value = value; - } - /** - * Add a new error to the container. - * The container must be empty. - * @param ex the exception to add - */ - public void addError(Throwable ex) { - ensureEmpty(); - hasContent = true; - this.error = ex; - } - /** - * @return test if the container is empty - */ - public boolean isEmpty() { - return !hasContent; - } - /** Throws an IllegalStateException if the container is full. */ - protected void ensureEmpty() { - if (hasContent) { - throw new IllegalStateException("Full"); - } - } - /** Throws an IllegalStateException if the container is empty. */ - protected void ensureFull() { - if (!hasContent) { - throw new IllegalStateException("Empty"); - } - } - /** - * Takes the current value or throws a RuntimeException - * if there is an error instead. - *

The container must be full, and gets empty after the call.

- * @return the value contained - */ - public T take() { - ensureFull(); - hasContent = false; - Throwable t = error; - if (t != null) { - error = null; - Exceptions.propagate(t); - } - T result = value; - value = null; - return result; - } - /** - * Takes just the exception from this container. - * The container becomes empty after the call. - * If the container doesn't hold an exception, an - * IllegalStateException is thrown. - * @return the exception - */ - public Throwable takeError() { - ensureFull(); - Throwable t = error; - if (t != null) { - error = null; - return t; - } - throw new IllegalStateException("no error"); - } - /** - * @return check if there is an error in this container - */ - public boolean hasError() { - return hasContent && error != null; - } - /** - * @return Consumes the content of this container in a form of - * an option instance. The container becomes empty after it. - */ - public Notification option() { - if (hasContent) { - Throwable t = error; - if (t != null) { - error = null; - return Notification.createOnError(t); - } - T v = value; - value = null; - return Notification.createOnNext(v); - } - return Notification.createOnCompleted(); - } - /** - * Add a new optional value to the container. - * The container must be empty. - * Throws IllegalArgumentException if o is None. - * @param o the option to add - */ - public void addOption(Notification o) { - if (o.isOnNext()) { - add(o.getValue()); - } else - if (o.isOnError()) { - addError(o.getThrowable()); - } else { - throw new IllegalArgumentException("OnCompleted Notification has no meaning here"); - } - } -} diff --git a/src/main/java/ix/internal/util/package-info.java b/src/main/java/ix/internal/util/package-info.java deleted file mode 100644 index cb6f35e..0000000 --- a/src/main/java/ix/internal/util/package-info.java +++ /dev/null @@ -1,19 +0,0 @@ -/* - * Copyright 2011-2016 David Karnok - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -/** - * Contains utility classes to support the internal implementations. - */ -package ix.internal.util; \ No newline at end of file diff --git a/src/test/java/ix/CollectTest.java b/src/test/java/ix/CollectTest.java deleted file mode 100644 index a2b7e70..0000000 --- a/src/test/java/ix/CollectTest.java +++ /dev/null @@ -1,80 +0,0 @@ -/* - * Copyright 2011-2016 David Karnok - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package ix; - -import java.util.*; - -import org.junit.*; - -import rx.functions.*; - -public class CollectTest { - - @Test - public void single() { - - Object[] a = Ix.just(1).collect(new Func0>() { - @Override - public Collection call() { - return new ArrayList(); - } - }, new Action2, Integer>() { - @Override - public void call(Collection a, Integer b) { - a.add(b); - } - }).toArray(); - - Assert.assertArrayEquals(new Object[] { Collections.singletonList(1) }, a); - } - - @Test - public void range() { - - Object[] a = Ix.range(1, 3).collect(new Func0>() { - @Override - public Collection call() { - return new ArrayList(); - } - }, new Action2, Integer>() { - @Override - public void call(Collection a, Integer b) { - a.add(b); - } - }).toArray(); - - Assert.assertArrayEquals(new Object[] { Arrays.asList(1, 2, 3) }, a); - } - - @Test - public void empty() { - - Object[] a = Ix.empty().collect(new Func0>() { - @Override - public Collection call() { - return new ArrayList(); - } - }, new Action2, Integer>() { - @Override - public void call(Collection a, Integer b) { - a.add(b); - } - }).toArray(); - - Assert.assertArrayEquals(new Object[] { Collections.emptyList() }, a); - } -} diff --git a/src/test/java/ix/FirstOrDefaultTest.java b/src/test/java/ix/FirstOrDefaultTest.java deleted file mode 100644 index 602ef52..0000000 --- a/src/test/java/ix/FirstOrDefaultTest.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright 2011-2016 David Karnok - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package ix; - -import org.junit.*; - -public class FirstOrDefaultTest { - - @Test - public void nonEmpty() { - int v = Ix.just(1).firstOrDefault(2); - - Assert.assertEquals(1, v); - } - - @Test - public void empty() { - int v = Ix.empty().firstOrDefault(2); - - Assert.assertEquals(2, v); - } - - @Test - public void longerNonEmpty() { - int v = Ix.range(100, 100).firstOrDefault(1); - Assert.assertEquals(100, v); - } -} diff --git a/src/main/java/ix/package-info.java b/src/test/java/ix/IxTest.java similarity index 89% rename from src/main/java/ix/package-info.java rename to src/test/java/ix/IxTest.java index 00133ff..ecfe75e 100644 --- a/src/main/java/ix/package-info.java +++ b/src/test/java/ix/IxTest.java @@ -1,19 +1,21 @@ -/* - * Copyright 2011-2016 David Karnok - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -/** - * Contains exception classes. - */ -package ix; \ No newline at end of file +/* + * Copyright 2011-2016 David Karnok + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ix; + +public class IxTest { + +} diff --git a/src/test/java/ix/LastOrDefaultTest.java b/src/test/java/ix/LastOrDefaultTest.java deleted file mode 100644 index 22879c0..0000000 --- a/src/test/java/ix/LastOrDefaultTest.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright 2011-2016 David Karnok - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package ix; - -import org.junit.*; - -public class LastOrDefaultTest { - - @Test - public void nonEmpty() { - int v = Ix.just(1).lastOrDefault(2); - - Assert.assertEquals(1, v); - } - - @Test - public void empty() { - int v = Ix.empty().lastOrDefault(2); - - Assert.assertEquals(2, v); - } - - @Test - public void longerNonEmpty() { - int v = Ix.range(100, 100).lastOrDefault(1); - Assert.assertEquals(199, v); - } -} diff --git a/src/test/java/ix/LastTest.java b/src/test/java/ix/LastTest.java deleted file mode 100644 index b8155d8..0000000 --- a/src/test/java/ix/LastTest.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright 2011-2016 David Karnok - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package ix; - -import java.util.NoSuchElementException; - -import org.junit.*; - -public class LastTest { - - @Test - public void nonEmpty() { - int v = Ix.just(1).last(); - - Assert.assertEquals(1, v); - } - - @Test(expected = NoSuchElementException.class) - public void empty() { - Ix.empty().last(); - } - - @Test - public void longerNonEmpty() { - int v = Ix.range(100, 100).lastOrDefault(1); - Assert.assertEquals(199, v); - } -} diff --git a/src/test/java/ix/ReduceTest.java b/src/test/java/ix/ReduceTest.java deleted file mode 100644 index 250913a..0000000 --- a/src/test/java/ix/ReduceTest.java +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright 2011-2016 David Karnok - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package ix; - -import org.junit.*; - -import rx.functions.Func2; - -public class ReduceTest { - - @Test - public void single() { - - Object[] a = Ix.just(1).reduce(new Func2() { - @Override - public Integer call(Integer a, Integer b) { - return a + b; - } - }).toArray(); - - Assert.assertArrayEquals(new Object[] { 1 }, a); - } - - @Test - public void range() { - - Object[] a = Ix.range(1, 3).reduce(new Func2() { - @Override - public Integer call(Integer a, Integer b) { - return a + b; - } - }).toArray(); - - Assert.assertArrayEquals(new Object[] { 6 }, a); - } - - @Test - public void empty() { - - Object[] a = Ix.empty().reduce(new Func2() { - @Override - public Integer call(Integer a, Integer b) { - return a + b; - } - }).toArray(); - - Assert.assertArrayEquals(new Object[] { }, a); - } -} diff --git a/src/test/java/ix/SkipTest.java b/src/test/java/ix/SkipTest.java deleted file mode 100644 index cf54ed3..0000000 --- a/src/test/java/ix/SkipTest.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright 2011-2016 David Karnok - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package ix; - -import java.util.*; - -import org.junit.*; - -public class SkipTest { - @Test - public void skipNegative() { - List list = Ix.range(1, 5).skip(-5).toList(); - - Assert.assertEquals(Arrays.asList(1, 2, 3, 4, 5), list); - } - - @Test - public void skipZero() { - List list = Ix.range(1, 5).skip(0).toList(); - - Assert.assertEquals(Arrays.asList(1, 2, 3, 4, 5), list); - } - - @Test - public void skipSome() { - List list = Ix.range(1, 5).skip(2).toList(); - - Assert.assertEquals(Arrays.asList(3, 4, 5), list); - } - - @Test - public void skipAll() { - List list = Ix.range(1, 5).skip(5).toList(); - - Assert.assertEquals(Arrays.asList(), list); - } - - @Test - public void skipMoreThanAll() { - List list = Ix.range(1, 5).skip(10).toList(); - - Assert.assertEquals(Arrays.asList(), list); - } - -} diff --git a/src/test/java/ix/TestInteractiveConcat.java b/src/test/java/ix/TestInteractiveConcat.java deleted file mode 100644 index 08aa468..0000000 --- a/src/test/java/ix/TestInteractiveConcat.java +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright 2011-2016 David Karnok - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package ix; - -import java.util.*; - -import org.junit.*; - -import ix.internal.operators.Interactive; - -/** - * Test the concat operator. - */ -public class TestInteractiveConcat { - /** - * Test if concat works correctly when one of the input sequences is empty. - */ - @Test - public void testConcat() { - Iterable one = Collections.singleton(1); - Iterable empty = Collections.emptySet(); - - List> iterables = new ArrayList>(); - iterables.add(one); - iterables.add(empty); - iterables.add(one); - - Iterable concat = Interactive.concat(iterables); - - List result = new ArrayList(); - for (Integer i : concat) { - result.add(i); - } - TestUtil.assertEqual(Arrays.asList(1, 1), result); - } - /** - * Test if concat item removal works when one of the input sequences is empty. - */ - @Test - public void testConcatRemove() { - List> iterables = new ArrayList>(); - - List list1 = TestUtil.newList(1); - List list2 = TestUtil.newList(1); - iterables.add(list1); - iterables.add(Collections.emptyList()); - iterables.add(list2); - - Iterable concat = Interactive.concat(iterables); - - Iterator it = concat.iterator(); - while (it.hasNext()) { - it.next(); - it.remove(); - } - - Assert.assertEquals(0, list1.size()); - Assert.assertEquals(0, list2.size()); - } - -} diff --git a/src/test/java/ix/TestInteractiveTake.java b/src/test/java/ix/TestInteractiveTake.java deleted file mode 100644 index e778003..0000000 --- a/src/test/java/ix/TestInteractiveTake.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright 2011-2016 David Karnok - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package ix; - -import static ix.internal.operators.Interactive.concat; -import static ix.internal.operators.Interactive.size; -import static ix.internal.operators.Interactive.take; -import static ix.internal.operators.Interactive.toIterable; - -import org.junit.Test; - -/** - * Test the Interactive.take operator. - */ -public class TestInteractiveTake { - /** - * Test take(). - */ - @Test - public void takeOk() { - Iterable prefix = toIterable(1, 2); - Iterable i = concat(prefix, toIterable(3, 4)); - TestUtil.assertEqual(take(i, size(prefix)), prefix); - } - -} diff --git a/src/test/java/ix/TestUtil.java b/src/test/java/ix/TestUtil.java deleted file mode 100644 index 10c30f1..0000000 --- a/src/test/java/ix/TestUtil.java +++ /dev/null @@ -1,119 +0,0 @@ -/* - * Copyright 2011-2016 David Karnok - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package ix; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Iterator; -import java.util.List; - -import org.junit.Assert; - -/** - * Test utility methods. - */ -public final class TestUtil { - /** Utility class. */ - private TestUtil() { } - - /** - * Returns a user-friendly textual representation of the given sequence. - * @param source the source sequence - * @return the output text - */ - public static String makeString( - Iterable source) { - Iterator iterator = Ix.from(source).join(", ").iterator(); - return iterator.hasNext() ? iterator.next() : ""; - } - /** - * Assert the equivalence of two sequences. - * @param the element type - * @param expected the expected sequence - * @param actual the actual sequence - */ - public static void assertEqual( - Iterable expected, - Iterable actual) { - assertCompare(expected, actual, true); - } - /** - * Assert the inequivalence of two sequences. - * @param the element type - * @param expected the expected sequence - * @param actual the actual sequence - */ - public static void assertNotEqual( - Iterable expected, - Iterable actual) { - assertCompare(expected, actual, false); - } - /** - * Creates a new ArrayList from the elements. - * @param the element type - * @param elements the elements - * @return the list - */ - public static List newList(T... elements) { - return new ArrayList(Arrays.asList(elements)); - } - /** - * Compare two sequences and assert their equivalence. - * @param the element type - * @param expected the expected sequence - * @param actual the actual sequence - * @param eq should they equal? - */ - public static void assertCompare( - Iterable expected, - Iterable actual, boolean eq) { - List expectedList = Ix.from(expected).toList(); - List actualList = Ix.from(actual).toList(); - if (eq != expectedList.equals(actualList)) { - fail(expectedList, actualList); - } - } - /** - * Calls the Assert.fail with a message that displays the expected and actual values as strings. - * @param expected the expected sequence - * @param actual the actual sequence - */ - public static void fail( - Iterable expected, - Iterable actual) { - Assert.fail("Sequences mismatch: expected = " + makeString(expected) + ", actual = " + makeString(actual)); - } - /** - * Test if the actual object is assignable to the expected class. - * @param expectedClass the expected class - * @param actual the actual object - */ - public static void assertInstanceof(Class expectedClass, Object actual) { - if (!expectedClass.isInstance(actual)) { - Assert.fail("Not instance, expected = " + expectedClass + ", actual = " + (actual != null ? actual.getClass() : "null")); - } - } - /** - * Test if the actual object is assignable to the expected class. - * @param expectedClass the expected class - * @param actual the actual object - */ - public static void assertNotInstanceof(Class expectedClass, Object actual) { - if (expectedClass.isInstance(actual)) { - Assert.fail("Shouldn't be an instance, expected = " + expectedClass + ", actual = " + (actual != null ? actual.getClass() : "null")); - } - } -} From db3da2685571c88f1c575a9c39273ee8b30c7884 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?D=C3=A1vid=20Karnok?= Date: Wed, 6 Jul 2016 00:38:42 +0200 Subject: [PATCH 02/66] Few basic operators, JMH setup --- build.gradle | 47 ++++-- src/jmh/java/ix/IxPerf.java | 50 +++++++ src/main/java/ix/Ix.java | 190 +++++++++++++++++++++++++ src/main/java/ix/IxBaseIterator.java | 73 ++++++++++ src/main/java/ix/IxCharacters.java | 75 ++++++++++ src/main/java/ix/IxCollect.java | 67 +++++++++ src/main/java/ix/IxEmpty.java | 49 +++++++ src/main/java/ix/IxFilter.java | 50 +++++++ src/main/java/ix/IxJust.java | 68 +++++++++ src/main/java/ix/IxMap.java | 63 ++++++++ src/main/java/ix/IxRange.java | 69 +++++++++ src/main/java/ix/IxReduce.java | 68 +++++++++ src/main/java/ix/IxScalarCallable.java | 30 ++++ src/main/java/ix/IxSource.java | 32 +++++ src/main/java/ix/IxWrapper.java | 32 +++++ src/main/java/ix/Pred.java | 31 ++++ src/main/java/ix/ToListHelper.java | 39 +++++ src/test/java/ix/CharactersTest.java | 32 +++++ src/test/java/ix/CollectTest.java | 43 ++++++ src/test/java/ix/FilterTest.java | 59 ++++++++ src/test/java/ix/IxTestHelper.java | 47 ++++++ src/test/java/ix/JustTest.java | 30 ++++ src/test/java/ix/MapTest.java | 36 +++++ src/test/java/ix/RangeTest.java | 29 ++++ src/test/java/ix/ReduceTest.java | 43 ++++++ 25 files changed, 1344 insertions(+), 8 deletions(-) create mode 100644 src/jmh/java/ix/IxPerf.java create mode 100644 src/main/java/ix/IxBaseIterator.java create mode 100644 src/main/java/ix/IxCharacters.java create mode 100644 src/main/java/ix/IxCollect.java create mode 100644 src/main/java/ix/IxEmpty.java create mode 100644 src/main/java/ix/IxFilter.java create mode 100644 src/main/java/ix/IxJust.java create mode 100644 src/main/java/ix/IxMap.java create mode 100644 src/main/java/ix/IxRange.java create mode 100644 src/main/java/ix/IxReduce.java create mode 100644 src/main/java/ix/IxScalarCallable.java create mode 100644 src/main/java/ix/IxSource.java create mode 100644 src/main/java/ix/IxWrapper.java create mode 100644 src/main/java/ix/Pred.java create mode 100644 src/main/java/ix/ToListHelper.java create mode 100644 src/test/java/ix/CharactersTest.java create mode 100644 src/test/java/ix/CollectTest.java create mode 100644 src/test/java/ix/FilterTest.java create mode 100644 src/test/java/ix/IxTestHelper.java create mode 100644 src/test/java/ix/JustTest.java create mode 100644 src/test/java/ix/MapTest.java create mode 100644 src/test/java/ix/RangeTest.java create mode 100644 src/test/java/ix/ReduceTest.java diff --git a/build.gradle b/build.gradle index 07f3b69..8b38624 100644 --- a/build.gradle +++ b/build.gradle @@ -1,5 +1,20 @@ +buildscript { + repositories { + mavenCentral() + maven { + url "https://plugins.gradle.org/m2/" + } + } + + dependencies { + classpath 'nl.javadude.gradle.plugins:license-gradle-plugin:0.9.0' + classpath "me.champeau.gradle:jmh-gradle-plugin:0.2.0" + } +} + apply plugin: 'java' apply plugin: 'eclipse' +apply plugin: "me.champeau.gradle.jmh" sourceCompatibility = '1.6' targetCompatibility = '1.6' @@ -55,16 +70,32 @@ jar { } } -buildscript { - repositories { - mavenCentral() - } +apply plugin: 'license' - dependencies { - classpath 'nl.javadude.gradle.plugins:license-gradle-plugin:0.9.0' +apply from: file('gradle/license.gradle') + +jmh { + jmhVersion = '1.11.3' + humanOutputFile = null + if (project.hasProperty('jmh')) { + include = ".*" + project.jmh + ".*" + } else { + include = ".*" } } -apply plugin: 'license' +plugins.withType(EclipsePlugin) { + project.eclipse.classpath.plusConfigurations += [ configurations.jmh ] +} -apply from: file('gradle/license.gradle') +javadoc { + failOnError = false +} + +test { + maxHeapSize = "2g" + testLogging { + events "started", "failed" // "skipped", "passed" + // showStandardStreams = true + } +} \ No newline at end of file diff --git a/src/jmh/java/ix/IxPerf.java b/src/jmh/java/ix/IxPerf.java new file mode 100644 index 0000000..0efd963 --- /dev/null +++ b/src/jmh/java/ix/IxPerf.java @@ -0,0 +1,50 @@ +/* + * Copyright 2011-2016 David Karnok + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ix; + +import java.util.concurrent.TimeUnit; + +import org.openjdk.jmh.annotations.*; +import org.openjdk.jmh.infra.Blackhole; + +/** + * Example benchmark. Run from command line as + *
+ * gradle jmh -Pjmh='IxPerf' + */ +@BenchmarkMode(Mode.Throughput) +@Warmup(iterations = 5) +@Measurement(iterations = 5, time = 1, timeUnit = TimeUnit.SECONDS) +@OutputTimeUnit(TimeUnit.SECONDS) +@Fork(value = 1) +@State(Scope.Thread) +public class IxPerf { + +// @Param({"1", "10", "100", "1000", "10000", "100000", "1000000"}) +// public int count; + + @Setup + public void setup(Blackhole bh) { + + } + + @Benchmark + public Object just() { + return new IxJust(1).iterator().next(); + } + +} diff --git a/src/main/java/ix/Ix.java b/src/main/java/ix/Ix.java index e9d2203..73b6902 100644 --- a/src/main/java/ix/Ix.java +++ b/src/main/java/ix/Ix.java @@ -16,6 +16,196 @@ package ix; +import java.util.*; +import java.util.concurrent.Callable; + +import rx.exceptions.Exceptions; +import rx.functions.*; + +/** + * Base class and entry point for fluent iterables. + * @param the value type + */ public abstract class Ix implements Iterable { + public static Ix just(T value) { + return new IxJust(value); + } + + public static Ix empty() { + return IxEmpty.instance(); + } + + /** + * Checks if the value is null and if so, throws + * a NullPointerException with the given message. + * @param the value type + * @param value the value to check for null + * @param message the message to report in the exception + * @return the value + */ + protected static U nullCheck(U value, String message) { + if (value == null) { + throw new NullPointerException(message); + } + return value; + } + + /** + * Convenience method to throw UnsupportedOperationException(); + */ + protected static void unsupported() { + throw new UnsupportedOperationException(); + } + + /** + * Convenience method to throw NoSuchElementException(); + * @param the value type + * @return never returns as it throws + */ + protected static U noelements() { + throw new NoSuchElementException(); + } + + public static Ix from(Iterable source) { + if (source instanceof Ix) { + return (Ix)source; + } + return new IxWrapper(nullCheck(source, "source")); + } + + public static Ix range(int start, int count) { + if (count == 0) { + return empty(); + } + if (count == 1) { + return just(start); + } + return new IxRange(start, count); + } + + public static Ix characters(CharSequence cs) { + return characters(cs, 0, cs.length()); + } + + public static Ix characters(CharSequence cs, int start, int end) { + int len = cs.length(); + if (start < 0 || start + end > len) { + throw new IndexOutOfBoundsException("start=" + start + ", end=" + end + ", length=" + len); + } + return new IxCharacters(cs, start, end); + } + + //--------------------------------------------------------------------------------------- + // Instance operators + //--------------------------------------------------------------------------------------- + + public final Ix map(Func1 mapper) { + return new IxMap(this, mapper); + } + + public final T first() { + if (this instanceof Callable) { + @SuppressWarnings("unchecked") + Callable c = (Callable) this; + + try { + return c.call(); + } catch (Exception ex) { + Exceptions.propagate(ex); + } + } + return iterator().next(); + } + + public final T first(T defaultValue) { + if (this instanceof Callable) { + @SuppressWarnings("unchecked") + Callable c = (Callable) this; + + try { + return c.call(); + } catch (Exception ex) { + Exceptions.propagate(ex); + } + } + Iterator it = iterator(); + if (it.hasNext()) { + return it.next(); + } + return defaultValue; + } + + public final T last() { + if (this instanceof Callable) { + @SuppressWarnings("unchecked") + Callable c = (Callable) this; + + try { + return c.call(); + } catch (Exception ex) { + Exceptions.propagate(ex); + } + } + Iterator it = iterator(); + if (!it.hasNext()) { + return noelements(); + } + + for (;;) { + T t = it.next(); + if (!it.hasNext()) { + return t; + } + } + } + + public final T last(T defaultValue) { + if (this instanceof Callable) { + @SuppressWarnings("unchecked") + Callable c = (Callable) this; + + try { + return c.call(); + } catch (Exception ex) { + Exceptions.propagate(ex); + } + } + Iterator it = iterator(); + if (!it.hasNext()) { + return defaultValue; + } + + for (;;) { + T t = it.next(); + if (!it.hasNext()) { + return t; + } + } + } + + public final Ix filter(Pred predicate) { + return new IxFilter(this, predicate); + } + + public final Ix collect(Func0 initialFactory, Action2 collector) { + return new IxCollect(this, initialFactory, collector); + } + + public final Ix reduce(Func0 initialFactory, Func2 reducer) { + return new IxReduce(this, initialFactory, reducer); + } + + public final Ix hide() { + return new IxWrapper(this); + } + + public final Ix> toList() { + return collect(ToListHelper.initialFactory(), ToListHelper.collector()); + } + + public final Ix toArray() { + return collect(ToListHelper.initialFactory(), ToListHelper.collector()) + .map(ToListHelper.toArray()); + } } diff --git a/src/main/java/ix/IxBaseIterator.java b/src/main/java/ix/IxBaseIterator.java new file mode 100644 index 0000000..8b2587b --- /dev/null +++ b/src/main/java/ix/IxBaseIterator.java @@ -0,0 +1,73 @@ +/* + * Copyright 2011-2016 David Karnok + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ix; + +import java.util.Iterator; + +/** + * A base iterator that references an upstream iterator and manages + * the state between hasNext() and the next() calls. + * @param the source value type + * @param the result value type + */ +abstract class IxBaseIterator implements Iterator { + + protected final Iterator it; + + protected boolean hasValue; + + protected boolean done; + + protected R value; + + public IxBaseIterator(Iterator it) { + this.it = it; + } + + /** + * Move the stream forward by a single element. + * @return what the hasNext should return + */ + protected abstract boolean moveNext(); + + @Override + public final boolean hasNext() { + boolean b = hasValue; + if (!b) { + if (!done) { + return moveNext(); + } + } + return b; + } + + @Override + public R next() { + if (!hasValue && !hasNext()) { + return Ix.noelements(); + } + R v = value; + hasValue = false; + value = null; + return v; + } + + @Override + public void remove() { + Ix.unsupported(); + } +} diff --git a/src/main/java/ix/IxCharacters.java b/src/main/java/ix/IxCharacters.java new file mode 100644 index 0000000..f4bae50 --- /dev/null +++ b/src/main/java/ix/IxCharacters.java @@ -0,0 +1,75 @@ +/* + * Copyright 2011-2016 David Karnok + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ix; + +import java.util.Iterator; + +final class IxCharacters extends Ix { + + final CharSequence source; + + final int start; + + final int end; + + public IxCharacters(CharSequence source, int start, int end) { + this.source = source; + this.start = start; + this.end = end; + } + + @Override + public Iterator iterator() { + return new CharactersIterator(source, start, end); + } + + static final class CharactersIterator implements Iterator { + + final CharSequence source; + + final int end; + + int index; + + public CharactersIterator(CharSequence source, int start, int end) { + this.source = source; + this.index = start; + this.end = end; + } + + @Override + public boolean hasNext() { + return index != end; + } + + @Override + public Integer next() { + int i = index; + if (i != end) { + index = i + 1; + return (int)source.charAt(i); + } + return noelements(); + } + + @Override + public void remove() { + unsupported(); + } + } + +} diff --git a/src/main/java/ix/IxCollect.java b/src/main/java/ix/IxCollect.java new file mode 100644 index 0000000..e8fe276 --- /dev/null +++ b/src/main/java/ix/IxCollect.java @@ -0,0 +1,67 @@ +/* + * Copyright 2011-2016 David Karnok + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ix; + +import java.util.Iterator; + +import rx.functions.*; + +final class IxCollect extends IxSource { + + final Func0 initialFactory; + + final Action2 collector; + + public IxCollect(Iterable source, Func0 initialFactory, Action2 collector) { + super(source); + this.initialFactory = initialFactory; + this.collector = collector; + } + + @Override + public Iterator iterator() { + return new CollectorIterator(source.iterator(), collector, initialFactory.call()); + } + + static final class CollectorIterator extends IxBaseIterator { + + final Action2 collector; + + public CollectorIterator(Iterator it, Action2 collector, C value) { + super(it); + this.collector = collector; + this.value = value; + } + + @Override + protected boolean moveNext() { + Iterator it = this.it; + + Action2 coll = collector; + + C c = value; + + while (it.hasNext()) { + coll.call(c, it.next()); + } + + hasValue = true; + done = true; + return true; + } + } +} diff --git a/src/main/java/ix/IxEmpty.java b/src/main/java/ix/IxEmpty.java new file mode 100644 index 0000000..9bc9d2d --- /dev/null +++ b/src/main/java/ix/IxEmpty.java @@ -0,0 +1,49 @@ +/* + * Copyright 2011-2016 David Karnok + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ix; + +import java.util.*; + +final class IxEmpty extends Ix implements Iterator { + + static final IxEmpty INSTANCE = new IxEmpty(); + + @SuppressWarnings("unchecked") + static Ix instance() { + return (Ix)INSTANCE; + } + + @Override + public Iterator iterator() { + return this; + } + + @Override + public boolean hasNext() { + return false; + } + + @Override + public Object next() { + return noelements(); + } + + @Override + public void remove() { + unsupported(); + } +} diff --git a/src/main/java/ix/IxFilter.java b/src/main/java/ix/IxFilter.java new file mode 100644 index 0000000..4e2be24 --- /dev/null +++ b/src/main/java/ix/IxFilter.java @@ -0,0 +1,50 @@ +package ix; + +import java.util.Iterator; + +final class IxFilter extends IxSource { + + final Pred predicate; + + public IxFilter(Iterable source, Pred predicate) { + super(source); + this.predicate = predicate; + } + + @Override + public Iterator iterator() { + return new FilterIterator(source.iterator(), predicate); + } + + static final class FilterIterator extends IxBaseIterator { + + final Pred predicate; + + public FilterIterator(Iterator it, Pred predicate) { + super(it); + this.predicate = predicate; + } + + @Override + protected boolean moveNext() { + for (;;) { + if (it.hasNext()) { + T v = it.next(); + if (predicate.test(v)) { + value = v; + hasValue = true; + return true; + } + } else { + done = true; + return false; + } + } + } + + @Override + public void remove() { + it.remove(); + } + } +} diff --git a/src/main/java/ix/IxJust.java b/src/main/java/ix/IxJust.java new file mode 100644 index 0000000..4f19e41 --- /dev/null +++ b/src/main/java/ix/IxJust.java @@ -0,0 +1,68 @@ +/* + * Copyright 2011-2016 David Karnok + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ix; + +import java.util.*; + +final class IxJust extends Ix implements IxScalarCallable { + + final T value; + + public IxJust(T value) { + this.value = value; + } + + @Override + public T call() { + return value; + } + + @Override + public Iterator iterator() { + return new JustIterator(value); + } + + static final class JustIterator implements Iterator { + + final T value; + + boolean empty; + + public JustIterator(T value) { + this.value = value; + } + + @Override + public boolean hasNext() { + return empty; + } + + @Override + public T next() { + if (!empty) { + empty = true; + return value; + } + return noelements(); + } + + @Override + public void remove() { + unsupported(); + } + } +} diff --git a/src/main/java/ix/IxMap.java b/src/main/java/ix/IxMap.java new file mode 100644 index 0000000..b542f4f --- /dev/null +++ b/src/main/java/ix/IxMap.java @@ -0,0 +1,63 @@ +/* + * Copyright 2011-2016 David Karnok + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ix; + +import java.util.Iterator; + +import rx.functions.Func1; + +final class IxMap extends IxSource { + + final Func1 mapper; + + public IxMap(Iterable source, Func1 mapper) { + super(source); + this.mapper = mapper; + } + + @Override + public Iterator iterator() { + return new MapIterator(source.iterator(), mapper); + } + + static final class MapIterator implements Iterator { + + final Iterator it; + + final Func1 mapper; + + public MapIterator(Iterator it, Func1 mapper) { + this.it = it; + this.mapper = mapper; + } + + @Override + public boolean hasNext() { + return it.hasNext(); + } + + @Override + public R next() { + return mapper.call(it.next()); + } + + @Override + public void remove() { + it.remove(); + } + } +} diff --git a/src/main/java/ix/IxRange.java b/src/main/java/ix/IxRange.java new file mode 100644 index 0000000..0261194 --- /dev/null +++ b/src/main/java/ix/IxRange.java @@ -0,0 +1,69 @@ +/* + * Copyright 2011-2016 David Karnok + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ix; + +import java.util.Iterator; + +final class IxRange extends Ix { + + final int start; + + final int end; + + public IxRange(int start, int count) { + this.start = start; + this.end = start + count; + } + + @Override + public Iterator iterator() { + return new RangeIterator(start, end); + } + + static final class RangeIterator implements Iterator { + + final int end; + + int index; + + public RangeIterator(int start, int end) { + this.index = start; + this.end = end; + } + + @Override + public boolean hasNext() { + return index != end; + } + + @Override + public Integer next() { + int i = index; + if (i != end) { + index = i + 1; + return i; + } + return noelements(); + } + + @Override + public void remove() { + unsupported(); + } + } + +} diff --git a/src/main/java/ix/IxReduce.java b/src/main/java/ix/IxReduce.java new file mode 100644 index 0000000..3fa977b --- /dev/null +++ b/src/main/java/ix/IxReduce.java @@ -0,0 +1,68 @@ +/* + * Copyright 2011-2016 David Karnok + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ix; + +import java.util.Iterator; + +import rx.functions.*; + +final class IxReduce extends IxSource { + + final Func0 initialFactory; + + final Func2 reducer; + + public IxReduce(Iterable source, Func0 initialFactory, Func2 reducer) { + super(source); + this.initialFactory = initialFactory; + this.reducer = reducer; + } + + @Override + public Iterator iterator() { + return new CollectorIterator(source.iterator(), reducer, initialFactory.call()); + } + + static final class CollectorIterator extends IxBaseIterator { + + final Func2 reducer; + + public CollectorIterator(Iterator it, Func2 reducer, C value) { + super(it); + this.reducer = reducer; + this.value = value; + } + + @Override + protected boolean moveNext() { + Iterator it = this.it; + + Func2 f = reducer; + + C c = value; + + while (it.hasNext()) { + c = f.call(c, it.next()); + } + + value = c; + hasValue = true; + done = true; + return true; + } + } +} diff --git a/src/main/java/ix/IxScalarCallable.java b/src/main/java/ix/IxScalarCallable.java new file mode 100644 index 0000000..dfbcefa --- /dev/null +++ b/src/main/java/ix/IxScalarCallable.java @@ -0,0 +1,30 @@ +/* + * Copyright 2011-2016 David Karnok + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ix; + +import java.util.concurrent.Callable; + +/** + * Marker interface to indicate a source that has exactly one constant + * value, available for assembly-time optimizations. + * @param the value type + */ +public interface IxScalarCallable extends Callable { + + @Override + T call(); +} diff --git a/src/main/java/ix/IxSource.java b/src/main/java/ix/IxSource.java new file mode 100644 index 0000000..4ef6f3c --- /dev/null +++ b/src/main/java/ix/IxSource.java @@ -0,0 +1,32 @@ +/* + * Copyright 2011-2016 David Karnok + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ix; + +/** + * Abstract base class for Ix operators that take a source Iterable. + * @param the source value type + * @param the result value type + */ +abstract class IxSource extends Ix { + + protected final Iterable source; + + public IxSource(Iterable source) { + this.source = source; + } + +} diff --git a/src/main/java/ix/IxWrapper.java b/src/main/java/ix/IxWrapper.java new file mode 100644 index 0000000..e8c0fac --- /dev/null +++ b/src/main/java/ix/IxWrapper.java @@ -0,0 +1,32 @@ +/* + * Copyright 2011-2016 David Karnok + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ix; + +import java.util.Iterator; + +final class IxWrapper extends IxSource { + + public IxWrapper(Iterable source) { + super(source); + } + + @Override + public Iterator iterator() { + return source.iterator(); + } + +} diff --git a/src/main/java/ix/Pred.java b/src/main/java/ix/Pred.java new file mode 100644 index 0000000..390f87f --- /dev/null +++ b/src/main/java/ix/Pred.java @@ -0,0 +1,31 @@ +/* + * Copyright 2011-2016 David Karnok + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ix; + +/** + * A predicate functional interface to test a value and return a primitive + * boolean. + * @param the value to test + */ +public interface Pred { + /** + * Test the given value. + * @param t the value to test + * @return true if the value passes the test + */ + boolean test(T t); +} diff --git a/src/main/java/ix/ToListHelper.java b/src/main/java/ix/ToListHelper.java new file mode 100644 index 0000000..275b655 --- /dev/null +++ b/src/main/java/ix/ToListHelper.java @@ -0,0 +1,39 @@ +package ix; + +import java.util.*; + +import rx.functions.*; + +enum ToListHelper implements Func0>, Action2, Object>, Func1, Object[]> { + INSTANCE; + + @SuppressWarnings({ "rawtypes", "unchecked" }) + public static Func0> initialFactory() { + return (Func0)INSTANCE; + } + + @SuppressWarnings({ "rawtypes", "unchecked" }) + public static Action2, T> collector() { + return (Action2)INSTANCE; + } + + @SuppressWarnings({ "rawtypes", "unchecked" }) + public static Func1, Object[]> toArray() { + return (Func1)INSTANCE; + } + @Override + public void call(List t1, Object t2) { + t1.add(t2); + } + + @Override + public List call() { + return new ArrayList(); + } + + @Override + public Object[] call(List t) { + return t.toArray(); + } + +} diff --git a/src/test/java/ix/CharactersTest.java b/src/test/java/ix/CharactersTest.java new file mode 100644 index 0000000..215c760 --- /dev/null +++ b/src/test/java/ix/CharactersTest.java @@ -0,0 +1,32 @@ +/* + * Copyright 2011-2016 David Karnok + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ix; + +import org.junit.Test; + +public class CharactersTest { + + @Test + public void normal() { + Ix source = Ix.characters("Hello world!"); + + IxTestHelper.assertValues(source, + (int)'H', (int)'e', (int)'l', (int)'l', + (int)'o', (int)' ', (int)'w', (int)'o', (int)'r', (int)'l', + (int)'d', (int)'!'); + } +} diff --git a/src/test/java/ix/CollectTest.java b/src/test/java/ix/CollectTest.java new file mode 100644 index 0000000..4def9d8 --- /dev/null +++ b/src/test/java/ix/CollectTest.java @@ -0,0 +1,43 @@ +/* + * Copyright 2011-2016 David Karnok + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ix; + +import org.junit.Test; + +import rx.functions.*; + +import static org.junit.Assert.*; + +public class CollectTest { + + @Test + public void normal() { + Ix source = Ix.range(1, 10).collect(new Func0() { + @Override + public Integer[] call() { + return new Integer[] { 0 }; + } + }, new Action2() { + @Override + public void call(Integer[] a, Integer b) { + a[0] += b; + } + }); + + assertEquals(55, source.first()[0].intValue()); + } +} diff --git a/src/test/java/ix/FilterTest.java b/src/test/java/ix/FilterTest.java new file mode 100644 index 0000000..cb22522 --- /dev/null +++ b/src/test/java/ix/FilterTest.java @@ -0,0 +1,59 @@ +/* + * Copyright 2011-2016 David Karnok + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ix; + +import org.junit.Test; + +public class FilterTest { + + @Test + public void normal() { + Ix source = Ix.range(1, 10).filter(new Pred() { + @Override + public boolean test(Integer v) { + return (v & 1) != 0; + } + }); + + IxTestHelper.assertValues(source, 1, 3, 5, 7, 9); + } + + @Test + public void empty() { + Ix source = Ix.empty().filter(new Pred() { + @Override + public boolean test(Integer v) { + return (v & 1) != 0; + } + }); + + IxTestHelper.assertValues(source); + } + + @Test + public void empty2() { + Ix source = Ix.just(0).filter(new Pred() { + @Override + public boolean test(Integer v) { + return (v & 1) != 0; + } + }); + + IxTestHelper.assertValues(source); + } + +} diff --git a/src/test/java/ix/IxTestHelper.java b/src/test/java/ix/IxTestHelper.java new file mode 100644 index 0000000..0c9e17e --- /dev/null +++ b/src/test/java/ix/IxTestHelper.java @@ -0,0 +1,47 @@ +/* + * Copyright 2011-2016 David Karnok + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ix; + +import org.junit.Assert; + +public enum IxTestHelper { + ; + + static String classOf(Object o) { + return o != null ? o.getClass().getSimpleName() : "null"; + } + + public static void assertValues(Iterable source, T... values) { + int i = 0; + + for (T t : source) { + if (i == values.length) { + throw new AssertionError("The source is longer than " + values.length); + } + Assert.assertEquals("index=" + i + ", expected class=" + + classOf(values[i]) + + ", actual class=" + + classOf(t), values[i], t); + i++; + } + + if (i != values.length) { + throw new AssertionError("The source is shorter than " + values.length); + } + + } +} diff --git a/src/test/java/ix/JustTest.java b/src/test/java/ix/JustTest.java new file mode 100644 index 0000000..a60b71f --- /dev/null +++ b/src/test/java/ix/JustTest.java @@ -0,0 +1,30 @@ +/* + * Copyright 2011-2016 David Karnok + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ix; + +import org.junit.Test; +import static org.junit.Assert.*; + +public class JustTest { + + @Test + public void normal() { + Ix source = Ix.just(1); + + assertEquals(1, source.iterator().next().intValue()); + } +} diff --git a/src/test/java/ix/MapTest.java b/src/test/java/ix/MapTest.java new file mode 100644 index 0000000..2bddf06 --- /dev/null +++ b/src/test/java/ix/MapTest.java @@ -0,0 +1,36 @@ +/* + * Copyright 2011-2016 David Karnok + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ix; + +import org.junit.Test; + +import rx.functions.Func1; + +public class MapTest { + + @Test + public void normal() { + Ix source = Ix.range(1, 10).map(new Func1() { + @Override + public Integer call(Integer v) { + return v + 1; + } + }); + + IxTestHelper.assertValues(source, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11); + } +} diff --git a/src/test/java/ix/RangeTest.java b/src/test/java/ix/RangeTest.java new file mode 100644 index 0000000..fb3347d --- /dev/null +++ b/src/test/java/ix/RangeTest.java @@ -0,0 +1,29 @@ +/* + * Copyright 2011-2016 David Karnok + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ix; + +import org.junit.Test; + +public class RangeTest { + + @Test + public void normal() { + Ix source = Ix.range(1, 10); + + IxTestHelper.assertValues(source, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10); + } +} diff --git a/src/test/java/ix/ReduceTest.java b/src/test/java/ix/ReduceTest.java new file mode 100644 index 0000000..b66d8a1 --- /dev/null +++ b/src/test/java/ix/ReduceTest.java @@ -0,0 +1,43 @@ +/* + * Copyright 2011-2016 David Karnok + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ix; + +import org.junit.Test; + +import rx.functions.*; + +import static org.junit.Assert.*; + +public class ReduceTest { + + @Test + public void normal() { + Ix source = Ix.range(1, 10).reduce(new Func0() { + @Override + public Integer call() { + return 0; + } + }, new Func2() { + @Override + public Integer call(Integer a, Integer b) { + return a + b; + } + }); + + assertEquals(55, source.first().intValue()); + } +} From f07744cdaae8050948e21dfd6f05bd9be69abc7b Mon Sep 17 00:00:00 2001 From: akarnokd Date: Wed, 6 Jul 2016 15:23:45 +0200 Subject: [PATCH 03/66] Several operators, code checkers, perf additions, badges --- README.md | 3 + build.gradle | 68 +++++- gradle.properties | 2 +- pmd.xml | 223 ++++++++++++++++++ src/jmh/java/ix/FlattenIterableArrayPerf.java | 95 ++++++++ src/jmh/java/ix/FlattenIterablePerf.java | 88 +++++++ src/jmh/java/ix/RangePerf.java | 81 +++++++ src/jmh/java/ix/ReducePerf.java | 61 +++++ src/main/java/ix/FunctionHelper.java | 38 +++ src/main/java/ix/Ix.java | 117 +++++++++ src/main/java/ix/IxAggregate.java | 65 +++++ src/main/java/ix/IxBaseIterator.java | 18 +- src/main/java/ix/IxCollect.java | 2 +- src/main/java/ix/IxFilter.java | 18 +- src/main/java/ix/IxFlattenArrayIterable.java | 94 ++++++++ src/main/java/ix/IxFlattenIterable.java | 101 ++++++++ src/main/java/ix/IxFromArray.java | 55 +++++ src/main/java/ix/IxJust.java | 2 +- src/main/java/ix/IxMaxInt.java | 58 +++++ src/main/java/ix/IxMaxLong.java | 58 +++++ src/main/java/ix/IxMinInt.java | 58 +++++ src/main/java/ix/IxMinLong.java | 58 +++++ src/main/java/ix/IxReduce.java | 2 +- src/main/java/ix/IxSkip.java | 70 ++++++ src/main/java/ix/IxSkipLast.java | 82 +++++++ src/main/java/ix/IxSourceIterator.java | 36 +++ src/main/java/ix/IxSourceQueuedIterator.java | 121 ++++++++++ src/main/java/ix/IxSumInt.java | 58 +++++ src/main/java/ix/IxSumLong.java | 58 +++++ src/main/java/ix/IxTake.java | 59 +++++ src/main/java/ix/IxTakeLast.java | 72 ++++++ src/main/java/ix/ReduceHelper.java | 86 +++++++ src/main/java/ix/ToListHelper.java | 16 ++ src/test/java/ix/AggregateTest.java | 47 ++++ src/test/java/ix/ConcatArrayTest.java | 70 ++++++ src/test/java/ix/FlattenIterableTest.java | 61 +++++ src/test/java/ix/FromArrayTest.java | 37 +++ src/test/java/ix/JustTest.java | 2 + src/test/java/ix/MaxTest.java | 67 ++++++ src/test/java/ix/MinTest.java | 67 ++++++ src/test/java/ix/SkipLastTest.java | 87 +++++++ src/test/java/ix/SkipTest.java | 58 +++++ src/test/java/ix/SumTest.java | 67 ++++++ src/test/java/ix/TakeLastTest.java | 87 +++++++ src/test/java/ix/TakeTest.java | 65 +++++ 45 files changed, 2721 insertions(+), 17 deletions(-) create mode 100644 pmd.xml create mode 100644 src/jmh/java/ix/FlattenIterableArrayPerf.java create mode 100644 src/jmh/java/ix/FlattenIterablePerf.java create mode 100644 src/jmh/java/ix/RangePerf.java create mode 100644 src/jmh/java/ix/ReducePerf.java create mode 100644 src/main/java/ix/FunctionHelper.java create mode 100644 src/main/java/ix/IxAggregate.java create mode 100644 src/main/java/ix/IxFlattenArrayIterable.java create mode 100644 src/main/java/ix/IxFlattenIterable.java create mode 100644 src/main/java/ix/IxFromArray.java create mode 100644 src/main/java/ix/IxMaxInt.java create mode 100644 src/main/java/ix/IxMaxLong.java create mode 100644 src/main/java/ix/IxMinInt.java create mode 100644 src/main/java/ix/IxMinLong.java create mode 100644 src/main/java/ix/IxSkip.java create mode 100644 src/main/java/ix/IxSkipLast.java create mode 100644 src/main/java/ix/IxSourceIterator.java create mode 100644 src/main/java/ix/IxSourceQueuedIterator.java create mode 100644 src/main/java/ix/IxSumInt.java create mode 100644 src/main/java/ix/IxSumLong.java create mode 100644 src/main/java/ix/IxTake.java create mode 100644 src/main/java/ix/IxTakeLast.java create mode 100644 src/main/java/ix/ReduceHelper.java create mode 100644 src/test/java/ix/AggregateTest.java create mode 100644 src/test/java/ix/ConcatArrayTest.java create mode 100644 src/test/java/ix/FlattenIterableTest.java create mode 100644 src/test/java/ix/FromArrayTest.java create mode 100644 src/test/java/ix/MaxTest.java create mode 100644 src/test/java/ix/MinTest.java create mode 100644 src/test/java/ix/SkipLastTest.java create mode 100644 src/test/java/ix/SkipTest.java create mode 100644 src/test/java/ix/SumTest.java create mode 100644 src/test/java/ix/TakeLastTest.java create mode 100644 src/test/java/ix/TakeTest.java diff --git a/README.md b/README.md index 3ac5707..cfaba77 100644 --- a/README.md +++ b/README.md @@ -11,6 +11,9 @@ and interactive dataflows.** # Releases +[![codecov.io](http://codecov.io/github/akarnokd/ixjava/coverage.svg?branch=1.x)](http://codecov.io/github/akarnokd/ixjava?branch=1.x) +[![Maven Central](https://maven-badges.herokuapp.com/maven-central/com.github.akarnokd/ixjava/badge.svg)](https://maven-badges.herokuapp.com/maven-central/com.github.akarnokd/ixjava) + **gradle** diff --git a/build.gradle b/build.gradle index 8b38624..0c2d00b 100644 --- a/build.gradle +++ b/build.gradle @@ -7,14 +7,19 @@ buildscript { } dependencies { - classpath 'nl.javadude.gradle.plugins:license-gradle-plugin:0.9.0' + classpath 'gradle.plugin.nl.javadude.gradle.plugins:license-gradle-plugin:0.13.1' classpath "me.champeau.gradle:jmh-gradle-plugin:0.2.0" + classpath 'ru.vyarus:gradle-animalsniffer-plugin:1.1.0' } } apply plugin: 'java' apply plugin: 'eclipse' apply plugin: "me.champeau.gradle.jmh" +apply plugin: 'pmd' +apply plugin: 'jacoco' +apply plugin: 'ru.vyarus.animalsniffer' +apply plugin: "com.github.hierynomus.license" sourceCompatibility = '1.6' targetCompatibility = '1.6' @@ -40,7 +45,10 @@ apply plugin: 'maven' apply plugin: 'osgi' dependencies { + signature 'org.codehaus.mojo.signature:java16:1.1@signature' + compile "io.reactivex:rxjava:1.1.6" + testCompile group: 'junit', name: 'junit', version: '4.12' } @@ -98,4 +106,60 @@ test { events "started", "failed" // "skipped", "passed" // showStandardStreams = true } -} \ No newline at end of file +} + +license { + excludes(["**/*.md", "**/*.txt"]) +} + +jacoco { + toolVersion = '0.7.7.201606060606' // See http://www.eclemma.org/jacoco/. +} + +jacocoTestReport { + reports { + xml.enabled = true + html.enabled = true + } +} + +build.dependsOn jacocoTestReport + +pmd { + toolVersion = '5.4.2' + ignoreFailures = true + sourceSets = [sourceSets.main] + ruleSets = [] + ruleSetFiles = files('pmd.xml') + +} + +pmdMain { + reports { + html.enabled = true + xml.enabled = true + } +} + +task pmdPrint(dependsOn: 'pmdMain') << { + File file = new File('build/reports/pmd/main.xml') + if (file.exists()) { + + println("Listing first 100 PMD violations") + + file.eachLine { line, count -> + if (count <= 100) { + println(line) + } + } + + } else { + println("PMD file not found.") + } +} + +build.dependsOn pmdPrint + +animalsniffer { + annotation = 'rx.internal.util.SuppressAnimalSniffer' +} diff --git a/gradle.properties b/gradle.properties index aef125e..07533ff 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1 +1 @@ -version=1.0.0 +version=1.0.0-M0 diff --git a/pmd.xml b/pmd.xml new file mode 100644 index 0000000..339af7d --- /dev/null +++ b/pmd.xml @@ -0,0 +1,223 @@ + + + RxJava PMD ruleset + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/jmh/java/ix/FlattenIterableArrayPerf.java b/src/jmh/java/ix/FlattenIterableArrayPerf.java new file mode 100644 index 0000000..1c997c8 --- /dev/null +++ b/src/jmh/java/ix/FlattenIterableArrayPerf.java @@ -0,0 +1,95 @@ +/* + * Copyright 2011-2016 David Karnok + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ix; + +import java.util.Arrays; +import java.util.concurrent.TimeUnit; + +import org.openjdk.jmh.annotations.*; +import org.openjdk.jmh.infra.Blackhole; + +import rx.functions.Func1; + +/** + * Example benchmark. Run from command line as + *
+ * gradle jmh -Pjmh='IxPerf' + */ +@BenchmarkMode(Mode.Throughput) +@Warmup(iterations = 5) +@Measurement(iterations = 5, time = 1, timeUnit = TimeUnit.SECONDS) +@OutputTimeUnit(TimeUnit.SECONDS) +@Fork(value = 1) +@State(Scope.Thread) +public class FlattenIterableArrayPerf implements Func1> { + + @Param({"1", "10", "100", "1000", "10000", "100000", "1000000"}) + public int count; + + Ix source; + + Ix inner; + + Ix flatMapJust; + + @Override + public Iterable call(Integer t) { + return inner; + } + + @Setup + public void setup(Blackhole bh) { + + int d = 1000000 / count; + + Integer[] countArray = new Integer[count]; + Arrays.fill(countArray, 777); + + inner = Ix.fromArray(countArray); + + Integer[] sourceArray = new Integer[d]; + Arrays.fill(sourceArray, 777); + + source = Ix.fromArray(sourceArray).flatMap(this); + + flatMapJust = inner.flatMap(new Func1>() { + @Override + public Iterable call(Integer v) { + return Ix.just(v); + } + }); + } + + @Benchmark + public Object xrangeLast() { + return source.last(); + } + + @Benchmark + public void xrangeEach(Blackhole bh) { + for (Integer i : source) { + bh.consume(i); + } + } + + @Benchmark + public void flatMapJust(Blackhole bh) { + for (Integer i : flatMapJust) { + bh.consume(i); + } + } +} diff --git a/src/jmh/java/ix/FlattenIterablePerf.java b/src/jmh/java/ix/FlattenIterablePerf.java new file mode 100644 index 0000000..5fa5275 --- /dev/null +++ b/src/jmh/java/ix/FlattenIterablePerf.java @@ -0,0 +1,88 @@ +/* + * Copyright 2011-2016 David Karnok + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ix; + +import java.util.concurrent.TimeUnit; + +import org.openjdk.jmh.annotations.*; +import org.openjdk.jmh.infra.Blackhole; + +import rx.functions.Func1; + +/** + * Example benchmark. Run from command line as + *
+ * gradle jmh -Pjmh='IxPerf' + */ +@BenchmarkMode(Mode.Throughput) +@Warmup(iterations = 5) +@Measurement(iterations = 5, time = 1, timeUnit = TimeUnit.SECONDS) +@OutputTimeUnit(TimeUnit.SECONDS) +@Fork(value = 1) +@State(Scope.Thread) +public class FlattenIterablePerf implements Func1> { + + @Param({"1", "10", "100", "1000", "10000", "100000", "1000000"}) + public int count; + + Ix source; + + Ix inner; + + Ix flatMapJust; + + @Override + public Iterable call(Integer t) { + return inner; + } + + @Setup + public void setup(Blackhole bh) { + + int d = 1000000 / count; + + inner = Ix.range(1, count); + + source = Ix.range(1, d).flatMap(this); + + flatMapJust = Ix.range(1, count).flatMap(new Func1>() { + @Override + public Iterable call(Integer v) { + return Ix.just(v); + } + }); + } + + @Benchmark + public Object xrangeLast() { + return source.last(); + } + + @Benchmark + public void xrangeEach(Blackhole bh) { + for (Integer i : source) { + bh.consume(i); + } + } + + @Benchmark + public void flatMapJust(Blackhole bh) { + for (Integer i : flatMapJust) { + bh.consume(i); + } + } +} diff --git a/src/jmh/java/ix/RangePerf.java b/src/jmh/java/ix/RangePerf.java new file mode 100644 index 0000000..7eb7ee2 --- /dev/null +++ b/src/jmh/java/ix/RangePerf.java @@ -0,0 +1,81 @@ +/* + * Copyright 2011-2016 David Karnok + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ix; + +import java.util.concurrent.TimeUnit; + +import org.openjdk.jmh.annotations.*; +import org.openjdk.jmh.infra.Blackhole; + +import rx.functions.Func1; + +/** + * Example benchmark. Run from command line as + *
+ * gradle jmh -Pjmh='IxPerf' + */ +@BenchmarkMode(Mode.Throughput) +@Warmup(iterations = 5) +@Measurement(iterations = 5, time = 1, timeUnit = TimeUnit.SECONDS) +@OutputTimeUnit(TimeUnit.SECONDS) +@Fork(value = 1) +@State(Scope.Thread) +public class RangePerf implements Func1> { + + @Param({"1", "10", "100", "1000", "10000", "100000", "1000000"}) + public int count; + + Ix source; + + Ix inner; + + Ix flatMapJust; + + @Override + public Iterable call(Integer t) { + return inner; + } + + @Setup + public void setup(Blackhole bh) { + + int d = 1000000 / count; + + inner = Ix.range(1, count); + + source = Ix.range(1, d).flatMap(this); + + flatMapJust = Ix.range(1, count).flatMap(new Func1>() { + @Override + public Iterable call(Integer v) { + return Ix.just(v); + } + }); + } + + @Benchmark + public Object rangeLast() { + return inner.last(); + } + + @Benchmark + public void rangeEach(Blackhole bh) { + for (Integer i : inner) { + bh.consume(i); + } + } +} diff --git a/src/jmh/java/ix/ReducePerf.java b/src/jmh/java/ix/ReducePerf.java new file mode 100644 index 0000000..c6efe16 --- /dev/null +++ b/src/jmh/java/ix/ReducePerf.java @@ -0,0 +1,61 @@ +/* + * Copyright 2011-2016 David Karnok + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ix; + +import java.util.Arrays; +import java.util.concurrent.TimeUnit; + +import org.openjdk.jmh.annotations.*; +import org.openjdk.jmh.infra.Blackhole; + +/** + * Example benchmark. Run from command line as + *
+ * gradle jmh -Pjmh='IxPerf' + */ +@BenchmarkMode(Mode.Throughput) +@Warmup(iterations = 5) +@Measurement(iterations = 5, time = 1, timeUnit = TimeUnit.SECONDS) +@OutputTimeUnit(TimeUnit.SECONDS) +@Fork(value = 1) +@State(Scope.Thread) +public class ReducePerf { + + @Param({"1", "10", "100", "1000", "10000", "100000", "1000000"}) + public int count; + + Ix sum; + + @Setup + public void setup(Blackhole bh) { + Integer[] array = new Integer[count]; + Arrays.fill(array, 1); + + sum = Ix.fromArray(array).sumInt(); + } + + @Benchmark + public Object sumLast() { + return sum.last(); + } + + @Benchmark + public Object sumFirst() { + return sum.first(); + } + +} diff --git a/src/main/java/ix/FunctionHelper.java b/src/main/java/ix/FunctionHelper.java new file mode 100644 index 0000000..45a0d78 --- /dev/null +++ b/src/main/java/ix/FunctionHelper.java @@ -0,0 +1,38 @@ +/* + * Copyright 2011-2016 David Karnok + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ix; + +import rx.functions.Func1; + +enum FunctionHelper { + ; + + enum Identity implements Func1 { + INSTANCE + ; + + @SuppressWarnings("unchecked") + public static Func1 instance() { + return (Func1)INSTANCE; + } + + @Override + public Object call(Object t) { + return t; + } + } +} diff --git a/src/main/java/ix/Ix.java b/src/main/java/ix/Ix.java index 73b6902..52d2f0b 100644 --- a/src/main/java/ix/Ix.java +++ b/src/main/java/ix/Ix.java @@ -96,6 +96,53 @@ public static Ix characters(CharSequence cs, int start, int end) { return new IxCharacters(cs, start, end); } + public static Ix fromArray(T... values) { + int n = values.length; + if (n == 0) { + return empty(); + } + if (n == 1) { + return just(values[0]); + } + return new IxFromArray(0, values.length, values); + } + + public static Ix fromArrayRange(int start, int end, T... values) { + if (start < 0 || end < 0 || start > values.length || end > values.length) { + throw new IndexOutOfBoundsException("start=" + start + ", end=" + end + ", length=" + values.length); + } + return new IxFromArray(start, end, values); + } + + public static Ix concatArray(Iterable... sources) { + int n = sources.length; + if (n == 0) { + return empty(); + } + if (n == 1) { + return from(sources[0]); + } + return new IxFlattenArrayIterable(sources); + } + + public static Ix mergeArray(Iterable... sources) { + return concatArray(sources); // concat and merge are the same in the Iterable world + } + + @SuppressWarnings("unchecked") + public static Ix concat(Iterable> sources) { + return new IxFlattenIterable, T>( + (Iterable>)sources, + FunctionHelper.Identity.>instance()); + } + + @SuppressWarnings("unchecked") + public static Ix merge(Iterable> sources) { + return new IxFlattenIterable, T>( + (Iterable>)sources, + FunctionHelper.Identity.>instance()); + } + //--------------------------------------------------------------------------------------- // Instance operators //--------------------------------------------------------------------------------------- @@ -208,4 +255,74 @@ public final Ix toArray() { return collect(ToListHelper.initialFactory(), ToListHelper.collector()) .map(ToListHelper.toArray()); } + + public final Ix reduce(Func2 reducer) { + return new IxAggregate(this, reducer); + } + + @SuppressWarnings("unchecked") + public final Ix maxInt() { + return new IxMaxInt((Ix)this); + } + + @SuppressWarnings("unchecked") + public final Ix minInt() { + return new IxMinInt((Ix)this); + } + + @SuppressWarnings("unchecked") + public final Ix sumInt() { + return new IxSumInt((Ix)this); + } + + @SuppressWarnings("unchecked") + public final Ix maxLong() { + return new IxMaxLong((Ix)this); + } + + @SuppressWarnings("unchecked") + public final Ix minLong() { + return new IxMinLong((Ix)this); + } + + @SuppressWarnings("unchecked") + public final Ix sumLong() { + return new IxSumLong((Ix)this); + } + + @SuppressWarnings("unchecked") + public final Ix toLong() { + return ((Ix)this).map(ReduceHelper.NumberToLong.INSTANCE); + } + + public final Ix skip(int n) { + if (n == 0) { + return this; + } + return new IxSkip(this, n); + } + + public final Ix take(int n) { + return new IxTake(this, n); + } + + public final Ix skipLast(int n) { + if (n == 0) { + return this; + } + return new IxSkipLast(this, n); + } + + public final Ix takeLast(int n) { + return new IxTakeLast(this, n); + } + + public final Ix flatMap(Func1> mapper) { + return new IxFlattenIterable(this, mapper); + } + + public final Ix concatMap(Func1> mapper) { + return new IxFlattenIterable(this, mapper); + } + } diff --git a/src/main/java/ix/IxAggregate.java b/src/main/java/ix/IxAggregate.java new file mode 100644 index 0000000..3749c4b --- /dev/null +++ b/src/main/java/ix/IxAggregate.java @@ -0,0 +1,65 @@ +/* + * Copyright 2011-2016 David Karnok + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ix; + +import java.util.Iterator; + +import rx.functions.Func2; + +final class IxAggregate extends IxSource { + + final Func2 aggregator; + + public IxAggregate(Iterable source, Func2 aggregator) { + super(source); + this.aggregator = aggregator; + } + + @Override + public Iterator iterator() { + return new AggregateIterator(source.iterator(), aggregator); + } + + static final class AggregateIterator extends IxSourceIterator { + + final Func2 aggregator; + + public AggregateIterator(Iterator it, Func2 aggregator) { + super(it); + this.aggregator = aggregator; + } + + @Override + protected boolean moveNext() { + Iterator it = this.it; + Func2 f = aggregator; + + if (it.hasNext()) { + T acc = it.next(); + while (it.hasNext()) { + acc = f.call(acc, it.next()); + } + value = acc; + hasValue = true; + done = true; + return true; + } + return false; + } + } + +} diff --git a/src/main/java/ix/IxBaseIterator.java b/src/main/java/ix/IxBaseIterator.java index 8b2587b..52b2658 100644 --- a/src/main/java/ix/IxBaseIterator.java +++ b/src/main/java/ix/IxBaseIterator.java @@ -19,25 +19,23 @@ import java.util.Iterator; /** - * A base iterator that references an upstream iterator and manages - * the state between hasNext() and the next() calls. + * A base iterator that manages + * the state between hasNext() and the next() calls; plus defines + * the remove() to throw UnsupportedOperationException. * @param the source value type * @param the result value type */ -abstract class IxBaseIterator implements Iterator { - - protected final Iterator it; +public abstract class IxBaseIterator implements Iterator { + /** Inidicates a value is available for consumption. */ protected boolean hasValue; + /** Indicates there are no more data available. */ protected boolean done; + /** The current value if hasValue is true. */ protected R value; - public IxBaseIterator(Iterator it) { - this.it = it; - } - /** * Move the stream forward by a single element. * @return what the hasNext should return @@ -56,7 +54,7 @@ public final boolean hasNext() { } @Override - public R next() { + public final R next() { if (!hasValue && !hasNext()) { return Ix.noelements(); } diff --git a/src/main/java/ix/IxCollect.java b/src/main/java/ix/IxCollect.java index e8fe276..5712589 100644 --- a/src/main/java/ix/IxCollect.java +++ b/src/main/java/ix/IxCollect.java @@ -37,7 +37,7 @@ public Iterator iterator() { return new CollectorIterator(source.iterator(), collector, initialFactory.call()); } - static final class CollectorIterator extends IxBaseIterator { + static final class CollectorIterator extends IxSourceIterator { final Action2 collector; diff --git a/src/main/java/ix/IxFilter.java b/src/main/java/ix/IxFilter.java index 4e2be24..e530c6e 100644 --- a/src/main/java/ix/IxFilter.java +++ b/src/main/java/ix/IxFilter.java @@ -1,3 +1,19 @@ +/* + * Copyright 2011-2016 David Karnok + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package ix; import java.util.Iterator; @@ -16,7 +32,7 @@ public Iterator iterator() { return new FilterIterator(source.iterator(), predicate); } - static final class FilterIterator extends IxBaseIterator { + static final class FilterIterator extends IxSourceIterator { final Pred predicate; diff --git a/src/main/java/ix/IxFlattenArrayIterable.java b/src/main/java/ix/IxFlattenArrayIterable.java new file mode 100644 index 0000000..1dbcb91 --- /dev/null +++ b/src/main/java/ix/IxFlattenArrayIterable.java @@ -0,0 +1,94 @@ +/* + * Copyright 2011-2016 David Karnok + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ix; + +import java.util.Iterator; +import java.util.concurrent.Callable; + +import rx.exceptions.Exceptions; + +final class IxFlattenArrayIterable extends Ix { + + final Iterable[] sources; + + public IxFlattenArrayIterable(Iterable[] sources) { + this.sources = sources; + } + + @Override + public Iterator iterator() { + return new FlattenIterator(sources); + } + + static final class FlattenIterator extends IxBaseIterator { + + final Iterable[] sources; + + Iterator current; + + int index; + + public FlattenIterator(Iterable[] sources) { + this.sources = sources; + } + + @SuppressWarnings("unchecked") + @Override + protected boolean moveNext() { + Iterator c = current; + + while (c == null) { + int i = index; + if (i != sources.length) { + Iterable inner = sources[i]; + index = i + 1; + if (inner instanceof Callable) { + try { + value = ((Callable)inner).call(); + } catch (Exception e) { + Exceptions.propagate(e); + } + hasValue = true; + return true; + } + + c = inner.iterator(); + + if (c.hasNext()) { + current = c; + break; + } else { + c = null; + } + } else { + done = true; + return false; + } + } + + value = c.next(); + hasValue = true; + + if (!c.hasNext()) { + current = null; + } + return true; + } + + } + +} diff --git a/src/main/java/ix/IxFlattenIterable.java b/src/main/java/ix/IxFlattenIterable.java new file mode 100644 index 0000000..1a6e7c5 --- /dev/null +++ b/src/main/java/ix/IxFlattenIterable.java @@ -0,0 +1,101 @@ +/* + * Copyright 2011-2016 David Karnok + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ix; + +import java.util.Iterator; +import java.util.concurrent.Callable; + +import rx.exceptions.Exceptions; +import rx.functions.Func1; + +final class IxFlattenIterable extends IxSource { + + final Func1> mapper; + + public IxFlattenIterable(Iterable source, Func1> mapper) { + super(source); + this.mapper = mapper; + } + + @SuppressWarnings("unchecked") + @Override + public Iterator iterator() { + if (source instanceof Callable) { + try { + return (Iterator)(mapper.call(((Callable)source).call()).iterator()); + } catch (Exception e) { + Exceptions.propagate(e); + } + } + return new FlattenIterator(source.iterator(), mapper); + } + + static final class FlattenIterator extends IxSourceIterator { + + final Func1> mapper; + + Iterator current; + + public FlattenIterator(Iterator it, Func1> mapper) { + super(it); + this.mapper = mapper; + } + + @SuppressWarnings("unchecked") + @Override + protected boolean moveNext() { + Iterator c = current; + + while (c == null) { + if (it.hasNext()) { + Iterable inner = mapper.call(it.next()); + if (inner instanceof Callable) { + try { + value = ((Callable)inner).call(); + } catch (Exception e) { + Exceptions.propagate(e); + } + hasValue = true; + return true; + } + + c = inner.iterator(); + + if (c.hasNext()) { + current = c; + break; + } else { + c = null; + } + } else { + done = true; + return false; + } + } + + value = c.next(); + hasValue = true; + + if (!c.hasNext()) { + current = null; + } + return true; + } + + } + +} diff --git a/src/main/java/ix/IxFromArray.java b/src/main/java/ix/IxFromArray.java new file mode 100644 index 0000000..b4c1edc --- /dev/null +++ b/src/main/java/ix/IxFromArray.java @@ -0,0 +1,55 @@ +package ix; + +import java.util.Iterator; + +final class IxFromArray extends Ix { + + final int start; + final int end; + final T[] array; + + public IxFromArray(int start, int end, T[] array) { + this.start = start; + this.end = end; + this.array = array; + } + + @Override + public Iterator iterator() { + return new FromArray(start, end, array); + } + + static final class FromArray implements Iterator { + final T[] array; + + final int end; + + int index; + + public FromArray(int start, int end, T[] array) { + this.index = start; + this.end = end; + this.array = array; + } + + @Override + public boolean hasNext() { + return index != end; + } + + @Override + public T next() { + int i = index; + if (i != end) { + index = i + 1; + return array[i]; + } + return noelements(); + } + + @Override + public void remove() { + unsupported(); + } + } +} diff --git a/src/main/java/ix/IxJust.java b/src/main/java/ix/IxJust.java index 4f19e41..abd98b1 100644 --- a/src/main/java/ix/IxJust.java +++ b/src/main/java/ix/IxJust.java @@ -48,7 +48,7 @@ public JustIterator(T value) { @Override public boolean hasNext() { - return empty; + return !empty; } @Override diff --git a/src/main/java/ix/IxMaxInt.java b/src/main/java/ix/IxMaxInt.java new file mode 100644 index 0000000..af7b419 --- /dev/null +++ b/src/main/java/ix/IxMaxInt.java @@ -0,0 +1,58 @@ +/* + * Copyright 2011-2016 David Karnok + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ix; + +import java.util.Iterator; + +final class IxMaxInt extends IxSource { + + public IxMaxInt(Iterable source) { + super(source); + } + + @Override + public Iterator iterator() { + return new MaxIntIterator(source.iterator()); + } + + static final class MaxIntIterator extends IxSourceIterator { + + public MaxIntIterator(Iterator it) { + super(it); + } + + @Override + protected boolean moveNext() { + Iterator it = this.it; + if (!it.hasNext()) { + done = true; + return false; + } + int sum = it.next(); + + while (it.hasNext()) { + sum = Math.max(sum, it.next()); + } + + value = sum; + hasValue = true; + done = true; + return true; + } + + } +} diff --git a/src/main/java/ix/IxMaxLong.java b/src/main/java/ix/IxMaxLong.java new file mode 100644 index 0000000..e9877d3 --- /dev/null +++ b/src/main/java/ix/IxMaxLong.java @@ -0,0 +1,58 @@ +/* + * Copyright 2011-2016 David Karnok + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ix; + +import java.util.Iterator; + +final class IxMaxLong extends IxSource { + + public IxMaxLong(Iterable source) { + super(source); + } + + @Override + public Iterator iterator() { + return new MaxLongIterator(source.iterator()); + } + + static final class MaxLongIterator extends IxSourceIterator { + + public MaxLongIterator(Iterator it) { + super(it); + } + + @Override + protected boolean moveNext() { + Iterator it = this.it; + if (!it.hasNext()) { + done = true; + return false; + } + long sum = it.next(); + + while (it.hasNext()) { + sum = Math.max(sum, it.next()); + } + + value = sum; + hasValue = true; + done = true; + return true; + } + + } +} diff --git a/src/main/java/ix/IxMinInt.java b/src/main/java/ix/IxMinInt.java new file mode 100644 index 0000000..f310560 --- /dev/null +++ b/src/main/java/ix/IxMinInt.java @@ -0,0 +1,58 @@ +/* + * Copyright 2011-2016 David Karnok + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ix; + +import java.util.Iterator; + +final class IxMinInt extends IxSource { + + public IxMinInt(Iterable source) { + super(source); + } + + @Override + public Iterator iterator() { + return new MinIntIterator(source.iterator()); + } + + static final class MinIntIterator extends IxSourceIterator { + + public MinIntIterator(Iterator it) { + super(it); + } + + @Override + protected boolean moveNext() { + Iterator it = this.it; + if (!it.hasNext()) { + done = true; + return false; + } + int sum = it.next(); + + while (it.hasNext()) { + sum = Math.min(sum, it.next()); + } + + value = sum; + hasValue = true; + done = true; + return true; + } + + } +} diff --git a/src/main/java/ix/IxMinLong.java b/src/main/java/ix/IxMinLong.java new file mode 100644 index 0000000..0f8670e --- /dev/null +++ b/src/main/java/ix/IxMinLong.java @@ -0,0 +1,58 @@ +/* + * Copyright 2011-2016 David Karnok + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ix; + +import java.util.Iterator; + +final class IxMinLong extends IxSource { + + public IxMinLong(Iterable source) { + super(source); + } + + @Override + public Iterator iterator() { + return new MinLongIterator(source.iterator()); + } + + static final class MinLongIterator extends IxSourceIterator { + + public MinLongIterator(Iterator it) { + super(it); + } + + @Override + protected boolean moveNext() { + Iterator it = this.it; + if (!it.hasNext()) { + done = true; + return false; + } + long sum = it.next(); + + while (it.hasNext()) { + sum = Math.min(sum, it.next()); + } + + value = sum; + hasValue = true; + done = true; + return true; + } + + } +} diff --git a/src/main/java/ix/IxReduce.java b/src/main/java/ix/IxReduce.java index 3fa977b..8d28540 100644 --- a/src/main/java/ix/IxReduce.java +++ b/src/main/java/ix/IxReduce.java @@ -37,7 +37,7 @@ public Iterator iterator() { return new CollectorIterator(source.iterator(), reducer, initialFactory.call()); } - static final class CollectorIterator extends IxBaseIterator { + static final class CollectorIterator extends IxSourceIterator { final Func2 reducer; diff --git a/src/main/java/ix/IxSkip.java b/src/main/java/ix/IxSkip.java new file mode 100644 index 0000000..2c319d2 --- /dev/null +++ b/src/main/java/ix/IxSkip.java @@ -0,0 +1,70 @@ +/* + * Copyright 2011-2016 David Karnok + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ix; + +import java.util.Iterator; + +final class IxSkip extends IxSource { + + final int n; + + public IxSkip(Iterable source, int n) { + super(source); + this.n = n; + } + + @Override + public Iterator iterator() { + return new SkipIterator(source.iterator(), n); + } + + static final class SkipIterator extends IxSourceIterator { + + int n; + public SkipIterator(Iterator it, int n) { + super(it); + this.n = n; + } + @Override + protected boolean moveNext() { + Iterator it = this.it; + int n = this.n; + + if (n != 0) { + while (n != 0) { + if (it.hasNext()) { + it.next(); + } else { + done = true; + return false; + } + n--; + } + this.n = 0; + } + if (it.hasNext()) { + value = it.next(); + hasValue = true; + return true; + } + done = true; + return false; + } + + + } +} diff --git a/src/main/java/ix/IxSkipLast.java b/src/main/java/ix/IxSkipLast.java new file mode 100644 index 0000000..74c67a1 --- /dev/null +++ b/src/main/java/ix/IxSkipLast.java @@ -0,0 +1,82 @@ +/* + * Copyright 2011-2016 David Karnok + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ix; + +import java.util.Iterator; + +final class IxSkipLast extends IxSource { + + final int n; + + public IxSkipLast(Iterable source, int n) { + super(source); + this.n = n; + } + + @Override + public Iterator iterator() { + return new SkipLastIterator(source.iterator(), n); + } + + static final class SkipLastIterator extends IxSourceQueuedIterator { + + final int n; + + int size; + + public SkipLastIterator(Iterator it, int n) { + super(it); + this.n = n; + } + + @Override + protected boolean moveNext() { + int s = size; + int n = this.n; + + Iterator it = this.it; + if (!it.hasNext()) { + done = true; + return false; + } + + if (s != n) { + while (s != n) { + offer(toObject(it.next())); + if (!it.hasNext()) { + done = true; + return false; + } + s++; + } + size = s; + } + + if (s == 0) { + value = it.next(); + } else { + value = fromObject(poll()); + offer(toObject(it.next())); + } + + hasValue = true; + + return true; + } + + } +} diff --git a/src/main/java/ix/IxSourceIterator.java b/src/main/java/ix/IxSourceIterator.java new file mode 100644 index 0000000..289c9c9 --- /dev/null +++ b/src/main/java/ix/IxSourceIterator.java @@ -0,0 +1,36 @@ +/* + * Copyright 2011-2016 David Karnok + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ix; + +import java.util.Iterator; + +/** + * A base iterator that references an upstream iterator and manages + * the state between hasNext() and the next() calls; plus defines + * the remove() to throw UnsupportedOperationException. + * @param the source value type + * @param the result value type + */ +public abstract class IxSourceIterator extends IxBaseIterator { + + /** The upstream's iterator. */ + protected final Iterator it; + + public IxSourceIterator(Iterator it) { + this.it = it; + } +} diff --git a/src/main/java/ix/IxSourceQueuedIterator.java b/src/main/java/ix/IxSourceQueuedIterator.java new file mode 100644 index 0000000..fd16f35 --- /dev/null +++ b/src/main/java/ix/IxSourceQueuedIterator.java @@ -0,0 +1,121 @@ +/* + * Copyright 2011-2016 David Karnok + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ix; + +import java.util.Iterator; + +/** + * A base iterator that extends a custom ArrayDeque, references an upstream iterator + * and manages the state between hasNext() and the next() calls; plus defines + * the remove() to throw UnsupportedOperationException. + * @param the source value type + * @param the queued element types + * @param the result value type + */ +public abstract class IxSourceQueuedIterator +extends IxSourceIterator { + + protected static final Object NULL = new Object(); + + private Object[] array; + + private int producerIndex; + + private int consumerIndex; + + public IxSourceQueuedIterator(Iterator it) { + super(it); + } + + /** + * Cast the value into an object and turn + * a null value into a sentinel value. + * @param value the value to cast + * @return the cast value, not null + * @see IxSourceQueuedIterator#fromObject(Object) + */ + protected final Object toObject(U value) { + return value != null ? value : NULL; + } + + /** + * Cast the object back to a typed value. + * @param value the value to cast back + * @return the typed value, maybe null + */ + @SuppressWarnings("unchecked") + protected final U fromObject(Object value) { + return value == NULL ? null : (U)value; + } + + protected final boolean offer(Object value) { + if (value == null) { + throw new NullPointerException("The queue doesn't support null values."); + } + Object[] a = array; + if (a == null) { + a = new Object[8]; + array = a; + } + int mask = a.length - 1; + int pi = producerIndex; + + int offset = pi & mask; + if (a[offset] != null) { + int newLen = mask * 2 + 2; + Object[] b = new Object[newLen]; + System.arraycopy(a, offset, b, 0, mask + 1 - offset); + System.arraycopy(a, 0, b, offset, offset); + b[mask + 1] = value; + + array = b; + consumerIndex = 0; + producerIndex = mask + 2; + } else { + a[offset] = value; + producerIndex = pi + 1; + } + return true; + } + + protected final Object poll() { + Object[] a = array; + if (a != null) { + int m = a.length - 1; + int ci = consumerIndex; + int offset = ci & m; + + Object v = a[offset]; + if (v != null) { + a[offset] = null; + consumerIndex = ci + 1; + } + return v; + } + return null; + } + + protected final boolean isEmpty() { + return consumerIndex == producerIndex; + } + + protected final void clear() { + array = null; + consumerIndex = 0; + producerIndex = 0; + } +} diff --git a/src/main/java/ix/IxSumInt.java b/src/main/java/ix/IxSumInt.java new file mode 100644 index 0000000..897885e --- /dev/null +++ b/src/main/java/ix/IxSumInt.java @@ -0,0 +1,58 @@ +/* + * Copyright 2011-2016 David Karnok + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ix; + +import java.util.Iterator; + +final class IxSumInt extends IxSource { + + public IxSumInt(Iterable source) { + super(source); + } + + @Override + public Iterator iterator() { + return new SumIntIterator(source.iterator()); + } + + static final class SumIntIterator extends IxSourceIterator { + + public SumIntIterator(Iterator it) { + super(it); + } + + @Override + protected boolean moveNext() { + Iterator it = this.it; + if (!it.hasNext()) { + done = true; + return false; + } + int sum = it.next(); + + while (it.hasNext()) { + sum += it.next(); + } + + value = sum; + hasValue = true; + done = true; + return true; + } + + } +} diff --git a/src/main/java/ix/IxSumLong.java b/src/main/java/ix/IxSumLong.java new file mode 100644 index 0000000..8a6e2c6 --- /dev/null +++ b/src/main/java/ix/IxSumLong.java @@ -0,0 +1,58 @@ +/* + * Copyright 2011-2016 David Karnok + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ix; + +import java.util.Iterator; + +final class IxSumLong extends IxSource { + + public IxSumLong(Iterable source) { + super(source); + } + + @Override + public Iterator iterator() { + return new SumLongIterator(source.iterator()); + } + + static final class SumLongIterator extends IxSourceIterator { + + public SumLongIterator(Iterator it) { + super(it); + } + + @Override + protected boolean moveNext() { + Iterator it = this.it; + if (!it.hasNext()) { + done = true; + return false; + } + long sum = it.next(); + + while (it.hasNext()) { + sum += it.next(); + } + + value = sum; + hasValue = true; + done = true; + return true; + } + + } +} diff --git a/src/main/java/ix/IxTake.java b/src/main/java/ix/IxTake.java new file mode 100644 index 0000000..24d2d00 --- /dev/null +++ b/src/main/java/ix/IxTake.java @@ -0,0 +1,59 @@ +/* + * Copyright 2011-2016 David Karnok + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ix; + +import java.util.Iterator; + +final class IxTake extends IxSource { + + final int n; + + public IxTake(Iterable source, int n) { + super(source); + this.n = n; + } + + @Override + public Iterator iterator() { + return new TakeIterator(source.iterator(), n); + } + + static final class TakeIterator extends IxSourceIterator { + + int n; + public TakeIterator(Iterator it, int n) { + super(it); + this.n = n; + } + + @Override + protected boolean moveNext() { + int n = this.n; + if (n == 0 || !it.hasNext()) { + done = true; + return false; + } + + value = it.next(); + hasValue = true; + this.n = n - 1; + + return true; + } + } + +} diff --git a/src/main/java/ix/IxTakeLast.java b/src/main/java/ix/IxTakeLast.java new file mode 100644 index 0000000..35bff0a --- /dev/null +++ b/src/main/java/ix/IxTakeLast.java @@ -0,0 +1,72 @@ +/* + * Copyright 2011-2016 David Karnok + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ix; + +import java.util.Iterator; + +final class IxTakeLast extends IxSource { + + final int n; + + public IxTakeLast(Iterable source, int n) { + super(source); + this.n = n; + } + + @Override + public Iterator iterator() { + return new TakeLastIterator(source.iterator(), n); + } + + static final class TakeLastIterator extends IxSourceQueuedIterator { + + int n; + + public TakeLastIterator(Iterator it, int n) { + super(it); + this.n = n; + } + + @Override + protected boolean moveNext() { + + int n = this.n; + if (n != 0) { + Iterator it = this.it; + while (it.hasNext()) { + if (n == 0) { + poll(); + } else { + n--; + } + offer(toObject(it.next())); + } + this.n = n; + } + + Object o = poll(); + if (o != null) { + value = fromObject(o); + hasValue = true; + return true; + } + done = true; + return false; + } + } + +} diff --git a/src/main/java/ix/ReduceHelper.java b/src/main/java/ix/ReduceHelper.java new file mode 100644 index 0000000..54be090 --- /dev/null +++ b/src/main/java/ix/ReduceHelper.java @@ -0,0 +1,86 @@ +/* + * Copyright 2011-2016 David Karnok + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ix; + +import rx.functions.*; + +enum ReduceHelper { + ; + + enum IntMax implements Func2 { + INSTANCE; + + @Override + public Integer call(Integer t1, Integer t2) { + return t1.compareTo(t2) < 0 ? t2 : t1; + } + } + + enum IntMin implements Func2 { + INSTANCE; + + @Override + public Integer call(Integer t1, Integer t2) { + return t1.compareTo(t2) < 0 ? t1 : t2; + } + } + + enum IntSum implements Func2 { + INSTANCE; + + @Override + public Integer call(Integer t1, Integer t2) { + return t1.intValue() + t2.intValue(); + } + } + + enum NumberToLong implements Func1 { + INSTANCE; + + @Override + public Long call(Number t1) { + return t1.longValue(); + } + } + + enum LongMax implements Func2 { + INSTANCE; + + @Override + public Long call(Long t1, Long t2) { + return t1.compareTo(t2) < 0 ? t2 : t1; + } + } + + enum LongMin implements Func2 { + INSTANCE; + + @Override + public Long call(Long t1, Long t2) { + return t1.compareTo(t2) < 0 ? t1 : t2; + } + } + + enum LongSum implements Func2 { + INSTANCE; + + @Override + public Long call(Long t1, Long t2) { + return t1.longValue() + t2.longValue(); + } + } +} diff --git a/src/main/java/ix/ToListHelper.java b/src/main/java/ix/ToListHelper.java index 275b655..7c2781c 100644 --- a/src/main/java/ix/ToListHelper.java +++ b/src/main/java/ix/ToListHelper.java @@ -1,3 +1,19 @@ +/* + * Copyright 2011-2016 David Karnok + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package ix; import java.util.*; diff --git a/src/test/java/ix/AggregateTest.java b/src/test/java/ix/AggregateTest.java new file mode 100644 index 0000000..8b6d83b --- /dev/null +++ b/src/test/java/ix/AggregateTest.java @@ -0,0 +1,47 @@ +/* + * Copyright 2011-2016 David Karnok + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ix; + +import org.junit.Test; + +public class AggregateTest { + + @Test + public void normal() { + + Ix source = Ix.range(1, 10).sumInt(); + + IxTestHelper.assertValues(source, 55); + } + + @Test + public void just() { + + Ix source = Ix.just(1).sumInt(); + + IxTestHelper.assertValues(source, 1); + } + + @Test + public void empty() { + + Ix source = Ix.empty().sumInt(); + + IxTestHelper.assertValues(source); + } + +} diff --git a/src/test/java/ix/ConcatArrayTest.java b/src/test/java/ix/ConcatArrayTest.java new file mode 100644 index 0000000..2120ac6 --- /dev/null +++ b/src/test/java/ix/ConcatArrayTest.java @@ -0,0 +1,70 @@ +/* + * Copyright 2011-2016 David Karnok + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ix; + +import org.junit.Test; + +public class ConcatArrayTest { + + @SuppressWarnings("unchecked") + @Test + public void normal() { + Ix source = Ix.concatArray(Ix.range(1, 5), Ix.range(6, 5)); + + + IxTestHelper.assertValues(source, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10); + } + + @SuppressWarnings("unchecked") + @Test + public void just() { + Ix source = Ix.concatArray(Ix.just(1), Ix.just(2)); + + + IxTestHelper.assertValues(source, 1, 2); + } + + @SuppressWarnings("unchecked") + @Test + public void empty() { + Ix source = Ix.concatArray(Ix.empty(), Ix.empty()); + + + IxTestHelper.assertValues(source); + } + + @SuppressWarnings("unchecked") + @Test + public void mixed() { + Ix source = Ix.concatArray(Ix.empty(), Ix.range(1, 5), + Ix.empty(), Ix.just(6), Ix.empty()); + + + IxTestHelper.assertValues(source, 1, 2, 3, 4, 5, 6); + } + + @SuppressWarnings("unchecked") + @Test + public void mixedTwo() { + Ix source = Ix.concatArray(Ix.range(1, 5), + Ix.empty(), Ix.just(6)); + + + IxTestHelper.assertValues(source, 1, 2, 3, 4, 5, 6); + } + +} diff --git a/src/test/java/ix/FlattenIterableTest.java b/src/test/java/ix/FlattenIterableTest.java new file mode 100644 index 0000000..9f95f86 --- /dev/null +++ b/src/test/java/ix/FlattenIterableTest.java @@ -0,0 +1,61 @@ +/* + * Copyright 2011-2016 David Karnok + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ix; + +import org.junit.Test; + +import rx.functions.Func1; + +public class FlattenIterableTest { + + @Test + public void normal() { + Ix source = Ix.range(1, 5).flatMap(new Func1>() { + @Override + public Iterable call(Integer v) { + return Ix.range(v, 2); + } + }); + + IxTestHelper.assertValues(source, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6); + } + + @Test + public void just() { + Ix source = Ix.just(1).flatMap(new Func1>() { + @Override + public Iterable call(Integer v) { + return Ix.range(v, 2); + } + }); + + IxTestHelper.assertValues(source, 1, 2); + } + + @Test + public void empty() { + Ix source = Ix.empty().flatMap(new Func1>() { + @Override + public Iterable call(Integer v) { + return Ix.range(v, 2); + } + }); + + IxTestHelper.assertValues(source); + } + +} diff --git a/src/test/java/ix/FromArrayTest.java b/src/test/java/ix/FromArrayTest.java new file mode 100644 index 0000000..a182ed5 --- /dev/null +++ b/src/test/java/ix/FromArrayTest.java @@ -0,0 +1,37 @@ +/* + * Copyright 2011-2016 David Karnok + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ix; + +import org.junit.Test; + +public class FromArrayTest { + + @Test + public void normal() { + Ix source = Ix.fromArray(1, 2, 3, 4, 5, 6, 7, 8, 9, 10); + + IxTestHelper.assertValues(source, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10); + } + + @Test + public void range() { + Ix source = Ix.fromArrayRange(1, 8, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10); + + IxTestHelper.assertValues(source, 2, 3, 4, 5, 6, 7, 8); + } + +} diff --git a/src/test/java/ix/JustTest.java b/src/test/java/ix/JustTest.java index a60b71f..c6cb546 100644 --- a/src/test/java/ix/JustTest.java +++ b/src/test/java/ix/JustTest.java @@ -26,5 +26,7 @@ public void normal() { Ix source = Ix.just(1); assertEquals(1, source.iterator().next().intValue()); + + IxTestHelper.assertValues(source, 1); } } diff --git a/src/test/java/ix/MaxTest.java b/src/test/java/ix/MaxTest.java new file mode 100644 index 0000000..5ad0d65 --- /dev/null +++ b/src/test/java/ix/MaxTest.java @@ -0,0 +1,67 @@ +/* + * Copyright 2011-2016 David Karnok + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ix; + +import static org.junit.Assert.assertEquals; + +import org.junit.Test; + +public class MaxTest { + + @Test + public void normal() { + Ix source = Ix.range(1, 10).maxInt(); + + assertEquals(10L, source.first().intValue()); + } + + @Test + public void just() { + Ix source = Ix.just(1).maxInt(); + + assertEquals(1, source.first().intValue()); + } + + @Test + public void empty() { + Ix source = Ix.empty().maxInt(); + + IxTestHelper.assertValues(source); + } + + @Test + public void normalLong() { + Ix source = Ix.range(1, 10).toLong().maxLong(); + + assertEquals(10L, source.first().longValue()); + } + + @Test + public void justLong() { + Ix source = Ix.just(1L).maxLong(); + + assertEquals(1L, source.first().longValue()); + } + + @Test + public void emptyLong() { + Ix source = Ix.empty().maxLong(); + + IxTestHelper.assertValues(source); + } + +} diff --git a/src/test/java/ix/MinTest.java b/src/test/java/ix/MinTest.java new file mode 100644 index 0000000..49d1dd4 --- /dev/null +++ b/src/test/java/ix/MinTest.java @@ -0,0 +1,67 @@ +/* + * Copyright 2011-2016 David Karnok + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ix; + +import static org.junit.Assert.assertEquals; + +import org.junit.Test; + +public class MinTest { + + @Test + public void normal() { + Ix source = Ix.range(1, 10).minInt(); + + assertEquals(1, source.first().intValue()); + } + + @Test + public void just() { + Ix source = Ix.just(1).minInt(); + + assertEquals(1, source.first().intValue()); + } + + @Test + public void empty() { + Ix source = Ix.empty().minInt(); + + IxTestHelper.assertValues(source); + } + + @Test + public void normalLong() { + Ix source = Ix.range(1, 10).toLong().minLong(); + + assertEquals(1, source.first().longValue()); + } + + @Test + public void justLong() { + Ix source = Ix.just(1L).minLong(); + + assertEquals(1L, source.first().longValue()); + } + + @Test + public void emptyLong() { + Ix source = Ix.empty().minLong(); + + IxTestHelper.assertValues(source); + } + +} diff --git a/src/test/java/ix/SkipLastTest.java b/src/test/java/ix/SkipLastTest.java new file mode 100644 index 0000000..d7e5685 --- /dev/null +++ b/src/test/java/ix/SkipLastTest.java @@ -0,0 +1,87 @@ +/* + * Copyright 2011-2016 David Karnok + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ix; + +import org.junit.Test; + +public class SkipLastTest { + + @Test + public void normal() { + Ix source = Ix.range(1, 10).skipLast(5); + + IxTestHelper.assertValues(source, 1, 2, 3, 4, 5); + } + + @Test + public void normalTwo() { + Ix source = Ix.range(1, 2).skipLast(1); + + IxTestHelper.assertValues(source, 1); + } + + @Test + public void normalThree() { + Ix source = Ix.range(1, 16).skipLast(1); + + IxTestHelper.assertValues(source, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); + } + + @Test + public void zero() { + Ix source = Ix.range(1, 10).skipLast(0); + + IxTestHelper.assertValues(source, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10); + } + + @Test + public void all() { + Ix source = Ix.range(1, 10).skipLast(10); + + IxTestHelper.assertValues(source); + } + + @Test + public void more() { + Ix source = Ix.range(1, 10).skipLast(15); + + IxTestHelper.assertValues(source); + } + + + @Test + public void just() { + Ix source = Ix.just(1).skipLast(1); + + IxTestHelper.assertValues(source); + } + + @Test + public void empty() { + Ix source = Ix.empty().skipLast(1); + + IxTestHelper.assertValues(source); + } + + @Test + public void emptyZero() { + Ix source = Ix.empty().skipLast(0); + + IxTestHelper.assertValues(source); + } + +} diff --git a/src/test/java/ix/SkipTest.java b/src/test/java/ix/SkipTest.java new file mode 100644 index 0000000..137aace --- /dev/null +++ b/src/test/java/ix/SkipTest.java @@ -0,0 +1,58 @@ +/* + * Copyright 2011-2016 David Karnok + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ix; + +import org.junit.Test; + +public class SkipTest { + + @Test + public void normal() { + Ix source = Ix.range(1, 10).skip(5); + + IxTestHelper.assertValues(source, 6, 7, 8, 9, 10); + } + + @Test + public void zero() { + Ix source = Ix.range(1, 10).skip(0); + + IxTestHelper.assertValues(source, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10); + } + + @Test + public void all() { + Ix source = Ix.range(1, 10).skip(10); + + IxTestHelper.assertValues(source); + } + + @Test + public void empty() { + Ix source = Ix.empty().skip(10); + + IxTestHelper.assertValues(source); + } + + @Test + public void emptyZero() { + Ix source = Ix.empty().skip(0); + + IxTestHelper.assertValues(source); + } + +} diff --git a/src/test/java/ix/SumTest.java b/src/test/java/ix/SumTest.java new file mode 100644 index 0000000..3221aa4 --- /dev/null +++ b/src/test/java/ix/SumTest.java @@ -0,0 +1,67 @@ +/* + * Copyright 2011-2016 David Karnok + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ix; + +import static org.junit.Assert.assertEquals; + +import org.junit.Test; + +public class SumTest { + + @Test + public void normal() { + Ix source = Ix.range(1, 10).sumInt(); + + assertEquals(55, source.first().intValue()); + } + + @Test + public void just() { + Ix source = Ix.just(1).sumInt(); + + assertEquals(1, source.first().intValue()); + } + + @Test + public void empty() { + Ix source = Ix.empty().sumInt(); + + IxTestHelper.assertValues(source); + } + + @Test + public void normalLong() { + Ix source = Ix.range(1, 10).toLong().sumLong(); + + assertEquals(55L, source.first().longValue()); + } + + @Test + public void justLong() { + Ix source = Ix.just(1L).sumLong(); + + assertEquals(1, source.first().intValue()); + } + + @Test + public void emptyLong() { + Ix source = Ix.empty().sumLong(); + + IxTestHelper.assertValues(source); + } + +} diff --git a/src/test/java/ix/TakeLastTest.java b/src/test/java/ix/TakeLastTest.java new file mode 100644 index 0000000..2bd7988 --- /dev/null +++ b/src/test/java/ix/TakeLastTest.java @@ -0,0 +1,87 @@ +/* + * Copyright 2011-2016 David Karnok + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ix; + +import org.junit.Test; + +public class TakeLastTest { + + @Test + public void normal() { + Ix source = Ix.range(1, 10).takeLast(5); + + IxTestHelper.assertValues(source, 6, 7, 8, 9, 10); + } + + @Test + public void normalTwo() { + Ix source = Ix.range(1, 2).takeLast(1); + + IxTestHelper.assertValues(source, 2); + } + + @Test + public void normalThree() { + Ix source = Ix.range(1, 16).takeLast(15); + + IxTestHelper.assertValues(source, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16); + } + + @Test + public void zero() { + Ix source = Ix.range(1, 10).takeLast(0); + + IxTestHelper.assertValues(source); + } + + @Test + public void all() { + Ix source = Ix.range(1, 10).takeLast(10); + + IxTestHelper.assertValues(source, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10); + } + + @Test + public void more() { + Ix source = Ix.range(1, 10).takeLast(15); + + IxTestHelper.assertValues(source, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10); + } + + + @Test + public void just() { + Ix source = Ix.just(1).takeLast(1); + + IxTestHelper.assertValues(source, 1); + } + + @Test + public void empty() { + Ix source = Ix.empty().takeLast(1); + + IxTestHelper.assertValues(source); + } + + @Test + public void emptyZero() { + Ix source = Ix.empty().takeLast(0); + + IxTestHelper.assertValues(source); + } + +} diff --git a/src/test/java/ix/TakeTest.java b/src/test/java/ix/TakeTest.java new file mode 100644 index 0000000..1b46053 --- /dev/null +++ b/src/test/java/ix/TakeTest.java @@ -0,0 +1,65 @@ +/* + * Copyright 2011-2016 David Karnok + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ix; + +import org.junit.Test; + +public class TakeTest { + + @Test + public void normal() { + Ix source = Ix.range(1, 10).take(5); + + IxTestHelper.assertValues(source, 1, 2, 3, 4, 5); + } + + @Test + public void all() { + Ix source = Ix.range(1, 10).take(10); + + IxTestHelper.assertValues(source, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10); + } + + @Test + public void more() { + Ix source = Ix.range(1, 10).take(15); + + IxTestHelper.assertValues(source, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10); + } + + @Test + public void none() { + Ix source = Ix.range(1, 10).take(0); + + IxTestHelper.assertValues(source); + } + + @Test + public void just() { + Ix source = Ix.just(1).take(5); + + IxTestHelper.assertValues(source, 1); + } + + @Test + public void empty() { + Ix source = Ix.empty().take(5); + + IxTestHelper.assertValues(source); + } + +} From f939076b2696c49763f8419813cb0fff1b9aeb1e Mon Sep 17 00:00:00 2001 From: akarnokd Date: Wed, 6 Jul 2016 15:26:06 +0200 Subject: [PATCH 04/66] Run codecov.io task --- .travis.yml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index de0ba35..9380f2d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,4 +4,7 @@ jdk: - oraclejdk7 before_install: - - chmod +x gradlew \ No newline at end of file + - chmod +x gradlew + +after_success: + - bash <(curl -s https://codecov.io/bash) \ No newline at end of file From f25b8f48534c6cc04c4c2367b47e2b8bfe6516b7 Mon Sep 17 00:00:00 2001 From: akarnokd Date: Wed, 6 Jul 2016 15:29:52 +0200 Subject: [PATCH 05/66] javac vs eclipse compiler disagreements --- src/main/java/ix/Ix.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/java/ix/Ix.java b/src/main/java/ix/Ix.java index 52d2f0b..d1638ae 100644 --- a/src/main/java/ix/Ix.java +++ b/src/main/java/ix/Ix.java @@ -129,17 +129,17 @@ public static Ix mergeArray(Iterable... sources) { return concatArray(sources); // concat and merge are the same in the Iterable world } - @SuppressWarnings("unchecked") + @SuppressWarnings({ "unchecked", "rawtypes" }) public static Ix concat(Iterable> sources) { return new IxFlattenIterable, T>( - (Iterable>)sources, + (Iterable)sources, FunctionHelper.Identity.>instance()); } - @SuppressWarnings("unchecked") + @SuppressWarnings({ "unchecked", "rawtypes" }) public static Ix merge(Iterable> sources) { return new IxFlattenIterable, T>( - (Iterable>)sources, + (Iterable)sources, FunctionHelper.Identity.>instance()); } From 62db20d387495a7fb9b5f3da6255a6abea4011dc Mon Sep 17 00:00:00 2001 From: akarnokd Date: Wed, 6 Jul 2016 15:33:40 +0200 Subject: [PATCH 06/66] cache gradle components --- .travis.yml | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 9380f2d..379a519 100644 --- a/.travis.yml +++ b/.travis.yml @@ -7,4 +7,11 @@ before_install: - chmod +x gradlew after_success: - - bash <(curl -s https://codecov.io/bash) \ No newline at end of file + - bash <(curl -s https://codecov.io/bash) + + # cache between builds +cache: + directories: + - $HOME/.m2 + - $HOME/.gradle + \ No newline at end of file From eb9e0bfd8dc50d744ee2fb17c33c90ba5a0fedfc Mon Sep 17 00:00:00 2001 From: akarnokd Date: Wed, 6 Jul 2016 15:41:45 +0200 Subject: [PATCH 07/66] jacoco doesn't seem to run --- .travis.yml | 4 ++-- src/main/java/ix/IxFromArray.java | 16 ++++++++++++++++ 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 379a519..815a6f7 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,10 +4,10 @@ jdk: - oraclejdk7 before_install: - - chmod +x gradlew + - chmod +x gradlew after_success: - - bash <(curl -s https://codecov.io/bash) + - bash <(curl -s https://codecov.io/bash) # cache between builds cache: diff --git a/src/main/java/ix/IxFromArray.java b/src/main/java/ix/IxFromArray.java index b4c1edc..8014f38 100644 --- a/src/main/java/ix/IxFromArray.java +++ b/src/main/java/ix/IxFromArray.java @@ -1,3 +1,19 @@ +/* + * Copyright 2011-2016 David Karnok + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package ix; import java.util.Iterator; From f2f80af4414e2a4ecc432d8717b967f387483275 Mon Sep 17 00:00:00 2001 From: akarnokd Date: Wed, 6 Jul 2016 15:52:59 +0200 Subject: [PATCH 08/66] Gradle cleanup --- build.gradle | 13 +++++-------- gradle/license.gradle | 6 ------ 2 files changed, 5 insertions(+), 14 deletions(-) delete mode 100644 gradle/license.gradle diff --git a/build.gradle b/build.gradle index 0c2d00b..13ef2a1 100644 --- a/build.gradle +++ b/build.gradle @@ -33,14 +33,11 @@ if (!hasProperty('mainClass')) { ext.mainClass = '' } - - -apply from: file('gradle/maven.gradle') - repositories { mavenCentral() } +apply from: file('gradle/maven.gradle') apply plugin: 'maven' apply plugin: 'osgi' @@ -78,10 +75,6 @@ jar { } } -apply plugin: 'license' - -apply from: file('gradle/license.gradle') - jmh { jmhVersion = '1.11.3' humanOutputFile = null @@ -109,6 +102,10 @@ test { } license { + header rootProject.file('HEADER') + ext.year = Calendar.getInstance().get(Calendar.YEAR) + skipExistingHeaders true + ignoreFailures true excludes(["**/*.md", "**/*.txt"]) } diff --git a/gradle/license.gradle b/gradle/license.gradle deleted file mode 100644 index c1a5658..0000000 --- a/gradle/license.gradle +++ /dev/null @@ -1,6 +0,0 @@ -license { - header rootProject.file('HEADER') - ext.year = Calendar.getInstance().get(Calendar.YEAR) - skipExistingHeaders true - ignoreFailures true -} From f869b5d8971657a172c24047284054488fc224d6 Mon Sep 17 00:00:00 2001 From: akarnokd Date: Wed, 6 Jul 2016 16:10:22 +0200 Subject: [PATCH 09/66] Hopefully jacoco will now run with check --- build.gradle | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/build.gradle b/build.gradle index 13ef2a1..d2c11e2 100644 --- a/build.gradle +++ b/build.gradle @@ -122,13 +122,14 @@ jacocoTestReport { build.dependsOn jacocoTestReport +check.dependsOn jacocoTestReport + pmd { toolVersion = '5.4.2' ignoreFailures = true sourceSets = [sourceSets.main] ruleSets = [] ruleSetFiles = files('pmd.xml') - } pmdMain { @@ -139,7 +140,7 @@ pmdMain { } task pmdPrint(dependsOn: 'pmdMain') << { - File file = new File('build/reports/pmd/main.xml') + File file = rootProject.file('build/reports/pmd/main.xml') if (file.exists()) { println("Listing first 100 PMD violations") @@ -156,6 +157,7 @@ task pmdPrint(dependsOn: 'pmdMain') << { } build.dependsOn pmdPrint +check.dependsOn pmdPrint animalsniffer { annotation = 'rx.internal.util.SuppressAnimalSniffer' From c706ad649cfe8251eece298162b5d3a5e48c9351 Mon Sep 17 00:00:00 2001 From: akarnokd Date: Wed, 6 Jul 2016 17:32:37 +0200 Subject: [PATCH 10/66] Increase coverage --- src/main/java/ix/ReduceHelper.java | 86 --------------------------- src/test/java/ix/ConcatArrayTest.java | 48 ++++++++++++++- 2 files changed, 47 insertions(+), 87 deletions(-) delete mode 100644 src/main/java/ix/ReduceHelper.java diff --git a/src/main/java/ix/ReduceHelper.java b/src/main/java/ix/ReduceHelper.java deleted file mode 100644 index 54be090..0000000 --- a/src/main/java/ix/ReduceHelper.java +++ /dev/null @@ -1,86 +0,0 @@ -/* - * Copyright 2011-2016 David Karnok - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package ix; - -import rx.functions.*; - -enum ReduceHelper { - ; - - enum IntMax implements Func2 { - INSTANCE; - - @Override - public Integer call(Integer t1, Integer t2) { - return t1.compareTo(t2) < 0 ? t2 : t1; - } - } - - enum IntMin implements Func2 { - INSTANCE; - - @Override - public Integer call(Integer t1, Integer t2) { - return t1.compareTo(t2) < 0 ? t1 : t2; - } - } - - enum IntSum implements Func2 { - INSTANCE; - - @Override - public Integer call(Integer t1, Integer t2) { - return t1.intValue() + t2.intValue(); - } - } - - enum NumberToLong implements Func1 { - INSTANCE; - - @Override - public Long call(Number t1) { - return t1.longValue(); - } - } - - enum LongMax implements Func2 { - INSTANCE; - - @Override - public Long call(Long t1, Long t2) { - return t1.compareTo(t2) < 0 ? t2 : t1; - } - } - - enum LongMin implements Func2 { - INSTANCE; - - @Override - public Long call(Long t1, Long t2) { - return t1.compareTo(t2) < 0 ? t1 : t2; - } - } - - enum LongSum implements Func2 { - INSTANCE; - - @Override - public Long call(Long t1, Long t2) { - return t1.longValue() + t2.longValue(); - } - } -} diff --git a/src/test/java/ix/ConcatArrayTest.java b/src/test/java/ix/ConcatArrayTest.java index 2120ac6..aba429f 100644 --- a/src/test/java/ix/ConcatArrayTest.java +++ b/src/test/java/ix/ConcatArrayTest.java @@ -16,7 +16,9 @@ package ix; -import org.junit.Test; +import java.util.Arrays; + +import org.junit.*; public class ConcatArrayTest { @@ -29,6 +31,16 @@ public void normal() { IxTestHelper.assertValues(source, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10); } + @SuppressWarnings("unchecked") + @Test + public void normalViaMerge() { + Ix source = Ix.mergeArray(Ix.range(1, 5), Ix.range(6, 5)); + + + IxTestHelper.assertValues(source, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10); + } + + @SuppressWarnings("unchecked") @Test public void just() { @@ -67,4 +79,38 @@ public void mixedTwo() { IxTestHelper.assertValues(source, 1, 2, 3, 4, 5, 6); } + @Test + public void emptyArray() { + @SuppressWarnings("unchecked") + Ix source = Ix.concatArray(); + + Assert.assertSame(source.getClass().toString(), source, Ix.empty()); + } + + @Test + public void justArray() { + @SuppressWarnings("unchecked") + Ix source = Ix.concatArray(Ix.just(1)); + + Assert.assertTrue(source.getClass().toString(), source instanceof IxScalarCallable); + } + + @SuppressWarnings("unchecked") + @Test + public void concatIterable() { + Ix source = Ix.concat(Arrays.asList(Ix.range(1, 5), Ix.range(6, 5))); + + + IxTestHelper.assertValues(source, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10); + } + + @SuppressWarnings("unchecked") + @Test + public void concatIterableViaMerge() { + Ix source = Ix.merge(Arrays.asList(Ix.range(1, 5), Ix.range(6, 5))); + + + IxTestHelper.assertValues(source, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10); + } + } From 33105f79b154b6da4dd43cc895e73de128b0850b Mon Sep 17 00:00:00 2001 From: akarnokd Date: Wed, 6 Jul 2016 17:40:29 +0200 Subject: [PATCH 11/66] Forgot to stash before commit --- src/main/java/ix/FunctionHelper.java | 9 ++ src/main/java/ix/Ix.java | 132 +++++++++--------- src/main/java/ix/IxCharacters.java | 6 +- src/main/java/ix/IxFlattenIterable.java | 13 +- src/main/java/ix/IxFromArray.java | 6 +- src/main/java/ix/IxJust.java | 4 +- src/main/java/ix/IxRange.java | 6 +- src/main/java/ix/IxSkipLast.java | 8 +- src/test/java/ix/CharactersTest.java | 37 ++++- src/test/java/ix/FirstTest.java | 67 +++++++++ src/test/java/ix/FlattenIterableTest.java | 37 +++++ src/test/java/ix/FromArrayTest.java | 46 +++++- src/test/java/ix/FromTest.java | 43 ++++++ src/test/java/ix/HideTest.java | 31 ++++ src/test/java/ix/IxTest.java | 49 +++++++ src/test/java/ix/IxTestHelper.java | 53 ++++++- src/test/java/ix/JustTest.java | 10 +- src/test/java/ix/LastTest.java | 67 +++++++++ src/test/java/ix/RangeTest.java | 27 +++- src/test/java/ix/ReduceTest.java | 24 ++++ .../java/ix/SourceQueuedIteratorTest.java | 79 +++++++++++ src/test/java/ix/ToArrayTest.java | 29 ++++ src/test/java/ix/ToListTest.java | 32 +++++ 23 files changed, 712 insertions(+), 103 deletions(-) create mode 100644 src/test/java/ix/FirstTest.java create mode 100644 src/test/java/ix/FromTest.java create mode 100644 src/test/java/ix/HideTest.java create mode 100644 src/test/java/ix/LastTest.java create mode 100644 src/test/java/ix/SourceQueuedIteratorTest.java create mode 100644 src/test/java/ix/ToArrayTest.java create mode 100644 src/test/java/ix/ToListTest.java diff --git a/src/main/java/ix/FunctionHelper.java b/src/main/java/ix/FunctionHelper.java index 45a0d78..647e3aa 100644 --- a/src/main/java/ix/FunctionHelper.java +++ b/src/main/java/ix/FunctionHelper.java @@ -35,4 +35,13 @@ public Object call(Object t) { return t; } } + + enum NumberToLong implements Func1 { + INSTANCE; + + @Override + public Long call(Number t1) { + return t1.longValue(); + } + } } diff --git a/src/main/java/ix/Ix.java b/src/main/java/ix/Ix.java index d1638ae..9dd7216 100644 --- a/src/main/java/ix/Ix.java +++ b/src/main/java/ix/Ix.java @@ -19,7 +19,6 @@ import java.util.*; import java.util.concurrent.Callable; -import rx.exceptions.Exceptions; import rx.functions.*; /** @@ -36,36 +35,6 @@ public static Ix empty() { return IxEmpty.instance(); } - /** - * Checks if the value is null and if so, throws - * a NullPointerException with the given message. - * @param the value type - * @param value the value to check for null - * @param message the message to report in the exception - * @return the value - */ - protected static U nullCheck(U value, String message) { - if (value == null) { - throw new NullPointerException(message); - } - return value; - } - - /** - * Convenience method to throw UnsupportedOperationException(); - */ - protected static void unsupported() { - throw new UnsupportedOperationException(); - } - - /** - * Convenience method to throw NoSuchElementException(); - * @param the value type - * @return never returns as it throws - */ - protected static U noelements() { - throw new NoSuchElementException(); - } public static Ix from(Iterable source) { if (source instanceof Ix) { @@ -90,7 +59,7 @@ public static Ix characters(CharSequence cs) { public static Ix characters(CharSequence cs, int start, int end) { int len = cs.length(); - if (start < 0 || start + end > len) { + if (start < 0 || end < 0 || start > len || end > len) { throw new IndexOutOfBoundsException("start=" + start + ", end=" + end + ", length=" + len); } return new IxCharacters(cs, start, end); @@ -151,30 +120,18 @@ public final Ix map(Func1 mapper) { return new IxMap(this, mapper); } + @SuppressWarnings("unchecked") public final T first() { if (this instanceof Callable) { - @SuppressWarnings("unchecked") - Callable c = (Callable) this; - - try { - return c.call(); - } catch (Exception ex) { - Exceptions.propagate(ex); - } + return checkedCall((Callable) this); } return iterator().next(); } + @SuppressWarnings("unchecked") public final T first(T defaultValue) { if (this instanceof Callable) { - @SuppressWarnings("unchecked") - Callable c = (Callable) this; - - try { - return c.call(); - } catch (Exception ex) { - Exceptions.propagate(ex); - } + return checkedCall((Callable) this); } Iterator it = iterator(); if (it.hasNext()) { @@ -183,20 +140,14 @@ public final T first(T defaultValue) { return defaultValue; } + @SuppressWarnings("unchecked") public final T last() { if (this instanceof Callable) { - @SuppressWarnings("unchecked") - Callable c = (Callable) this; - - try { - return c.call(); - } catch (Exception ex) { - Exceptions.propagate(ex); - } + return checkedCall((Callable) this); } Iterator it = iterator(); if (!it.hasNext()) { - return noelements(); + throw new NoSuchElementException(); } for (;;) { @@ -207,16 +158,10 @@ public final T last() { } } + @SuppressWarnings("unchecked") public final T last(T defaultValue) { if (this instanceof Callable) { - @SuppressWarnings("unchecked") - Callable c = (Callable) this; - - try { - return c.call(); - } catch (Exception ex) { - Exceptions.propagate(ex); - } + return checkedCall((Callable) this); } Iterator it = iterator(); if (!it.hasNext()) { @@ -292,7 +237,7 @@ public final Ix sumLong() { @SuppressWarnings("unchecked") public final Ix toLong() { - return ((Ix)this).map(ReduceHelper.NumberToLong.INSTANCE); + return ((Ix)this).map(FunctionHelper.NumberToLong.INSTANCE); } public final Ix skip(int n) { @@ -325,4 +270,59 @@ public final Ix concatMap(Func1(this, mapper); } + // -------------------------------------------------------------------------------------------- + // Helper methods + // -------------------------------------------------------------------------------------------- + + /** + * Checks if the value is null and if so, throws + * a NullPointerException with the given message. + * @param the value type + * @param value the value to check for null + * @param message the message to report in the exception + * @return the value + */ + protected static U nullCheck(U value, String message) { + if (value == null) { + throw new NullPointerException(message); + } + return value; + } + + /** + * Convenience method to throw UnsupportedOperationException(); + */ + protected static void unsupported() { + throw new UnsupportedOperationException(); + } + + /** + * Convenience method to throw NoSuchElementException(); + * @param the value type + * @return never returns as it throws + */ + protected static U noelements() { + throw new NoSuchElementException(); + } + + /** + * Calls the given callable and rethrows its exception + * (as RuntimeException if necessary). + * @param the value type + * @param callable the callable to call + * @return the value returned by the callable + */ + protected static U checkedCall(Callable callable) { + try { + return callable.call(); + } catch (Throwable ex) { + if (ex instanceof RuntimeException) { + throw (RuntimeException)ex; + } + if (ex instanceof Error) { + throw (Error)ex; + } + throw new RuntimeException(ex); + } + } } diff --git a/src/main/java/ix/IxCharacters.java b/src/main/java/ix/IxCharacters.java index f4bae50..0f75588 100644 --- a/src/main/java/ix/IxCharacters.java +++ b/src/main/java/ix/IxCharacters.java @@ -16,7 +16,7 @@ package ix; -import java.util.Iterator; +import java.util.*; final class IxCharacters extends Ix { @@ -63,12 +63,12 @@ public Integer next() { index = i + 1; return (int)source.charAt(i); } - return noelements(); + throw new NoSuchElementException(); } @Override public void remove() { - unsupported(); + throw new UnsupportedOperationException(); } } diff --git a/src/main/java/ix/IxFlattenIterable.java b/src/main/java/ix/IxFlattenIterable.java index 1a6e7c5..6b4aa63 100644 --- a/src/main/java/ix/IxFlattenIterable.java +++ b/src/main/java/ix/IxFlattenIterable.java @@ -19,7 +19,6 @@ import java.util.Iterator; import java.util.concurrent.Callable; -import rx.exceptions.Exceptions; import rx.functions.Func1; final class IxFlattenIterable extends IxSource { @@ -35,11 +34,7 @@ public IxFlattenIterable(Iterable source, Func1 iterator() { if (source instanceof Callable) { - try { - return (Iterator)(mapper.call(((Callable)source).call()).iterator()); - } catch (Exception e) { - Exceptions.propagate(e); - } + return (Iterator)(mapper.call(checkedCall((Callable)source)).iterator()); } return new FlattenIterator(source.iterator(), mapper); } @@ -64,11 +59,7 @@ protected boolean moveNext() { if (it.hasNext()) { Iterable inner = mapper.call(it.next()); if (inner instanceof Callable) { - try { - value = ((Callable)inner).call(); - } catch (Exception e) { - Exceptions.propagate(e); - } + value = checkedCall((Callable)inner); hasValue = true; return true; } diff --git a/src/main/java/ix/IxFromArray.java b/src/main/java/ix/IxFromArray.java index 8014f38..087ff4f 100644 --- a/src/main/java/ix/IxFromArray.java +++ b/src/main/java/ix/IxFromArray.java @@ -16,7 +16,7 @@ package ix; -import java.util.Iterator; +import java.util.*; final class IxFromArray extends Ix { @@ -60,12 +60,12 @@ public T next() { index = i + 1; return array[i]; } - return noelements(); + throw new NoSuchElementException(); } @Override public void remove() { - unsupported(); + throw new UnsupportedOperationException(); } } } diff --git a/src/main/java/ix/IxJust.java b/src/main/java/ix/IxJust.java index abd98b1..ba34558 100644 --- a/src/main/java/ix/IxJust.java +++ b/src/main/java/ix/IxJust.java @@ -57,12 +57,12 @@ public T next() { empty = true; return value; } - return noelements(); + throw new NoSuchElementException(); } @Override public void remove() { - unsupported(); + throw new UnsupportedOperationException(); } } } diff --git a/src/main/java/ix/IxRange.java b/src/main/java/ix/IxRange.java index 0261194..2aa8bcd 100644 --- a/src/main/java/ix/IxRange.java +++ b/src/main/java/ix/IxRange.java @@ -16,7 +16,7 @@ package ix; -import java.util.Iterator; +import java.util.*; final class IxRange extends Ix { @@ -57,12 +57,12 @@ public Integer next() { index = i + 1; return i; } - return noelements(); + throw new NoSuchElementException(); } @Override public void remove() { - unsupported(); + throw new UnsupportedOperationException(); } } diff --git a/src/main/java/ix/IxSkipLast.java b/src/main/java/ix/IxSkipLast.java index 74c67a1..b8cbc31 100644 --- a/src/main/java/ix/IxSkipLast.java +++ b/src/main/java/ix/IxSkipLast.java @@ -66,12 +66,8 @@ protected boolean moveNext() { size = s; } - if (s == 0) { - value = it.next(); - } else { - value = fromObject(poll()); - offer(toObject(it.next())); - } + value = fromObject(poll()); + offer(toObject(it.next())); hasValue = true; diff --git a/src/test/java/ix/CharactersTest.java b/src/test/java/ix/CharactersTest.java index 215c760..af6b977 100644 --- a/src/test/java/ix/CharactersTest.java +++ b/src/test/java/ix/CharactersTest.java @@ -16,7 +16,7 @@ package ix; -import org.junit.Test; +import org.junit.*; public class CharactersTest { @@ -28,5 +28,40 @@ public void normal() { (int)'H', (int)'e', (int)'l', (int)'l', (int)'o', (int)' ', (int)'w', (int)'o', (int)'r', (int)'l', (int)'d', (int)'!'); + + IxTestHelper.assertNoRemove(source); } + + @Test + public void rangeChecks() { + String s = "Hello world"; + + try { + Ix.characters(s, -1, 1); + Assert.fail("Failed to throw IndexOutOfBoundsException"); + } catch (IndexOutOfBoundsException ex) { + Assert.assertEquals("start=-1, end=1, length=11", ex.getMessage()); + } + + try { + Ix.characters(s, 1, -1); + Assert.fail("Failed to throw IndexOutOfBoundsException"); + } catch (IndexOutOfBoundsException ex) { + Assert.assertEquals("start=1, end=-1, length=11", ex.getMessage()); + } + + try { + Ix.characters(s, 12, -1); + Assert.fail("Failed to throw IndexOutOfBoundsException"); + } catch (IndexOutOfBoundsException ex) { + Assert.assertEquals("start=12, end=-1, length=11", ex.getMessage()); + } + + try { + Ix.characters(s, 1, 12); + Assert.fail("Failed to throw IndexOutOfBoundsException"); + } catch (IndexOutOfBoundsException ex) { + Assert.assertEquals("start=1, end=12, length=11", ex.getMessage()); + } + } } diff --git a/src/test/java/ix/FirstTest.java b/src/test/java/ix/FirstTest.java new file mode 100644 index 0000000..e16c444 --- /dev/null +++ b/src/test/java/ix/FirstTest.java @@ -0,0 +1,67 @@ +/* + * Copyright 2011-2016 David Karnok + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ix; + +import java.util.*; + +import org.junit.*; + +public class FirstTest { + + @Test + public void normal() { + Ix source = Ix.range(1, 10); + + Assert.assertEquals(1, source.first().intValue()); + } + + @Test + public void just() { + Ix source = Ix.just(1); + + Assert.assertEquals(1, source.first().intValue()); + } + + @Test(expected = NoSuchElementException.class) + public void empty() { + Ix source = Ix.empty(); + + Assert.assertEquals(1, source.first().intValue()); + } + + @Test + public void emptyDefault() { + Ix source = Ix.empty(); + + Assert.assertEquals(100, source.first(100).intValue()); + } + + @Test + public void justDefault() { + Ix source = Ix.just(1); + + Assert.assertEquals(1, source.first(100).intValue()); + } + + @Test + public void rangeDefault() { + Ix source = Ix.range(1, 10); + + Assert.assertEquals(1, source.first(100).intValue()); + } + +} diff --git a/src/test/java/ix/FlattenIterableTest.java b/src/test/java/ix/FlattenIterableTest.java index 9f95f86..0bcf696 100644 --- a/src/test/java/ix/FlattenIterableTest.java +++ b/src/test/java/ix/FlattenIterableTest.java @@ -32,6 +32,20 @@ public Iterable call(Integer v) { }); IxTestHelper.assertValues(source, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6); + + IxTestHelper.assertNoRemove(source); + } + + @Test + public void normalViaConcatMap() { + Ix source = Ix.range(1, 5).concatMap(new Func1>() { + @Override + public Iterable call(Integer v) { + return Ix.range(v, 2); + } + }); + + IxTestHelper.assertValues(source, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6); } @Test @@ -58,4 +72,27 @@ public Iterable call(Integer v) { IxTestHelper.assertValues(source); } + @Test + public void rangeJust() { + Ix source = Ix.range(1, 2).flatMap(new Func1>() { + @Override + public Iterable call(Integer v) { + return Ix.just(v); + } + }); + + IxTestHelper.assertValues(source, 1, 2); + } + + @Test + public void rangeEmpty() { + Ix source = Ix.range(1, 2).flatMap(new Func1>() { + @Override + public Iterable call(Integer v) { + return Ix.empty(); + } + }); + + IxTestHelper.assertValues(source); + } } diff --git a/src/test/java/ix/FromArrayTest.java b/src/test/java/ix/FromArrayTest.java index a182ed5..35d7fb6 100644 --- a/src/test/java/ix/FromArrayTest.java +++ b/src/test/java/ix/FromArrayTest.java @@ -16,7 +16,7 @@ package ix; -import org.junit.Test; +import org.junit.*; public class FromArrayTest { @@ -33,5 +33,49 @@ public void range() { IxTestHelper.assertValues(source, 2, 3, 4, 5, 6, 7, 8); } + + @Test + public void empty() { + Ix source = Ix.fromArray(); + + Assert.assertSame(source.getClass().toString(), source, Ix.empty()); + } + @Test + public void just() { + Ix source = Ix.fromArray(1); + + Assert.assertTrue(source.getClass().toString(), source instanceof IxScalarCallable); + } + + @Test + public void rangeChecks() { + try { + Ix.fromArrayRange(-1, 1, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10); + Assert.fail("Failed to throw IndexOutOfBoundsException"); + } catch (IndexOutOfBoundsException ex) { + Assert.assertEquals("start=-1, end=1, length=10", ex.getMessage()); + } + + try { + Ix.fromArrayRange(1, -1, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10); + Assert.fail("Failed to throw IndexOutOfBoundsException"); + } catch (IndexOutOfBoundsException ex) { + Assert.assertEquals("start=1, end=-1, length=10", ex.getMessage()); + } + + try { + Ix.fromArrayRange(12, -1, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10); + Assert.fail("Failed to throw IndexOutOfBoundsException"); + } catch (IndexOutOfBoundsException ex) { + Assert.assertEquals("start=12, end=-1, length=10", ex.getMessage()); + } + + try { + Ix.fromArrayRange(1, 12, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10); + Assert.fail("Failed to throw IndexOutOfBoundsException"); + } catch (IndexOutOfBoundsException ex) { + Assert.assertEquals("start=1, end=12, length=10", ex.getMessage()); + } + } } diff --git a/src/test/java/ix/FromTest.java b/src/test/java/ix/FromTest.java new file mode 100644 index 0000000..82a1d3a --- /dev/null +++ b/src/test/java/ix/FromTest.java @@ -0,0 +1,43 @@ +/* + * Copyright 2011-2016 David Karnok + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ix; + +import java.util.Arrays; + +import org.junit.*; + +public class FromTest { + + @Test + public void normal() { + Ix source = Ix.from(Arrays.asList(1, 2, 3, 4, 5)); + + Assert.assertTrue(source.getClass().toString(), source instanceof IxWrapper); + + IxTestHelper.assertValues(source, 1, 2, 3, 4, 5); + } + + @Test + public void noRewrapping() { + Ix source = Ix.from(Ix.range(1, 5)); + + Assert.assertFalse(source.getClass().toString(), source instanceof IxWrapper); + + IxTestHelper.assertValues(source, 1, 2, 3, 4, 5); + } + +} diff --git a/src/test/java/ix/HideTest.java b/src/test/java/ix/HideTest.java new file mode 100644 index 0000000..1e2622f --- /dev/null +++ b/src/test/java/ix/HideTest.java @@ -0,0 +1,31 @@ +/* + * Copyright 2011-2016 David Karnok + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ix; + +import org.junit.*; + +public class HideTest { + + @Test + public void normal() { + Ix source = Ix.just(1); + + Assert.assertTrue(source instanceof IxScalarCallable); + + Assert.assertFalse((source.hide()) instanceof IxScalarCallable); + } +} diff --git a/src/test/java/ix/IxTest.java b/src/test/java/ix/IxTest.java index ecfe75e..0f9321a 100644 --- a/src/test/java/ix/IxTest.java +++ b/src/test/java/ix/IxTest.java @@ -16,6 +16,55 @@ package ix; +import java.io.IOException; +import java.util.concurrent.Callable; + +import org.junit.*; + public class IxTest { + @Test(expected = RuntimeException.class) + public void checkedCallWraps() { + + Ix.checkedCall(new Callable() { + @Override + public Integer call() throws Exception { + throw new IOException(); + } + }); + } + + @Test(expected = InternalError.class) + public void checkedCallNoWrapsError() { + + Ix.checkedCall(new Callable() { + @Override + public Integer call() throws Exception { + throw new InternalError(); + } + }); + } + + @Test(expected = IllegalArgumentException.class) + public void checkedCallNoWrapping() { + + Ix.checkedCall(new Callable() { + @Override + public Integer call() throws Exception { + throw new IllegalArgumentException(); + } + }); + } + + @Test + public void nullCheck() { + Ix.nullCheck(1, "Should not fail"); + try { + Ix.nullCheck(null, "Failure"); + Assert.fail("Failed to throw NPE"); + } catch (NullPointerException ex) { + Assert.assertEquals("Failure", ex.getMessage()); + } + } + } diff --git a/src/test/java/ix/IxTestHelper.java b/src/test/java/ix/IxTestHelper.java index 0c9e17e..56304a8 100644 --- a/src/test/java/ix/IxTestHelper.java +++ b/src/test/java/ix/IxTestHelper.java @@ -16,6 +16,8 @@ package ix; +import java.util.*; + import org.junit.Assert; public enum IxTestHelper { @@ -25,17 +27,41 @@ static String classOf(Object o) { return o != null ? o.getClass().getSimpleName() : "null"; } + /** + * Asserts that the iterable produces the specified array of values and + * verifies if it honors the iterator contract. + * @param the value type + * @param source the source sequence to validate + * @param values the values expected + */ public static void assertValues(Iterable source, T... values) { + Iterator a = source.iterator(); int i = 0; - for (T t : source) { + for (;;) { + boolean b1 = a.hasNext(); + boolean b2 = a.hasNext(); + + Assert.assertEquals("Inconsistent hasNext()", b1, b2); + + if (!b1) { + break; + } + if (i == values.length) { throw new AssertionError("The source is longer than " + values.length); } + + T t = a.next(); + + if (t instanceof Object[]) { + Assert.assertArrayEquals((Object[])values[i], (Object[])t); + } else { Assert.assertEquals("index=" + i + ", expected class=" + classOf(values[i]) + ", actual class=" + classOf(t), values[i], t); + } i++; } @@ -43,5 +69,30 @@ public static void assertValues(Iterable source, T... values) { throw new AssertionError("The source is shorter than " + values.length); } + try { + a.next(); + Assert.fail("The next() should have thrown a NoSuchElementException"); + } catch (NoSuchElementException ex) { + // expected + } + } + + /** + * Assert that calling remove() on the source's Iterator throws + * an UnsupportedOperationException. + * @param source the source to validate + */ + public static void assertNoRemove(Iterable source) { + Iterator it = source.iterator(); + + if (it.hasNext()) { + it.next(); + try { + it.remove(); + Assert.fail("Should have thrown UnsupportedOperationException"); + } catch (UnsupportedOperationException ex) { + // expected + } + } } } diff --git a/src/test/java/ix/JustTest.java b/src/test/java/ix/JustTest.java index c6cb546..cb2bc6c 100644 --- a/src/test/java/ix/JustTest.java +++ b/src/test/java/ix/JustTest.java @@ -16,17 +16,17 @@ package ix; +import java.util.*; + import org.junit.Test; -import static org.junit.Assert.*; public class JustTest { + @SuppressWarnings("unchecked") @Test public void normal() { - Ix source = Ix.just(1); - - assertEquals(1, source.iterator().next().intValue()); + Ix> source = Ix.range(1, 10).toList(); - IxTestHelper.assertValues(source, 1); + IxTestHelper.assertValues(source, Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)); } } diff --git a/src/test/java/ix/LastTest.java b/src/test/java/ix/LastTest.java new file mode 100644 index 0000000..a921b2f --- /dev/null +++ b/src/test/java/ix/LastTest.java @@ -0,0 +1,67 @@ +/* + * Copyright 2011-2016 David Karnok + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ix; + +import java.util.*; + +import org.junit.*; + +public class LastTest { + + @Test + public void normal() { + Ix source = Ix.range(1, 10); + + Assert.assertEquals(10, source.last().intValue()); + } + + @Test + public void just() { + Ix source = Ix.just(1); + + Assert.assertEquals(1, source.last().intValue()); + } + + @Test(expected = NoSuchElementException.class) + public void empty() { + Ix source = Ix.empty(); + + Assert.assertEquals(1, source.last().intValue()); + } + + @Test + public void emptyDefault() { + Ix source = Ix.empty(); + + Assert.assertEquals(100, source.last(100).intValue()); + } + + @Test + public void justDefault() { + Ix source = Ix.just(1); + + Assert.assertEquals(1, source.last(100).intValue()); + } + + @Test + public void rangeDefault() { + Ix source = Ix.range(1, 10); + + Assert.assertEquals(10, source.last(100).intValue()); + } + +} diff --git a/src/test/java/ix/RangeTest.java b/src/test/java/ix/RangeTest.java index fb3347d..b2688d5 100644 --- a/src/test/java/ix/RangeTest.java +++ b/src/test/java/ix/RangeTest.java @@ -16,7 +16,9 @@ package ix; -import org.junit.Test; +import java.util.Iterator; + +import org.junit.*; public class RangeTest { @@ -25,5 +27,28 @@ public void normal() { Ix source = Ix.range(1, 10); IxTestHelper.assertValues(source, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10); + + IxTestHelper.assertNoRemove(source); + } + + @Test(expected = UnsupportedOperationException.class) + public void cantRemove() { + Iterator it = Ix.range(1, 10).iterator(); + it.next(); + it.remove(); + } + + @Test + public void empty() { + Ix source = Ix.range(1, 0); + + Assert.assertSame(Ix.empty(), source); + } + + @Test + public void just() { + Ix source = Ix.range(1, 1); + + Assert.assertTrue(source.getClass().toString(), source instanceof IxScalarCallable); } } diff --git a/src/test/java/ix/ReduceTest.java b/src/test/java/ix/ReduceTest.java index b66d8a1..08241e3 100644 --- a/src/test/java/ix/ReduceTest.java +++ b/src/test/java/ix/ReduceTest.java @@ -40,4 +40,28 @@ public Integer call(Integer a, Integer b) { assertEquals(55, source.first().intValue()); } + + @Test + public void aggregate() { + Ix source = Ix.range(1, 10).reduce(new Func2() { + @Override + public Integer call(Integer a, Integer b) { + return a + b; + } + }); + + assertEquals(55, source.first().intValue()); + } + + @Test + public void aggregateEmpty() { + Ix source = Ix.empty().reduce(new Func2() { + @Override + public Integer call(Integer a, Integer b) { + return a + b; + } + }); + + IxTestHelper.assertValues(source); + } } diff --git a/src/test/java/ix/SourceQueuedIteratorTest.java b/src/test/java/ix/SourceQueuedIteratorTest.java new file mode 100644 index 0000000..c3b1d84 --- /dev/null +++ b/src/test/java/ix/SourceQueuedIteratorTest.java @@ -0,0 +1,79 @@ +/* + * Copyright 2011-2016 David Karnok + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ix; + +import org.junit.*; + +public class SourceQueuedIteratorTest { + + IxSourceQueuedIterator it; + + @Before + public void before() { + it = new IxSourceQueuedIterator(Ix.empty().iterator()) { + + @Override + protected boolean moveNext() { + return false; + } + }; + } + + @Test + public void normal() { + Assert.assertTrue(it.isEmpty()); + + it.offer(1); + + Assert.assertFalse(it.isEmpty()); + + Assert.assertEquals(1, it.poll()); + Assert.assertTrue(it.isEmpty()); + + Assert.assertNull(it.poll()); + Assert.assertTrue(it.isEmpty()); + } + + @Test(expected = NullPointerException.class) + public void nullOffer() { + it.offer(null); + } + + @Test + public void clear() { + Assert.assertTrue(it.isEmpty()); + + it.offer(1); + + Assert.assertFalse(it.isEmpty()); + + it.clear(); + + Assert.assertNull(it.poll()); + Assert.assertTrue(it.isEmpty()); + } + + @Test + public void nullWraps() { + Assert.assertSame(IxSourceQueuedIterator.NULL, it.toObject(null)); + } + + @Test + public void nullUnwraps() { + Assert.assertNull(it.fromObject(IxSourceQueuedIterator.NULL)); + } +} diff --git a/src/test/java/ix/ToArrayTest.java b/src/test/java/ix/ToArrayTest.java new file mode 100644 index 0000000..9f5f681 --- /dev/null +++ b/src/test/java/ix/ToArrayTest.java @@ -0,0 +1,29 @@ +/* + * Copyright 2011-2016 David Karnok + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ix; + +import org.junit.Test; + +public class ToArrayTest { + + @Test + public void normal() { + Ix source = Ix.range(1, 10).toArray(); + + IxTestHelper.assertValues(source, new Object[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }); + } +} diff --git a/src/test/java/ix/ToListTest.java b/src/test/java/ix/ToListTest.java new file mode 100644 index 0000000..30366a9 --- /dev/null +++ b/src/test/java/ix/ToListTest.java @@ -0,0 +1,32 @@ +/* + * Copyright 2011-2016 David Karnok + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ix; + +import org.junit.Test; +import static org.junit.Assert.*; + +public class ToListTest { + + @Test + public void normal() { + Ix source = Ix.just(1); + + assertEquals(1, source.iterator().next().intValue()); + + IxTestHelper.assertValues(source, 1); + } +} From a54e04d090dde9f8d51743b034e00bcc6b1d32de Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?D=C3=A1vid=20Karnok?= Date: Wed, 6 Jul 2016 19:00:17 +0200 Subject: [PATCH 12/66] Refactors and full coverage (locally it is) --- src/main/java/ix/IdentityHelper.java | 18 ++++++++ src/main/java/ix/Ix.java | 30 +++++-------- src/main/java/ix/IxBaseIterator.java | 6 +-- src/main/java/ix/IxEmpty.java | 4 +- src/main/java/ix/IxFlattenArrayIterable.java | 8 +--- src/main/java/ix/NumberToLongHelper.java | 12 ++++++ .../java/ix/EmptyTest.java} | 38 ++++++++-------- src/test/java/ix/FilterTest.java | 17 +++++++- src/test/java/ix/FromArrayTest.java | 2 + src/test/java/ix/HelperTest.java | 43 +++++++++++++++++++ src/test/java/ix/JustTest.java | 9 ++-- src/test/java/ix/MapTest.java | 18 +++++++- 12 files changed, 147 insertions(+), 58 deletions(-) create mode 100644 src/main/java/ix/IdentityHelper.java create mode 100644 src/main/java/ix/NumberToLongHelper.java rename src/{main/java/ix/FunctionHelper.java => test/java/ix/EmptyTest.java} (54%) create mode 100644 src/test/java/ix/HelperTest.java diff --git a/src/main/java/ix/IdentityHelper.java b/src/main/java/ix/IdentityHelper.java new file mode 100644 index 0000000..c5c9085 --- /dev/null +++ b/src/main/java/ix/IdentityHelper.java @@ -0,0 +1,18 @@ +package ix; + +import rx.functions.Func1; + +enum IdentityHelper implements Func1 { + INSTANCE + ; + + @SuppressWarnings("unchecked") + public static Func1 instance() { + return (Func1)INSTANCE; + } + + @Override + public Object call(Object t) { + return t; + } +} \ No newline at end of file diff --git a/src/main/java/ix/Ix.java b/src/main/java/ix/Ix.java index 9dd7216..85cf215 100644 --- a/src/main/java/ix/Ix.java +++ b/src/main/java/ix/Ix.java @@ -102,14 +102,14 @@ public static Ix mergeArray(Iterable... sources) { public static Ix concat(Iterable> sources) { return new IxFlattenIterable, T>( (Iterable)sources, - FunctionHelper.Identity.>instance()); + IdentityHelper.>instance()); } @SuppressWarnings({ "unchecked", "rawtypes" }) public static Ix merge(Iterable> sources) { return new IxFlattenIterable, T>( (Iterable)sources, - FunctionHelper.Identity.>instance()); + IdentityHelper.>instance()); } //--------------------------------------------------------------------------------------- @@ -237,7 +237,7 @@ public final Ix sumLong() { @SuppressWarnings("unchecked") public final Ix toLong() { - return ((Ix)this).map(FunctionHelper.NumberToLong.INSTANCE); + return ((Ix)this).map(NumberToLongHelper.INSTANCE); } public final Ix skip(int n) { @@ -270,6 +270,14 @@ public final Ix concatMap(Func1(this, mapper); } + public final void removeAll() { + Iterator it = iterator(); + while (it.hasNext()) { + it.next(); + it.remove(); + } + } + // -------------------------------------------------------------------------------------------- // Helper methods // -------------------------------------------------------------------------------------------- @@ -289,22 +297,6 @@ protected static U nullCheck(U value, String message) { return value; } - /** - * Convenience method to throw UnsupportedOperationException(); - */ - protected static void unsupported() { - throw new UnsupportedOperationException(); - } - - /** - * Convenience method to throw NoSuchElementException(); - * @param the value type - * @return never returns as it throws - */ - protected static U noelements() { - throw new NoSuchElementException(); - } - /** * Calls the given callable and rethrows its exception * (as RuntimeException if necessary). diff --git a/src/main/java/ix/IxBaseIterator.java b/src/main/java/ix/IxBaseIterator.java index 52b2658..0fe02a3 100644 --- a/src/main/java/ix/IxBaseIterator.java +++ b/src/main/java/ix/IxBaseIterator.java @@ -16,7 +16,7 @@ package ix; -import java.util.Iterator; +import java.util.*; /** * A base iterator that manages @@ -56,7 +56,7 @@ public final boolean hasNext() { @Override public final R next() { if (!hasValue && !hasNext()) { - return Ix.noelements(); + throw new NoSuchElementException(); } R v = value; hasValue = false; @@ -66,6 +66,6 @@ public final R next() { @Override public void remove() { - Ix.unsupported(); + throw new UnsupportedOperationException(); } } diff --git a/src/main/java/ix/IxEmpty.java b/src/main/java/ix/IxEmpty.java index 9bc9d2d..a19d66e 100644 --- a/src/main/java/ix/IxEmpty.java +++ b/src/main/java/ix/IxEmpty.java @@ -39,11 +39,11 @@ public boolean hasNext() { @Override public Object next() { - return noelements(); + throw new NoSuchElementException(); } @Override public void remove() { - unsupported(); + throw new UnsupportedOperationException(); } } diff --git a/src/main/java/ix/IxFlattenArrayIterable.java b/src/main/java/ix/IxFlattenArrayIterable.java index 1dbcb91..35d127e 100644 --- a/src/main/java/ix/IxFlattenArrayIterable.java +++ b/src/main/java/ix/IxFlattenArrayIterable.java @@ -19,8 +19,6 @@ import java.util.Iterator; import java.util.concurrent.Callable; -import rx.exceptions.Exceptions; - final class IxFlattenArrayIterable extends Ix { final Iterable[] sources; @@ -57,11 +55,7 @@ protected boolean moveNext() { Iterable inner = sources[i]; index = i + 1; if (inner instanceof Callable) { - try { - value = ((Callable)inner).call(); - } catch (Exception e) { - Exceptions.propagate(e); - } + value = checkedCall(((Callable)inner)); hasValue = true; return true; } diff --git a/src/main/java/ix/NumberToLongHelper.java b/src/main/java/ix/NumberToLongHelper.java new file mode 100644 index 0000000..7c2d09f --- /dev/null +++ b/src/main/java/ix/NumberToLongHelper.java @@ -0,0 +1,12 @@ +package ix; + +import rx.functions.Func1; + +enum NumberToLongHelper implements Func1 { + INSTANCE; + + @Override + public Long call(Number t1) { + return t1.longValue(); + } +} \ No newline at end of file diff --git a/src/main/java/ix/FunctionHelper.java b/src/test/java/ix/EmptyTest.java similarity index 54% rename from src/main/java/ix/FunctionHelper.java rename to src/test/java/ix/EmptyTest.java index 647e3aa..0e9d2ac 100644 --- a/src/main/java/ix/FunctionHelper.java +++ b/src/test/java/ix/EmptyTest.java @@ -16,32 +16,30 @@ package ix; -import rx.functions.Func1; +import org.junit.*; -enum FunctionHelper { - ; - - enum Identity implements Func1 { - INSTANCE - ; +public class EmptyTest { + + @Test + public void normal() { + Ix source = Ix.empty(); - @SuppressWarnings("unchecked") - public static Func1 instance() { - return (Func1)INSTANCE; - } + IxTestHelper.assertValues(source); - @Override - public Object call(Object t) { - return t; - } + IxTestHelper.assertNoRemove(source); } - enum NumberToLong implements Func1 { - INSTANCE; + @Test + public void removeThrows() { + Ix source = Ix.empty(); + + IxTestHelper.assertNoRemove(source); - @Override - public Long call(Number t1) { - return t1.longValue(); + try { + source.iterator().remove(); + Assert.fail("Should have thrown UnsupportedOperationException"); + } catch (UnsupportedOperationException ex) { + // expected } } } diff --git a/src/test/java/ix/FilterTest.java b/src/test/java/ix/FilterTest.java index cb22522..fdfd2af 100644 --- a/src/test/java/ix/FilterTest.java +++ b/src/test/java/ix/FilterTest.java @@ -16,7 +16,9 @@ package ix; -import org.junit.Test; +import java.util.*; + +import org.junit.*; public class FilterTest { @@ -56,4 +58,17 @@ public boolean test(Integer v) { IxTestHelper.assertValues(source); } + @Test + public void removeComposes() { + List list = Ix.range(1, 10).toList().first(); + + Ix.from(list).filter(new Pred() { + @Override + public boolean test(Integer v) { + return (v & 1) != 0; + } + }).removeAll(); + + Assert.assertEquals(Arrays.asList(2, 4, 6, 8, 10), list); + } } diff --git a/src/test/java/ix/FromArrayTest.java b/src/test/java/ix/FromArrayTest.java index 35d7fb6..fd06ad9 100644 --- a/src/test/java/ix/FromArrayTest.java +++ b/src/test/java/ix/FromArrayTest.java @@ -25,6 +25,8 @@ public void normal() { Ix source = Ix.fromArray(1, 2, 3, 4, 5, 6, 7, 8, 9, 10); IxTestHelper.assertValues(source, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10); + + IxTestHelper.assertNoRemove(source); } @Test diff --git a/src/test/java/ix/HelperTest.java b/src/test/java/ix/HelperTest.java new file mode 100644 index 0000000..d53fea1 --- /dev/null +++ b/src/test/java/ix/HelperTest.java @@ -0,0 +1,43 @@ +/* + * Copyright 2011-2016 David Karnok + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ix; + +import org.junit.*; + +public class HelperTest { + + @Test + public void toListHelper() { + Assert.assertEquals(1, ToListHelper.values().length); + + Assert.assertNotNull(ToListHelper.valueOf("INSTANCE")); + } + + @Test + public void identityHelper() { + Assert.assertEquals(1, IdentityHelper.values().length); + + Assert.assertNotNull(IdentityHelper.valueOf("INSTANCE")); + } + + @Test + public void numberToLongHelper() { + Assert.assertEquals(1, NumberToLongHelper.values().length); + + Assert.assertNotNull(NumberToLongHelper.valueOf("INSTANCE")); + } +} diff --git a/src/test/java/ix/JustTest.java b/src/test/java/ix/JustTest.java index cb2bc6c..7fe8359 100644 --- a/src/test/java/ix/JustTest.java +++ b/src/test/java/ix/JustTest.java @@ -16,17 +16,16 @@ package ix; -import java.util.*; - import org.junit.Test; public class JustTest { - @SuppressWarnings("unchecked") @Test public void normal() { - Ix> source = Ix.range(1, 10).toList(); + Ix source = Ix.just(1); + + IxTestHelper.assertValues(source, 1); - IxTestHelper.assertValues(source, Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)); + IxTestHelper.assertNoRemove(source); } } diff --git a/src/test/java/ix/MapTest.java b/src/test/java/ix/MapTest.java index 2bddf06..d3c5f1e 100644 --- a/src/test/java/ix/MapTest.java +++ b/src/test/java/ix/MapTest.java @@ -16,7 +16,9 @@ package ix; -import org.junit.Test; +import java.util.*; + +import org.junit.*; import rx.functions.Func1; @@ -33,4 +35,18 @@ public Integer call(Integer v) { IxTestHelper.assertValues(source, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11); } + + @Test + public void removeComposes() { + List list = Ix.range(1, 10).toList().first(); + + Ix.from(list).map(new Func1() { + @Override + public Integer call(Integer v) { + return v + 1; + } + }).removeAll(); + + Assert.assertEquals(Arrays.asList(), list); + } } From 81ff022c1bd574aae1c06fec46f94274f4d9a4a6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?D=C3=A1vid=20Karnok?= Date: Wed, 6 Jul 2016 20:14:55 +0200 Subject: [PATCH 13/66] Update tests, + operators --- src/main/java/ix/Ix.java | 14 ++++- src/main/java/ix/IxSkipWhile.java | 78 ++++++++++++++++++++++++++++ src/main/java/ix/IxTakeUntil.java | 65 +++++++++++++++++++++++ src/main/java/ix/IxTakeWhile.java | 66 +++++++++++++++++++++++ src/test/java/ix/CharactersTest.java | 20 ++++++- src/test/java/ix/FromArrayTest.java | 8 +++ src/test/java/ix/IxTestHelper.java | 4 ++ src/test/java/ix/SkipWhileTest.java | 76 +++++++++++++++++++++++++++ src/test/java/ix/TakeUntilTest.java | 76 +++++++++++++++++++++++++++ src/test/java/ix/TakeWhileTest.java | 76 +++++++++++++++++++++++++++ 10 files changed, 481 insertions(+), 2 deletions(-) create mode 100644 src/main/java/ix/IxSkipWhile.java create mode 100644 src/main/java/ix/IxTakeUntil.java create mode 100644 src/main/java/ix/IxTakeWhile.java create mode 100644 src/test/java/ix/SkipWhileTest.java create mode 100644 src/test/java/ix/TakeUntilTest.java create mode 100644 src/test/java/ix/TakeWhileTest.java diff --git a/src/main/java/ix/Ix.java b/src/main/java/ix/Ix.java index 85cf215..1924611 100644 --- a/src/main/java/ix/Ix.java +++ b/src/main/java/ix/Ix.java @@ -54,7 +54,7 @@ public static Ix range(int start, int count) { } public static Ix characters(CharSequence cs) { - return characters(cs, 0, cs.length()); + return new IxCharacters(cs, 0, cs.length()); } public static Ix characters(CharSequence cs, int start, int end) { @@ -278,6 +278,18 @@ public final void removeAll() { } } + public final Ix skipWhile(Pred predicate) { + return new IxSkipWhile(this, predicate); + } + + public final Ix takeWhile(Pred predicate) { + return new IxTakeWhile(this, predicate); + } + + public final Ix takeUntil(Pred stopPredicate) { + return new IxTakeUntil(this, stopPredicate); + } + // -------------------------------------------------------------------------------------------- // Helper methods // -------------------------------------------------------------------------------------------- diff --git a/src/main/java/ix/IxSkipWhile.java b/src/main/java/ix/IxSkipWhile.java new file mode 100644 index 0000000..d17f91c --- /dev/null +++ b/src/main/java/ix/IxSkipWhile.java @@ -0,0 +1,78 @@ +/* + * Copyright 2011-2016 David Karnok + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ix; + +import java.util.Iterator; + +final class IxSkipWhile extends IxSource { + + final Pred predicate; + + public IxSkipWhile(Iterable source, Pred predicate) { + super(source); + this.predicate = predicate; + } + + @Override + public Iterator iterator() { + return new SkipWhileIterator(source.iterator(), predicate); + } + + static final class SkipWhileIterator extends IxSourceIterator { + + final Pred predicate; + + boolean passthrough; + + public SkipWhileIterator(Iterator it, Pred predicate) { + super(it); + this.predicate = predicate; + } + + @Override + protected boolean moveNext() { + if (passthrough) { + if (it.hasNext()) { + hasValue = true; + value = it.next(); + return true; + } + done = true; + return false; + } + + while (it.hasNext()) { + T v = it.next(); + if (!predicate.test(v)) { + passthrough = true; + hasValue = true; + value = v; + return true; + } + } + + done = true; + return false; + } + + @Override + public void remove() { + it.remove(); + } + } + +} diff --git a/src/main/java/ix/IxTakeUntil.java b/src/main/java/ix/IxTakeUntil.java new file mode 100644 index 0000000..38f61fa --- /dev/null +++ b/src/main/java/ix/IxTakeUntil.java @@ -0,0 +1,65 @@ +/* + * Copyright 2011-2016 David Karnok + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ix; + +import java.util.Iterator; + +final class IxTakeUntil extends IxSource { + + final Pred predicate; + + public IxTakeUntil(Iterable source, Pred predicate) { + super(source); + this.predicate = predicate; + } + + @Override + public Iterator iterator() { + return new TakeUntilIterator(source.iterator(), predicate); + } + + static final class TakeUntilIterator extends IxSourceIterator { + + final Pred predicate; + + public TakeUntilIterator(Iterator it, Pred predicate) { + super(it); + this.predicate = predicate; + } + + @Override + protected boolean moveNext() { + if (it.hasNext()) { + T v = it.next(); + value = v; + hasValue = true; + if (predicate.test(v)) { + done = true; + } + return true; + } + done = true; + return false; + } + + @Override + public void remove() { + it.remove(); + } + } + +} diff --git a/src/main/java/ix/IxTakeWhile.java b/src/main/java/ix/IxTakeWhile.java new file mode 100644 index 0000000..438f966 --- /dev/null +++ b/src/main/java/ix/IxTakeWhile.java @@ -0,0 +1,66 @@ +/* + * Copyright 2011-2016 David Karnok + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ix; + +import java.util.Iterator; + +final class IxTakeWhile extends IxSource { + + final Pred predicate; + + public IxTakeWhile(Iterable source, Pred predicate) { + super(source); + this.predicate = predicate; + } + + @Override + public Iterator iterator() { + return new TakeWhileIterator(source.iterator(), predicate); + } + + static final class TakeWhileIterator extends IxSourceIterator { + + final Pred predicate; + + public TakeWhileIterator(Iterator it, Pred predicate) { + super(it); + this.predicate = predicate; + } + + @Override + protected boolean moveNext() { + if (it.hasNext()) { + T v = it.next(); + if (!predicate.test(v)) { + done = true; + return false; + } + value = v; + hasValue = true; + return true; + } + done = true; + return false; + } + + @Override + public void remove() { + it.remove(); + } + } + +} diff --git a/src/test/java/ix/CharactersTest.java b/src/test/java/ix/CharactersTest.java index af6b977..c269c50 100644 --- a/src/test/java/ix/CharactersTest.java +++ b/src/test/java/ix/CharactersTest.java @@ -31,7 +31,18 @@ public void normal() { IxTestHelper.assertNoRemove(source); } - + + @Test + public void normalRange() { + Ix source = Ix.characters("Hello world!", 2, 8); + + IxTestHelper.assertValues(source, + (int)'l', (int)'l', + (int)'o', (int)' ', (int)'w', (int)'o'); + + IxTestHelper.assertNoRemove(source); + } + @Test public void rangeChecks() { String s = "Hello world"; @@ -63,5 +74,12 @@ public void rangeChecks() { } catch (IndexOutOfBoundsException ex) { Assert.assertEquals("start=1, end=12, length=11", ex.getMessage()); } + + try { + Ix.characters(s, 12, 12); + Assert.fail("Failed to throw IndexOutOfBoundsException"); + } catch (IndexOutOfBoundsException ex) { + Assert.assertEquals("start=12, end=12, length=11", ex.getMessage()); + } } } diff --git a/src/test/java/ix/FromArrayTest.java b/src/test/java/ix/FromArrayTest.java index fd06ad9..18d5944 100644 --- a/src/test/java/ix/FromArrayTest.java +++ b/src/test/java/ix/FromArrayTest.java @@ -79,5 +79,13 @@ public void rangeChecks() { } catch (IndexOutOfBoundsException ex) { Assert.assertEquals("start=1, end=12, length=10", ex.getMessage()); } + + try { + Ix.fromArrayRange(12, 12, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10); + Assert.fail("Failed to throw IndexOutOfBoundsException"); + } catch (IndexOutOfBoundsException ex) { + Assert.assertEquals("start=12, end=12, length=10", ex.getMessage()); + } + } } diff --git a/src/test/java/ix/IxTestHelper.java b/src/test/java/ix/IxTestHelper.java index 56304a8..cfdc589 100644 --- a/src/test/java/ix/IxTestHelper.java +++ b/src/test/java/ix/IxTestHelper.java @@ -95,4 +95,8 @@ public static void assertNoRemove(Iterable source) { } } } + + public static List range(int start, int count) { + return Ix.range(1, 10).toList().first(); + } } diff --git a/src/test/java/ix/SkipWhileTest.java b/src/test/java/ix/SkipWhileTest.java new file mode 100644 index 0000000..9dcefcf --- /dev/null +++ b/src/test/java/ix/SkipWhileTest.java @@ -0,0 +1,76 @@ +/* + * Copyright 2011-2016 David Karnok + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ix; + +import java.util.*; + +import org.junit.*; + +public class SkipWhileTest { + + @Test + public void normal() { + Ix source = Ix.range(1, 10).skipWhile(new Pred() { + @Override + public boolean test(Integer v) { + return v < 6; + } + }); + + IxTestHelper.assertValues(source, 6, 7, 8, 9, 10); + + IxTestHelper.assertNoRemove(source); + } + + @Test + public void skipAll() { + Ix source = Ix.range(1, 10).skipWhile(new Pred() { + @Override + public boolean test(Integer v) { + return true; + } + }); + + IxTestHelper.assertValues(source); + } + + @Test + public void skipNone() { + Ix source = Ix.range(1, 10).skipWhile(new Pred() { + @Override + public boolean test(Integer v) { + return false; + } + }); + + IxTestHelper.assertValues(source, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10); + } + + @Test + public void removeUnskipped() { + List list = IxTestHelper.range(1, 10); + Ix.from(list).skipWhile(new Pred() { + @Override + public boolean test(Integer v) { + return v < 6; + } + }).removeAll(); + + Assert.assertEquals(Arrays.asList(1, 2, 3, 4, 5), list); + } + +} diff --git a/src/test/java/ix/TakeUntilTest.java b/src/test/java/ix/TakeUntilTest.java new file mode 100644 index 0000000..1da5893 --- /dev/null +++ b/src/test/java/ix/TakeUntilTest.java @@ -0,0 +1,76 @@ +/* + * Copyright 2011-2016 David Karnok + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ix; + +import java.util.*; + +import org.junit.*; + +public class TakeUntilTest { + + @Test + public void normal() { + Ix source = Ix.range(1, 10).takeUntil(new Pred() { + @Override + public boolean test(Integer v) { + return v == 5; + } + }); + + IxTestHelper.assertValues(source, 1, 2, 3, 4, 5); + + IxTestHelper.assertNoRemove(source); + } + + @Test + public void takeOne() { + Ix source = Ix.range(1, 10).takeUntil(new Pred() { + @Override + public boolean test(Integer v) { + return true; + } + }); + + IxTestHelper.assertValues(source, 1); + } + + @Test + public void takeAll() { + Ix source = Ix.range(1, 10).takeUntil(new Pred() { + @Override + public boolean test(Integer v) { + return false; + } + }); + + IxTestHelper.assertValues(source, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10); + } + + @Test + public void removeUnskipped() { + List list = IxTestHelper.range(1, 10); + Ix.from(list).takeUntil(new Pred() { + @Override + public boolean test(Integer v) { + return v == 5; + } + }).removeAll(); + + Assert.assertEquals(Arrays.asList(6, 7, 8, 9, 10), list); + } + +} diff --git a/src/test/java/ix/TakeWhileTest.java b/src/test/java/ix/TakeWhileTest.java new file mode 100644 index 0000000..3fb70c8 --- /dev/null +++ b/src/test/java/ix/TakeWhileTest.java @@ -0,0 +1,76 @@ +/* + * Copyright 2011-2016 David Karnok + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ix; + +import java.util.*; + +import org.junit.*; + +public class TakeWhileTest { + + @Test + public void normal() { + Ix source = Ix.range(1, 10).takeWhile(new Pred() { + @Override + public boolean test(Integer v) { + return v < 6; + } + }); + + IxTestHelper.assertValues(source, 1, 2, 3, 4, 5); + + IxTestHelper.assertNoRemove(source); + } + + @Test + public void takeAll() { + Ix source = Ix.range(1, 10).takeWhile(new Pred() { + @Override + public boolean test(Integer v) { + return true; + } + }); + + IxTestHelper.assertValues(source, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10); + } + + @Test + public void takeNone() { + Ix source = Ix.range(1, 10).takeWhile(new Pred() { + @Override + public boolean test(Integer v) { + return false; + } + }); + + IxTestHelper.assertValues(source); + } + + @Test + public void removeUnskipped() { + List list = IxTestHelper.range(1, 10); + Ix.from(list).takeWhile(new Pred() { + @Override + public boolean test(Integer v) { + return v < 6; + } + }).removeAll(); + + Assert.assertEquals(Arrays.asList(6, 7, 8, 9, 10), list); + } + +} From 904fea2122c1a8971f60a8e264c6440f5e91c460 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?D=C3=A1vid=20Karnok?= Date: Wed, 6 Jul 2016 21:17:11 +0200 Subject: [PATCH 14/66] Maven local publishing (experiment), added headers, +foreach() --- build.gradle | 13 +++++ src/main/java/ix/IdentityHelper.java | 16 ++++++ src/main/java/ix/Ix.java | 55 ++++++++++++++------- src/main/java/ix/NumberToLongHelper.java | 16 ++++++ src/test/java/ix/ForeachTest.java | 63 ++++++++++++++++++++++++ 5 files changed, 145 insertions(+), 18 deletions(-) create mode 100644 src/test/java/ix/ForeachTest.java diff --git a/build.gradle b/build.gradle index d2c11e2..64ac096 100644 --- a/build.gradle +++ b/build.gradle @@ -75,6 +75,19 @@ jar { } } +apply plugin: 'maven-publish' + +publishing { + publications { + mavenJava(MavenPublication) { + from components.java + artifact (sourcesJar) { + classifier = 'sources' + } + } + } +} + jmh { jmhVersion = '1.11.3' humanOutputFile = null diff --git a/src/main/java/ix/IdentityHelper.java b/src/main/java/ix/IdentityHelper.java index c5c9085..ff5e680 100644 --- a/src/main/java/ix/IdentityHelper.java +++ b/src/main/java/ix/IdentityHelper.java @@ -1,3 +1,19 @@ +/* + * Copyright 2011-2016 David Karnok + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package ix; import rx.functions.Func1; diff --git a/src/main/java/ix/Ix.java b/src/main/java/ix/Ix.java index 1924611..d579aea 100644 --- a/src/main/java/ix/Ix.java +++ b/src/main/java/ix/Ix.java @@ -83,18 +83,19 @@ public static Ix fromArrayRange(int start, int end, T... values) { return new IxFromArray(start, end, values); } - public static Ix concatArray(Iterable... sources) { + @SuppressWarnings("unchecked") + public static Ix concatArray(Iterable... sources) { int n = sources.length; if (n == 0) { return empty(); } if (n == 1) { - return from(sources[0]); + return from((Iterable)sources[0]); } - return new IxFlattenArrayIterable(sources); + return new IxFlattenArrayIterable((Iterable[])sources); } - public static Ix mergeArray(Iterable... sources) { + public static Ix mergeArray(Iterable... sources) { return concatArray(sources); // concat and merge are the same in the Iterable world } @@ -113,13 +114,9 @@ public static Ix merge(Iterable> sources) } //--------------------------------------------------------------------------------------- - // Instance operators + // Leaving the Iterable world //--------------------------------------------------------------------------------------- - - public final Ix map(Func1 mapper) { - return new IxMap(this, mapper); - } - + @SuppressWarnings("unchecked") public final T first() { if (this instanceof Callable) { @@ -176,6 +173,36 @@ public final T last(T defaultValue) { } } + public final void removeAll() { + Iterator it = iterator(); + while (it.hasNext()) { + it.next(); + it.remove(); + } + } + + public final void foreach(Action1 action) { + for (T t : this) { + action.call(t); + } + } + + public final void foreachWhile(Pred action) { + for (T t : this) { + if (!action.test(t)) { + break; + } + } + } + + //--------------------------------------------------------------------------------------- + // Instance operators + //--------------------------------------------------------------------------------------- + + public final Ix map(Func1 mapper) { + return new IxMap(this, mapper); + } + public final Ix filter(Pred predicate) { return new IxFilter(this, predicate); } @@ -270,14 +297,6 @@ public final Ix concatMap(Func1(this, mapper); } - public final void removeAll() { - Iterator it = iterator(); - while (it.hasNext()) { - it.next(); - it.remove(); - } - } - public final Ix skipWhile(Pred predicate) { return new IxSkipWhile(this, predicate); } diff --git a/src/main/java/ix/NumberToLongHelper.java b/src/main/java/ix/NumberToLongHelper.java index 7c2d09f..41ee68b 100644 --- a/src/main/java/ix/NumberToLongHelper.java +++ b/src/main/java/ix/NumberToLongHelper.java @@ -1,3 +1,19 @@ +/* + * Copyright 2011-2016 David Karnok + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package ix; import rx.functions.Func1; diff --git a/src/test/java/ix/ForeachTest.java b/src/test/java/ix/ForeachTest.java new file mode 100644 index 0000000..51943c2 --- /dev/null +++ b/src/test/java/ix/ForeachTest.java @@ -0,0 +1,63 @@ +/* + * Copyright 2011-2016 David Karnok + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ix; + +import java.util.*; + +import org.junit.*; + +import rx.functions.Action1; + +public class ForeachTest implements Action1, Pred { + + List list; + + @Before + public void before() { + list = new ArrayList(); + } + + @Override + public void call(Integer t) { + list.add(t); + } + + @Override + public boolean test(Integer t) { + list.add(t); + return list.size() < 5; + } + + @Test + public void normal() { + Ix source = Ix.range(1, 10); + + source.foreach(this); + + Assert.assertEquals(Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10), list); + } + + @Test + public void normalWhile() { + Ix source = Ix.range(1, 10); + + source.foreachWhile(this); + + Assert.assertEquals(Arrays.asList(1, 2, 3, 4, 5), list); + } + +} From eb0cda7ab95c888fc117596e7f9bee7e6f073ae1 Mon Sep 17 00:00:00 2001 From: akarnokd Date: Thu, 7 Jul 2016 14:24:12 +0200 Subject: [PATCH 15/66] Placeholders for the API methods --- src/main/java/ix/GroupedIx.java | 22 ++ src/main/java/ix/Ix.java | 620 ++++++++++++++++++++++++++---- src/main/java/ix/IxTransform.java | 54 +++ src/main/java/ix/Pred0.java | 28 ++ src/main/java/ix/Pred2.java | 33 ++ 5 files changed, 689 insertions(+), 68 deletions(-) create mode 100644 src/main/java/ix/GroupedIx.java create mode 100644 src/main/java/ix/IxTransform.java create mode 100644 src/main/java/ix/Pred0.java create mode 100644 src/main/java/ix/Pred2.java diff --git a/src/main/java/ix/GroupedIx.java b/src/main/java/ix/GroupedIx.java new file mode 100644 index 0000000..a4d405c --- /dev/null +++ b/src/main/java/ix/GroupedIx.java @@ -0,0 +1,22 @@ +package ix; + +/** + * An Iterable plus a key representing a group for the + * operator {@code groupBy()}. + * + * @param the key type + * @param the value type + */ +public abstract class GroupedIx extends Ix { + + protected final K key; + + public GroupedIx(K key) { + this.key = key; + } + + public final K key() { + return key; + } + +} diff --git a/src/main/java/ix/Ix.java b/src/main/java/ix/Ix.java index d579aea..63db5c2 100644 --- a/src/main/java/ix/Ix.java +++ b/src/main/java/ix/Ix.java @@ -19,6 +19,9 @@ import java.util.*; import java.util.concurrent.Callable; +import rx.Observer; +import rx.Subscriber; +import rx.exceptions.Exceptions; import rx.functions.*; /** @@ -113,91 +116,208 @@ public static Ix merge(Iterable> sources) IdentityHelper.>instance()); } + public static Ix defer(Func0> factory) { + // TODO implement + throw new UnsupportedOperationException(); + } + + public static Ix generate(Action1> nextSupplier) { + // TODO implement + throw new UnsupportedOperationException(); + } + + public static Ix generate(Func0 stateSupplier, Func2, S> nextSupplier) { + // TODO implement + throw new UnsupportedOperationException(); + } + + public static Ix generate(Func0 stateSupplier, Func2, S> nextSupplier, Action1 stateDisposer) { + // TODO implement + throw new UnsupportedOperationException(); + } + + public static Ix zip(Iterable[] sources, FuncN zipper) { + // TODO implement + throw new UnsupportedOperationException(); + } + + public static Ix zip(Iterable> sources, FuncN zipper) { + // TODO implement + throw new UnsupportedOperationException(); + } + + public static Ix zip( + Iterable it1, Iterable it2, + Func2 zipper) { + // TODO implement + throw new UnsupportedOperationException(); + } + + public static Ix zip( + Iterable it1, Iterable it2, + Iterable it3, + Func3 zipper) { + // TODO implement + throw new UnsupportedOperationException(); + } + + public static Ix zip( + Iterable it1, Iterable it2, + Iterable it3, Iterable it4, + Func4 zipper) { + // TODO implement + throw new UnsupportedOperationException(); + } + + public static Ix repeat(T value) { + // TODO implement + throw new UnsupportedOperationException(); + } + + public static Ix repeat(T value, long count) { + // TODO implement + throw new UnsupportedOperationException(); + } + + public static Ix repeat(T value, Pred0 stopPredicate) { + // TODO implement + throw new UnsupportedOperationException(); + } + + public static Ix forloop(T seed, Pred condition, Func1 next) { + // TODO implement + throw new UnsupportedOperationException(); + } + //--------------------------------------------------------------------------------------- - // Leaving the Iterable world + // Instance operators //--------------------------------------------------------------------------------------- - @SuppressWarnings("unchecked") - public final T first() { - if (this instanceof Callable) { - return checkedCall((Callable) this); - } - return iterator().next(); + public final R as(Func1, R> transformer) { + // TODO implement + throw new UnsupportedOperationException(); } - @SuppressWarnings("unchecked") - public final T first(T defaultValue) { - if (this instanceof Callable) { - return checkedCall((Callable) this); - } - Iterator it = iterator(); - if (it.hasNext()) { - return it.next(); - } - return defaultValue; + public final Ix compose(Func1, ? extends Iterable> transformer) { + // TODO implement + throw new UnsupportedOperationException(); } - @SuppressWarnings("unchecked") - public final T last() { - if (this instanceof Callable) { - return checkedCall((Callable) this); - } - Iterator it = iterator(); - if (!it.hasNext()) { - throw new NoSuchElementException(); - } - - for (;;) { - T t = it.next(); - if (!it.hasNext()) { - return t; - } - } + public final Ix any(Pred predicate) { + // TODO implement + throw new UnsupportedOperationException(); } + - @SuppressWarnings("unchecked") - public final T last(T defaultValue) { - if (this instanceof Callable) { - return checkedCall((Callable) this); - } - Iterator it = iterator(); - if (!it.hasNext()) { - return defaultValue; - } - - for (;;) { - T t = it.next(); - if (!it.hasNext()) { - return t; - } - } + public final Ix all(Pred predicate) { + // TODO implement + throw new UnsupportedOperationException(); } - public final void removeAll() { - Iterator it = iterator(); - while (it.hasNext()) { - it.next(); - it.remove(); - } + public final Ix hasElements() { + // TODO implement + throw new UnsupportedOperationException(); } - public final void foreach(Action1 action) { - for (T t : this) { - action.call(t); - } + public final Ix ignoreElements() { + // TODO implement + throw new UnsupportedOperationException(); } - public final void foreachWhile(Pred action) { - for (T t : this) { - if (!action.test(t)) { - break; - } - } + public final Ix max(Comparator comparator) { + // TODO implement + throw new UnsupportedOperationException(); } - //--------------------------------------------------------------------------------------- - // Instance operators - //--------------------------------------------------------------------------------------- + public final Ix max() { + // TODO implement + throw new UnsupportedOperationException(); + } + + public final Ix min(Comparator comparator) { + // TODO implement + throw new UnsupportedOperationException(); + } + + public final Ix min() { + // TODO implement + throw new UnsupportedOperationException(); + } + + public final Ix contains(Object o) { + // TODO implement + throw new UnsupportedOperationException(); + } + + public final Ix count() { + // TODO implement + throw new UnsupportedOperationException(); + } + + public final Ix countLong() { + // TODO implement + throw new UnsupportedOperationException(); + } + + public final Ix distinct() { + // TODO implement + throw new UnsupportedOperationException(); + } + + public final Ix distinct(Pred2 comparer) { + // TODO implement + throw new UnsupportedOperationException(); + } + + public final Ix distinct(Func1 keySelector) { + // TODO implement + throw new UnsupportedOperationException(); + } + + public final Ix distinctUntilChanged() { + // TODO implement + throw new UnsupportedOperationException(); + } + + public final Ix distinctUntilChanged(Pred2 comparer) { + // TODO implement + throw new UnsupportedOperationException(); + } + + public final Ix distinctUntilChanged(Func1 keySelector) { + // TODO implement + throw new UnsupportedOperationException(); + } + + public final Ix doOnNext(Action1 action) { + // TODO implement + throw new UnsupportedOperationException(); + } + + public final Ix doOnCompleted(Action1 action) { + // TODO implement + throw new UnsupportedOperationException(); + } + + public final Ix startWith(T... value) { + // TODO implement + throw new UnsupportedOperationException(); + } + + public final Ix endWith(T... value) { + // TODO implement + throw new UnsupportedOperationException(); + } + + public final Ix join() { + // TODO implement + throw new UnsupportedOperationException(); + } + + public final Ix join(CharSequence separator) { + // TODO implement + throw new UnsupportedOperationException(); + } public final Ix map(Func1 mapper) { return new IxMap(this, mapper); @@ -309,6 +429,370 @@ public final Ix takeUntil(Pred stopPredicate) { return new IxTakeUntil(this, stopPredicate); } + public final Ix> buffer(int size) { + // TODO implement + throw new UnsupportedOperationException(); + } + + public final Ix> buffer(int size, int skip) { + // TODO implement + throw new UnsupportedOperationException(); + } + + public final Ix> groupBy(Func1 keySelector) { + // TODO implement + throw new UnsupportedOperationException(); + } + + public final Ix> groupBy(Func1 keySelector, + Func1 valueSelector) { + // TODO implement + throw new UnsupportedOperationException(); + } + + public final Ix repeat() { + // TODO implement + throw new UnsupportedOperationException(); + } + + public final Ix repeat(long times) { + // TODO implement + throw new UnsupportedOperationException(); + } + + public final Ix repeat(Pred0 predicate) { + // TODO implement + throw new UnsupportedOperationException(); + } + + public final Ix repeat(long times, Pred0 predicate) { + // TODO implement + throw new UnsupportedOperationException(); + } + + public final Ix publish() { + // TODO implement + throw new UnsupportedOperationException(); + } + + public final Ix publish(Func1, ? extends Iterator> transform) { + // TODO implement + throw new UnsupportedOperationException(); + } + + public final Ix replay() { + // TODO implement + throw new UnsupportedOperationException(); + } + + public final Ix replay(int size) { + // TODO implement + throw new UnsupportedOperationException(); + } + + public final Ix replay(Func1, ? extends Iterator> transform) { + // TODO implement + throw new UnsupportedOperationException(); + } + + public final Ix replay(int size, Func1, ? extends Iterator> transform) { + // TODO implement + throw new UnsupportedOperationException(); + } + + public final Ix> toMap(Func1 keySelector) { + Func1 f = IdentityHelper.instance(); + return this.toMap(keySelector, f); + } + + public final Ix> toMap(Func1 keySelector, Func1 valueSelector) { + // TODO implement + throw new UnsupportedOperationException(); + } + + public final Ix>> toMultimap(Func1 keySelector) { + Func1 f = IdentityHelper.instance(); + return this.toMultimap(keySelector, f); + } + + public final Ix>> toMultimap(Func1 keySelector, Func1 valueSelector) { + // TODO implement + throw new UnsupportedOperationException(); + } + + public final Ix> window(int size) { + return window(size, size); + } + + public final Ix> window(int size, int skip) { + // TODO implement + throw new UnsupportedOperationException(); + } + + public final Ix concatWith(Iterator other) { + // TODO implement + throw new UnsupportedOperationException(); + } + + public final Ix mergeWith(Iterator other) { + return concatWith(other); + } + + public final Ix zipWith(Iterator other, Func2 zipper) { + // TODO implement + throw new UnsupportedOperationException(); + } + + public final Ix orderBy() { + // TODO implement + throw new UnsupportedOperationException(); + } + + public final Ix orderBy(Comparator comparator) { + // TODO implement + throw new UnsupportedOperationException(); + } + + public final > Ix orderBy(Func1 keySelector) { + // TODO implement + throw new UnsupportedOperationException(); + } + + public final Ix scan(Func2 scanner) { + // TODO implement + throw new UnsupportedOperationException(); + } + + public final Ix scan(Func0 initialFactory, Func2 scanner) { + // TODO implement + throw new UnsupportedOperationException(); + } + + public final Ix remove(Pred predicate) { + // TODO implement + throw new UnsupportedOperationException(); + } + + public final Ix transform(IxTransform transformer) { + // TODO implement + throw new UnsupportedOperationException(); + } + + public final Ix lift(Func1, ? extends Iterator> lifter) { + // TODO implement + throw new UnsupportedOperationException(); + } + + //--------------------------------------------------------------------------------------- + // Leaving the Iterable world + //--------------------------------------------------------------------------------------- + + @SuppressWarnings("unchecked") + public final T first() { + if (this instanceof Callable) { + return checkedCall((Callable) this); + } + return iterator().next(); + } + + @SuppressWarnings("unchecked") + public final T first(T defaultValue) { + if (this instanceof Callable) { + return checkedCall((Callable) this); + } + Iterator it = iterator(); + if (it.hasNext()) { + return it.next(); + } + return defaultValue; + } + + @SuppressWarnings("unchecked") + public final T last() { + if (this instanceof Callable) { + return checkedCall((Callable) this); + } + Iterator it = iterator(); + if (!it.hasNext()) { + throw new NoSuchElementException(); + } + + for (;;) { + T t = it.next(); + if (!it.hasNext()) { + return t; + } + } + } + + @SuppressWarnings("unchecked") + public final T last(T defaultValue) { + if (this instanceof Callable) { + return checkedCall((Callable) this); + } + Iterator it = iterator(); + if (!it.hasNext()) { + return defaultValue; + } + + for (;;) { + T t = it.next(); + if (!it.hasNext()) { + return t; + } + } + } + + public final void removeAll() { + Iterator it = iterator(); + while (it.hasNext()) { + it.next(); + it.remove(); + } + } + + public final void foreach(Action1 action) { + for (T t : this) { + action.call(t); + } + } + + public final void foreachWhile(Pred action) { + for (T t : this) { + if (!action.test(t)) { + break; + } + } + } + + public final > U into(U collection) { + for (T v : this) { + collection.add(v); + } + return collection; + } + + public final void print() { + print(", ", 80); + } + + public final void print(CharSequence separator, int charsPerLine) { + boolean first = true; + int len = 0; + + for (T v : this) { + + String s = String.valueOf(v); + + if (first) { + System.out.print(s); + len += s.length(); + first = false; + } else { + System.out.print(separator); + len += separator.length(); + if (len > charsPerLine) { + System.out.println();; + System.out.print(s); + len = s.length(); + } + } + + } + } + + public final void println() { + for (T v : this) { + System.out.println(v); + } + } + + public final void println(CharSequence prefix) { + for (T v : this) { + System.out.print(prefix); + System.out.println(v); + } + } + + /** + * Iterates over this instance, dropping all values it produces. + */ + public final void run() { + Iterator it = iterator(); + while (it.hasNext()) { + it.next(); + } + } + + public final void subscribe() { + run(); + } + + public final void subscribe(Action1 consumer) { + for (T v : this) { + consumer.call(v); + } + } + + public final void subscribe(Action1 consumer, Action1 onError) { + try { + for (T v : this) { + consumer.call(v); + } + } catch (Throwable ex) { + Exceptions.throwIfFatal(ex); + onError.call(ex); + } + } + + public final void subscribe(Action1 consumer, Action1 onError, Action0 onCompleted) { + try { + for (T v : this) { + consumer.call(v); + } + } catch (Throwable ex) { + Exceptions.throwIfFatal(ex); + onError.call(ex); + return; + } + onCompleted.call(); + } + + public final void subscribe(Observer observer) { + try { + for (T v : this) { + observer.onNext(v); + } + } catch (Throwable ex) { + Exceptions.throwIfFatal(ex); + observer.onError(ex); + return; + } + observer.onCompleted(); + } + + public final void subscribe(Subscriber subscriber) { + try { + for (T v : this) { + if (subscriber.isUnsubscribed()) { + return; + } + subscriber.onNext(v); + } + } catch (Throwable ex) { + Exceptions.throwIfFatal(ex); + if (subscriber.isUnsubscribed()) { + return; + } + subscriber.onError(ex); + return; + } + if (subscriber.isUnsubscribed()) { + return; + } + subscriber.onCompleted(); + } + // -------------------------------------------------------------------------------------------- // Helper methods // -------------------------------------------------------------------------------------------- diff --git a/src/main/java/ix/IxTransform.java b/src/main/java/ix/IxTransform.java new file mode 100644 index 0000000..797f4d9 --- /dev/null +++ b/src/main/java/ix/IxTransform.java @@ -0,0 +1,54 @@ +/* + * Copyright 2011-2016 David Karnok + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ix; + +import java.util.Iterator; + +import rx.functions.Action1; + +/** + * Functional interface that allows transforming an + * upstream Iterator for each downstream next() call. + *

+ * If you need per consumer-state, wrap the parent operator + * with compose(): + *


+ * Ix.range(1, 10).compose(o -> {
+ *     int[] counter = { 0 };
+ *     return o.transform((it, c) -> {
+ *         if (it.hasNext()) {
+ *             it.next();
+ *             c.call(++counter[0]);
+ *             return NEXT;
+ *         }
+ *         return STOP;
+ *     });
+ * });
+ * 
+ * @param the source value type + * @param the result value type + */ +public interface IxTransform { + + int STOP = 0; + + int NEXT = 1; + + int LAST = 2; + + int moveNext(Iterator it, Action1 consumer); +} diff --git a/src/main/java/ix/Pred0.java b/src/main/java/ix/Pred0.java new file mode 100644 index 0000000..b23a207 --- /dev/null +++ b/src/main/java/ix/Pred0.java @@ -0,0 +1,28 @@ +/* + * Copyright 2011-2016 David Karnok + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ix; + +/** + * A supplier of a single boolean value. + */ +public interface Pred0 { + /** + * Returns a boolean value. + * @return a boolean value + */ + boolean getAsBoolean(); +} diff --git a/src/main/java/ix/Pred2.java b/src/main/java/ix/Pred2.java new file mode 100644 index 0000000..e80f56f --- /dev/null +++ b/src/main/java/ix/Pred2.java @@ -0,0 +1,33 @@ +/* + * Copyright 2011-2016 David Karnok + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ix; + +/** + * A predicate functional interface to test a value and return a primitive + * boolean. + * @param the first value to test + * @param the second value to test + */ +public interface Pred2 { + /** + * Test the given value. + * @param t the first value to test + * @param u the second value to test + * @return true if the value passes the test + */ + boolean test(T t, U u); +} From 77467bc1074dce44b597c3ddac9927a90d8e4766 Mon Sep 17 00:00:00 2001 From: akarnokd Date: Thu, 7 Jul 2016 14:33:10 +0200 Subject: [PATCH 16/66] Added some terminal methods --- src/main/java/ix/Ix.java | 53 ++++++++++++++++++++++++++++++++++++++-- 1 file changed, 51 insertions(+), 2 deletions(-) diff --git a/src/main/java/ix/Ix.java b/src/main/java/ix/Ix.java index 63db5c2..dc43cc2 100644 --- a/src/main/java/ix/Ix.java +++ b/src/main/java/ix/Ix.java @@ -26,7 +26,9 @@ /** * Base class and entry point for fluent iterables. + * * @param the value type + * @since 1.0 */ public abstract class Ix implements Iterable { @@ -572,7 +574,7 @@ public final Ix remove(Pred predicate) { // TODO implement throw new UnsupportedOperationException(); } - + public final Ix transform(IxTransform transformer) { // TODO implement throw new UnsupportedOperationException(); @@ -792,7 +794,54 @@ public final void subscribe(Subscriber subscriber) { } subscriber.onCompleted(); } - + + /** + * Consumes this Iterable and removes all elements for + * which the predicate returns false; in other words, + * retain those elements of a mutable source that match + * the predicate. + * @param predicate the predicate called with the current + * element and should return true for elements to keep, false + * for elements to remove. + * @throws UnsupportedOperationException if the this Iterable + * doesn't allow removing elements. + * @see #removeAll(Pred) + * @since 1.0 + */ + public final void retainAll(Pred predicate) { + Iterator it = iterator(); + while (it.hasNext()) { + T v = it.next(); + if (!predicate.test(v)) { + it.remove(); + } + } + } + + /** + * Consumes this Iterable and removes all elements for + * which the predicate returns true; in other words, + * remove those elements of a mutable source that match + * the predicate. + * @param predicate the predicate called with the current + * element and should return true for elements to remove, false + * for elements to keep. + * @throws UnsupportedOperationException if the this Iterable + * doesn't allow removing elements. + * @see #retainAll(Pred) + * @see #removeAll() + * @since 1.0 + */ + public final void removeAll(Pred predicate) { + Iterator it = iterator(); + while (it.hasNext()) { + T v = it.next(); + if (predicate.test(v)) { + it.remove(); + } + } + } + // -------------------------------------------------------------------------------------------- // Helper methods // -------------------------------------------------------------------------------------------- From 339930978801e0c46a1ddd6d44e4cb5509714c6a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?D=C3=A1vid=20Karnok?= Date: Tue, 12 Jul 2016 23:58:21 +0200 Subject: [PATCH 17/66] +defer, +generate, +zip --- src/main/java/ix/Ix.java | 30 ++-- src/main/java/ix/IxBaseIterator.java | 3 +- src/main/java/ix/IxDefer.java | 20 +++ src/main/java/ix/IxEmptyAction.java | 34 +++++ src/main/java/ix/IxFlattenArrayIterable.java | 2 +- src/main/java/ix/IxGenerate.java | 99 +++++++++++++ src/main/java/ix/IxGenerateStateless.java | 80 +++++++++++ src/main/java/ix/IxSourceIterator.java | 2 +- src/main/java/ix/IxZip2.java | 74 ++++++++++ src/main/java/ix/IxZip3.java | 87 +++++++++++ src/main/java/ix/IxZip4.java | 100 +++++++++++++ src/main/java/ix/IxZipArray.java | 84 +++++++++++ src/main/java/ix/IxZipIterable.java | 56 ++++++++ src/test/java/ix/DeferTest.java | 39 +++++ src/test/java/ix/GenerateStatelessTest.java | 103 +++++++++++++ src/test/java/ix/GenerateTest.java | 143 +++++++++++++++++++ src/test/java/ix/Zip2Test.java | 68 +++++++++ src/test/java/ix/Zip3Test.java | 77 ++++++++++ src/test/java/ix/Zip4Test.java | 86 +++++++++++ src/test/java/ix/ZipArrayTest.java | 76 ++++++++++ src/test/java/ix/ZipIterableTest.java | 99 +++++++++++++ 21 files changed, 1338 insertions(+), 24 deletions(-) create mode 100644 src/main/java/ix/IxDefer.java create mode 100644 src/main/java/ix/IxEmptyAction.java create mode 100644 src/main/java/ix/IxGenerate.java create mode 100644 src/main/java/ix/IxGenerateStateless.java create mode 100644 src/main/java/ix/IxZip2.java create mode 100644 src/main/java/ix/IxZip3.java create mode 100644 src/main/java/ix/IxZip4.java create mode 100644 src/main/java/ix/IxZipArray.java create mode 100644 src/main/java/ix/IxZipIterable.java create mode 100644 src/test/java/ix/DeferTest.java create mode 100644 src/test/java/ix/GenerateStatelessTest.java create mode 100644 src/test/java/ix/GenerateTest.java create mode 100644 src/test/java/ix/Zip2Test.java create mode 100644 src/test/java/ix/Zip3Test.java create mode 100644 src/test/java/ix/Zip4Test.java create mode 100644 src/test/java/ix/ZipArrayTest.java create mode 100644 src/test/java/ix/ZipIterableTest.java diff --git a/src/main/java/ix/Ix.java b/src/main/java/ix/Ix.java index dc43cc2..8ac4fd8 100644 --- a/src/main/java/ix/Ix.java +++ b/src/main/java/ix/Ix.java @@ -40,7 +40,6 @@ public static Ix empty() { return IxEmpty.instance(); } - public static Ix from(Iterable source) { if (source instanceof Ix) { return (Ix)source; @@ -119,56 +118,47 @@ public static Ix merge(Iterable> sources) } public static Ix defer(Func0> factory) { - // TODO implement - throw new UnsupportedOperationException(); + return new IxDefer(factory); } public static Ix generate(Action1> nextSupplier) { - // TODO implement - throw new UnsupportedOperationException(); + return new IxGenerateStateless(nextSupplier); } public static Ix generate(Func0 stateSupplier, Func2, S> nextSupplier) { - // TODO implement - throw new UnsupportedOperationException(); + return generate(stateSupplier, nextSupplier, IxEmptyAction.instance1()); } public static Ix generate(Func0 stateSupplier, Func2, S> nextSupplier, Action1 stateDisposer) { - // TODO implement - throw new UnsupportedOperationException(); + return new IxGenerate(stateSupplier, nextSupplier, stateDisposer); } public static Ix zip(Iterable[] sources, FuncN zipper) { - // TODO implement - throw new UnsupportedOperationException(); + return new IxZipArray(sources, zipper); } public static Ix zip(Iterable> sources, FuncN zipper) { - // TODO implement - throw new UnsupportedOperationException(); + return new IxZipIterable(sources, zipper); } public static Ix zip( Iterable it1, Iterable it2, Func2 zipper) { - // TODO implement - throw new UnsupportedOperationException(); + return new IxZip2(it1, it2, zipper); } public static Ix zip( Iterable it1, Iterable it2, Iterable it3, Func3 zipper) { - // TODO implement - throw new UnsupportedOperationException(); + return new IxZip3(it1, it2, it3, zipper); } public static Ix zip( Iterable it1, Iterable it2, - Iterable it3, Iterable it4, + Iterable it3, Iterable it4, Func4 zipper) { - // TODO implement - throw new UnsupportedOperationException(); + return new IxZip4(it1, it2, it3, it4, zipper); } public static Ix repeat(T value) { diff --git a/src/main/java/ix/IxBaseIterator.java b/src/main/java/ix/IxBaseIterator.java index 0fe02a3..b17930c 100644 --- a/src/main/java/ix/IxBaseIterator.java +++ b/src/main/java/ix/IxBaseIterator.java @@ -22,10 +22,9 @@ * A base iterator that manages * the state between hasNext() and the next() calls; plus defines * the remove() to throw UnsupportedOperationException. - * @param the source value type * @param the result value type */ -public abstract class IxBaseIterator implements Iterator { +public abstract class IxBaseIterator implements Iterator { /** Inidicates a value is available for consumption. */ protected boolean hasValue; diff --git a/src/main/java/ix/IxDefer.java b/src/main/java/ix/IxDefer.java new file mode 100644 index 0000000..c9ba8fc --- /dev/null +++ b/src/main/java/ix/IxDefer.java @@ -0,0 +1,20 @@ +package ix; + +import java.util.Iterator; + +import rx.functions.Func0; + +final class IxDefer extends Ix { + + final Func0> factory; + + public IxDefer(Func0> factory) { + this.factory = factory; + } + + @SuppressWarnings("unchecked") + @Override + public Iterator iterator() { + return (Iterator)factory.call().iterator(); + } +} diff --git a/src/main/java/ix/IxEmptyAction.java b/src/main/java/ix/IxEmptyAction.java new file mode 100644 index 0000000..1dfd0c4 --- /dev/null +++ b/src/main/java/ix/IxEmptyAction.java @@ -0,0 +1,34 @@ +/* + * Copyright 2011-2016 David Karnok + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ix; + +import rx.functions.*; + +enum IxEmptyAction implements Action1 { + INSTANCE; + + @SuppressWarnings("unchecked") + public static Action1 instance1() { + return (Action1)INSTANCE; + } + + @Override + public void call(Object t) { + // deliberately no op + } + +} diff --git a/src/main/java/ix/IxFlattenArrayIterable.java b/src/main/java/ix/IxFlattenArrayIterable.java index 35d127e..aa89bfa 100644 --- a/src/main/java/ix/IxFlattenArrayIterable.java +++ b/src/main/java/ix/IxFlattenArrayIterable.java @@ -32,7 +32,7 @@ public Iterator iterator() { return new FlattenIterator(sources); } - static final class FlattenIterator extends IxBaseIterator { + static final class FlattenIterator extends IxBaseIterator { final Iterable[] sources; diff --git a/src/main/java/ix/IxGenerate.java b/src/main/java/ix/IxGenerate.java new file mode 100644 index 0000000..e324c1e --- /dev/null +++ b/src/main/java/ix/IxGenerate.java @@ -0,0 +1,99 @@ +/* + * Copyright 2011-2016 David Karnok + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ix; + +import java.util.Iterator; + +import rx.Observer; +import rx.functions.*; + +final class IxGenerate extends Ix { + + final Func0 stateFactory; + + final Func2, S> generator; + + final Action1 stateDisposer; + + public IxGenerate(Func0 stateFactory, Func2, S> generator, Action1 stateDisposer) { + this.stateFactory = stateFactory; + this.generator = generator; + this.stateDisposer = stateDisposer; + } + + @Override + public Iterator iterator() { + return new GenerateIterator(stateFactory.call(), generator, stateDisposer); + } + + static final class GenerateIterator extends IxBaseIterator + implements Observer { + + final Func2, S> generator; + + final Action1 stateDisposer; + + S state; + + public GenerateIterator(S state, Func2, S> generator, Action1 stateDisposer) { + this.state = state; + this.generator = generator; + this.stateDisposer = stateDisposer; + } + + @Override + protected boolean moveNext() { + + state = generator.call(state, this); + + boolean hv = hasValue; + boolean d = done; + if (!hv && !d) { + stateDisposer.call(state); + throw new IllegalStateException("The generator didn't call any of the onXXX methods!"); + } + if (d) { + stateDisposer.call(state); + } + return hv; + } + + @Override + public void onNext(T t) { + value = t; + hasValue = true; + } + + @Override + public void onError(Throwable e) { + stateDisposer.call(state); + + if (e instanceof RuntimeException) { + throw (RuntimeException)e; + } + if (e instanceof Error) { + throw (Error)e; + } + throw new RuntimeException(e); + } + + @Override + public void onCompleted() { + done = true; + } + } +} diff --git a/src/main/java/ix/IxGenerateStateless.java b/src/main/java/ix/IxGenerateStateless.java new file mode 100644 index 0000000..418994f --- /dev/null +++ b/src/main/java/ix/IxGenerateStateless.java @@ -0,0 +1,80 @@ +/* + * Copyright 2011-2016 David Karnok + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ix; + +import java.util.Iterator; + +import rx.Observer; +import rx.functions.Action1; + +final class IxGenerateStateless extends Ix { + + final Action1> generator; + + public IxGenerateStateless(Action1> generator) { + this.generator = generator; + } + + @Override + public Iterator iterator() { + return new GenerateIterator(generator); + } + + static final class GenerateIterator extends IxBaseIterator + implements Observer { + + final Action1> generator; + + public GenerateIterator(Action1> generator) { + this.generator = generator; + } + + @Override + protected boolean moveNext() { + + generator.call(this); + + boolean hv = hasValue; + if (!hv && !done) { + throw new IllegalStateException("The generator didn't call any of the onXXX methods!"); + } + return hv; + } + + @Override + public void onNext(T t) { + value = t; + hasValue = true; + } + + @Override + public void onError(Throwable e) { + if (e instanceof RuntimeException) { + throw (RuntimeException)e; + } + if (e instanceof Error) { + throw (Error)e; + } + throw new RuntimeException(e); + } + + @Override + public void onCompleted() { + done = true; + } + } +} diff --git a/src/main/java/ix/IxSourceIterator.java b/src/main/java/ix/IxSourceIterator.java index 289c9c9..e7b87c6 100644 --- a/src/main/java/ix/IxSourceIterator.java +++ b/src/main/java/ix/IxSourceIterator.java @@ -25,7 +25,7 @@ * @param the source value type * @param the result value type */ -public abstract class IxSourceIterator extends IxBaseIterator { +public abstract class IxSourceIterator extends IxBaseIterator { /** The upstream's iterator. */ protected final Iterator it; diff --git a/src/main/java/ix/IxZip2.java b/src/main/java/ix/IxZip2.java new file mode 100644 index 0000000..abd0629 --- /dev/null +++ b/src/main/java/ix/IxZip2.java @@ -0,0 +1,74 @@ +/* + * Copyright 2011-2016 David Karnok + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ix; + +import java.util.Iterator; + +import rx.functions.Func2; + +final class IxZip2 extends Ix { + + final Iterable source1; + + final Iterable source2; + + final Func2 zipper; + + public IxZip2(Iterable source1, Iterable source2, Func2 zipper) { + this.source1 = source1; + this.source2 = source2; + this.zipper = zipper; + } + + @Override + public Iterator iterator() { + return new Zip2Iterator(source1.iterator(), source2.iterator(), zipper); + } + + static final class Zip2Iterator extends IxBaseIterator { + + final Iterator source1; + + final Iterator source2; + + final Func2 zipper; + + public Zip2Iterator(Iterator source1, Iterator source2, Func2 zipper) { + this.source1 = source1; + this.source2 = source2; + this.zipper = zipper; + } + + @Override + protected boolean moveNext() { + if (!source1.hasNext()) { + done = true; + return false; + } + + if (!source2.hasNext()) { + done = true; + return false; + } + + value = zipper.call(source1.next(), source2.next()); + hasValue = true; + return true; + } + + } +} diff --git a/src/main/java/ix/IxZip3.java b/src/main/java/ix/IxZip3.java new file mode 100644 index 0000000..334fb7a --- /dev/null +++ b/src/main/java/ix/IxZip3.java @@ -0,0 +1,87 @@ +/* + * Copyright 2011-2016 David Karnok + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ix; + +import java.util.Iterator; + +import rx.functions.Func3; + +final class IxZip3 extends Ix { + final Iterable source1; + + final Iterable source2; + + final Iterable source3; + + final Func3 zipper; + + public IxZip3(Iterable source1, Iterable source2, Iterable source3, + Func3 zipper) { + this.source1 = source1; + this.source2 = source2; + this.source3 = source3; + this.zipper = zipper; + } + + @Override + public Iterator iterator() { + return new Zip3Iterator(source1.iterator(), source2.iterator(), + source3.iterator(), zipper); + } + + static final class Zip3Iterator extends IxBaseIterator { + + final Iterator source1; + + final Iterator source2; + + final Iterator source3; + + final Func3 zipper; + + public Zip3Iterator(Iterator source1, Iterator source2, Iterator source3, + Func3 zipper) { + this.source1 = source1; + this.source2 = source2; + this.source3 = source3; + this.zipper = zipper; + } + + @Override + protected boolean moveNext() { + if (!source1.hasNext()) { + done = true; + return false; + } + + if (!source2.hasNext()) { + done = true; + return false; + } + + if (!source3.hasNext()) { + done = true; + return false; + } + + value = zipper.call(source1.next(), source2.next(), source3.next()); + hasValue = true; + return true; + } + + } +} diff --git a/src/main/java/ix/IxZip4.java b/src/main/java/ix/IxZip4.java new file mode 100644 index 0000000..d243217 --- /dev/null +++ b/src/main/java/ix/IxZip4.java @@ -0,0 +1,100 @@ +/* + * Copyright 2011-2016 David Karnok + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ix; + +import java.util.Iterator; + +import rx.functions.Func4; + +final class IxZip4 extends Ix { + final Iterable source1; + + final Iterable source2; + + final Iterable source3; + + final Iterable source4; + + final Func4 zipper; + + public IxZip4(Iterable source1, Iterable source2, + Iterable source3, Iterable source4, + Func4 zipper) { + this.source1 = source1; + this.source2 = source2; + this.source3 = source3; + this.source4 = source4; + this.zipper = zipper; + } + + @Override + public Iterator iterator() { + return new Zip4Iterator(source1.iterator(), source2.iterator(), + source3.iterator(), source4.iterator(), zipper); + } + + static final class Zip4Iterator extends IxBaseIterator { + + final Iterator source1; + + final Iterator source2; + + final Iterator source3; + + final Iterator source4; + + final Func4 zipper; + + public Zip4Iterator(Iterator source1, Iterator source2, Iterator source3, + Iterator source4, + Func4 zipper) { + this.source1 = source1; + this.source2 = source2; + this.source3 = source3; + this.source4 = source4; + this.zipper = zipper; + } + + @Override + protected boolean moveNext() { + if (!source1.hasNext()) { + done = true; + return false; + } + + if (!source2.hasNext()) { + done = true; + return false; + } + + if (!source3.hasNext()) { + done = true; + return false; + } + + if (!source4.hasNext()) { + done = true; + return false; + } + + value = zipper.call(source1.next(), source2.next(), source3.next(), source4.next()); + hasValue = true; + return true; + } + + } +} diff --git a/src/main/java/ix/IxZipArray.java b/src/main/java/ix/IxZipArray.java new file mode 100644 index 0000000..d40bcef --- /dev/null +++ b/src/main/java/ix/IxZipArray.java @@ -0,0 +1,84 @@ +/* + * Copyright 2011-2016 David Karnok + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ix; + +import java.util.Iterator; + +import rx.functions.FuncN; + +final class IxZipArray extends Ix { + + final Iterable[] sources; + + final FuncN zipper; + + public IxZipArray(Iterable[] sources, FuncN zipper) { + this.sources = sources; + this.zipper = zipper; + } + + @SuppressWarnings("unchecked") + @Override + public Iterator iterator() { + + Iterable[] src = sources; + + Iterator[] itors = new Iterator[src.length]; + for (int i = 0; i < itors.length; i++) { + itors[i] = (Iterator)src[i].iterator(); + } + + return new ZipArrayIterator(itors, zipper); + } + + static final class ZipArrayIterator extends IxBaseIterator { + + final Iterator[] sources; + + final FuncN zipper; + + public ZipArrayIterator(Iterator[] sources, FuncN zipper) { + this.sources = sources; + this.zipper = zipper; + } + + @SuppressWarnings("unchecked") + @Override + protected boolean moveNext() { + Iterator[] itors = sources; + int n = itors.length; + T[] a = (T[])new Object[n]; + + for (int i = 0; i < n; i++) { + Iterator it = itors[i]; + if (it.hasNext()) { + a[i] = it.next(); + } else { + done = true; + return false; + } + } + + value = zipper.call(a); + hasValue = true; + + return true; + } + + } + +} diff --git a/src/main/java/ix/IxZipIterable.java b/src/main/java/ix/IxZipIterable.java new file mode 100644 index 0000000..f242df0 --- /dev/null +++ b/src/main/java/ix/IxZipIterable.java @@ -0,0 +1,56 @@ +/* + * Copyright 2011-2016 David Karnok + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ix; + +import java.util.*; + +import ix.IxZipArray.ZipArrayIterator; +import rx.functions.FuncN; + +final class IxZipIterable extends Ix { + + final Iterable> sources; + + final FuncN zipper; + + public IxZipIterable(Iterable> sources, FuncN zipper) { + this.sources = sources; + this.zipper = zipper; + } + + @SuppressWarnings("unchecked") + @Override + public Iterator iterator() { + + Iterable[] src = new Iterable[8]; + int n = 0; + + for (Iterable it : sources) { + if (n == src.length) { + src = Arrays.copyOf(src, n + (n >> 1)); + } + src[n++] = it; + } + + Iterator[] itors = new Iterator[n]; + for (int i = 0; i < n; i++) { + itors[i] = (Iterator)src[i].iterator(); + } + + return new ZipArrayIterator(itors, zipper); + } +} diff --git a/src/test/java/ix/DeferTest.java b/src/test/java/ix/DeferTest.java new file mode 100644 index 0000000..8592d4e --- /dev/null +++ b/src/test/java/ix/DeferTest.java @@ -0,0 +1,39 @@ +/* + * Copyright 2011-2016 David Karnok + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ix; + +import org.junit.Test; + +import rx.functions.Func0; + +public class DeferTest { + + @Test + public void normal() { + Ix source = Ix.defer(new Func0>() { + int count; + @Override + public Iterable call() { + return Ix.range(++count, 2); + } + }); + + IxTestHelper.assertValues(source, 1, 2); + IxTestHelper.assertValues(source, 2, 3); + IxTestHelper.assertValues(source, 3, 4); + } +} diff --git a/src/test/java/ix/GenerateStatelessTest.java b/src/test/java/ix/GenerateStatelessTest.java new file mode 100644 index 0000000..6080d0c --- /dev/null +++ b/src/test/java/ix/GenerateStatelessTest.java @@ -0,0 +1,103 @@ +/* + * Copyright 2011-2016 David Karnok + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ix; + +import java.io.IOException; + +import org.junit.Test; + +import rx.Observer; +import rx.functions.Action1; + +public class GenerateStatelessTest { + + @Test + public void normal() { + Ix source = Ix.generate(new Action1>() { + int count; + @Override + public void call(Observer t) { + t.onNext(++count); + if (count == 10) { + t.onCompleted(); + } + } + }); + + IxTestHelper.assertValues(source, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10); + } + + @Test + public void empty() { + Ix source = Ix.generate(new Action1>() { + @Override + public void call(Observer t) { + t.onCompleted(); + } + }); + + IxTestHelper.assertValues(source); + } + + @Test(expected = IllegalStateException.class) + public void never() { + Ix source = Ix.generate(new Action1>() { + @Override + public void call(Observer t) { + } + }); + + IxTestHelper.assertValues(source); + } + + @Test(expected = IllegalArgumentException.class) + public void runtimeError() { + Ix source = Ix.generate(new Action1>() { + @Override + public void call(Observer t) { + t.onError(new IllegalArgumentException()); + } + }); + + IxTestHelper.assertValues(source); + } + + @Test(expected = InternalError.class) + public void error() { + Ix source = Ix.generate(new Action1>() { + @Override + public void call(Observer t) { + t.onError(new InternalError()); + } + }); + + IxTestHelper.assertValues(source); + } + + @Test(expected = RuntimeException.class) + public void exceptionError() { + Ix source = Ix.generate(new Action1>() { + @Override + public void call(Observer t) { + t.onError(new IOException()); + } + }); + + IxTestHelper.assertValues(source); + } + +} diff --git a/src/test/java/ix/GenerateTest.java b/src/test/java/ix/GenerateTest.java new file mode 100644 index 0000000..09e8ab4 --- /dev/null +++ b/src/test/java/ix/GenerateTest.java @@ -0,0 +1,143 @@ +/* + * Copyright 2011-2016 David Karnok + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ix; + +import java.io.IOException; +import java.util.concurrent.atomic.AtomicInteger; + +import org.junit.*; + +import rx.Observer; +import rx.functions.*; + +public class GenerateTest { + + Func0 stateFactory = new Func0() { + @Override + public Integer call() { + return 0; + } + }; + + @Test + public void normal() { + Ix source = Ix.generate(stateFactory, new Func2, Integer>() { + @Override + public Integer call(Integer s, Observer t) { + int i = ++s; + t.onNext(i); + if (i == 10) { + t.onCompleted(); + } + return i; + } + }); + + IxTestHelper.assertValues(source, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10); + } + + @Test + public void normalState() { + final AtomicInteger value = new AtomicInteger(); + + Ix source = Ix.generate(stateFactory, new Func2, Integer>() { + @Override + public Integer call(Integer s, Observer t) { + int i = ++s; + t.onNext(i); + if (i == 10) { + t.onCompleted(); + } + return i; + } + }, new Action1() { + @Override + public void call(Integer t) { + value.set(t); + } + }); + + IxTestHelper.assertValues(source, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10); + + Assert.assertEquals(10, value.get()); + } + + @Test + public void empty() { + Ix source = Ix.generate(stateFactory, new Func2, Integer>() { + @Override + public Integer call(Integer s, Observer t) { + t.onCompleted(); + return s; + } + }); + + IxTestHelper.assertValues(source); + } + + @Test(expected = IllegalStateException.class) + public void never() { + Ix source = Ix.generate(stateFactory, new Func2, Integer>() { + @Override + public Integer call(Integer s, Observer t) { + return s; + } + }); + + IxTestHelper.assertValues(source); + } + + @Test(expected = IllegalArgumentException.class) + public void runtimeError() { + Ix source = Ix.generate(stateFactory, new Func2, Integer>() { + @Override + public Integer call(Integer s, Observer t) { + t.onError(new IllegalArgumentException()); + return s; + } + }); + + IxTestHelper.assertValues(source); + } + + @Test(expected = InternalError.class) + public void error() { + Ix source = Ix.generate(stateFactory, new Func2, Integer>() { + @Override + public Integer call(Integer s, Observer t) { + t.onError(new InternalError()); + return s; + } + }); + + IxTestHelper.assertValues(source); + } + + @Test(expected = RuntimeException.class) + public void exceptionError() { + Ix source = Ix.generate(stateFactory, new Func2, Integer>() { + @Override + public Integer call(Integer s, Observer t) { + t.onError(new IOException()); + return s; + } + }); + + IxTestHelper.assertValues(source); + } + +} diff --git a/src/test/java/ix/Zip2Test.java b/src/test/java/ix/Zip2Test.java new file mode 100644 index 0000000..c8ab782 --- /dev/null +++ b/src/test/java/ix/Zip2Test.java @@ -0,0 +1,68 @@ +/* + * Copyright 2011-2016 David Karnok + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ix; + +import org.junit.Test; + +import rx.functions.*; + +public class Zip2Test { + + Func2 sum = new Func2() { + @Override + public Integer call(Integer a, Integer b) { + return a + b; + } + }; + + @Test + public void normal() { + + Ix source = Ix.zip( + Ix.range(1, 2), Ix.range(10, 2), sum); + + IxTestHelper.assertValues(source, 11, 13); + } + + @Test + public void firstShorter() { + + Ix source = Ix.zip( + Ix.range(1, 1), Ix.range(10, 2), sum); + + IxTestHelper.assertValues(source, 11); + } + + @Test + public void secondShorter() { + + Ix source = Ix.zip( + Ix.range(1, 3), Ix.range(10, 2), sum); + + IxTestHelper.assertValues(source, 11, 13); + } + + @Test + public void bothEmpty() { + + Ix source = Ix.zip( + Ix.empty(), Ix.empty(), sum); + + IxTestHelper.assertValues(source); + } + +} diff --git a/src/test/java/ix/Zip3Test.java b/src/test/java/ix/Zip3Test.java new file mode 100644 index 0000000..96e4fca --- /dev/null +++ b/src/test/java/ix/Zip3Test.java @@ -0,0 +1,77 @@ +/* + * Copyright 2011-2016 David Karnok + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ix; + +import org.junit.Test; + +import rx.functions.*; + +public class Zip3Test { + + Func3 sum = new Func3() { + @Override + public Integer call(Integer a, Integer b, Integer c) { + return a + b + c; + } + }; + + @Test + public void normal() { + + Ix source = Ix.zip( + Ix.range(1, 2), Ix.range(10, 2), Ix.range(100, 2), sum); + + IxTestHelper.assertValues(source, 111, 114); + } + + @Test + public void firstShorter() { + + Ix source = Ix.zip( + Ix.range(1, 1), Ix.range(10, 2), Ix.range(100, 2), sum); + + IxTestHelper.assertValues(source, 111); + } + + @Test + public void secondShorter() { + + Ix source = Ix.zip( + Ix.range(1, 3), Ix.range(10, 2), Ix.range(100, 2), sum); + + IxTestHelper.assertValues(source, 111, 114); + } + + @Test + public void thirdShorter() { + + Ix source = Ix.zip( + Ix.range(1, 3), Ix.range(10, 3), Ix.range(100, 2), sum); + + IxTestHelper.assertValues(source, 111, 114); + } + + @Test + public void allEmpty() { + + Ix source = Ix.zip( + Ix.empty(), Ix.empty(), Ix.empty(), sum); + + IxTestHelper.assertValues(source); + } + +} diff --git a/src/test/java/ix/Zip4Test.java b/src/test/java/ix/Zip4Test.java new file mode 100644 index 0000000..460fc8e --- /dev/null +++ b/src/test/java/ix/Zip4Test.java @@ -0,0 +1,86 @@ +/* + * Copyright 2011-2016 David Karnok + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ix; + +import org.junit.Test; + +import rx.functions.*; + +public class Zip4Test { + + Func4 sum = new Func4() { + @Override + public Integer call(Integer a, Integer b, Integer c, Integer d) { + return a + b + c + d; + } + }; + + @Test + public void normal() { + + Ix source = Ix.zip( + Ix.range(1, 2), Ix.range(10, 2), Ix.range(100, 2), Ix.range(1000, 2), sum); + + IxTestHelper.assertValues(source, 1111, 1115); + } + + @Test + public void firstShorter() { + + Ix source = Ix.zip( + Ix.range(1, 1), Ix.range(10, 2), Ix.range(100, 2), Ix.range(1000, 2), sum); + + IxTestHelper.assertValues(source, 1111); + } + + @Test + public void secondShorter() { + + Ix source = Ix.zip( + Ix.range(1, 3), Ix.range(10, 2), Ix.range(100, 3), Ix.range(1000, 3), sum); + + IxTestHelper.assertValues(source, 1111, 1115); + } + + @Test + public void thirdShorter() { + + Ix source = Ix.zip( + Ix.range(1, 3), Ix.range(10, 3), Ix.range(100, 2), Ix.range(1000, 3), sum); + + IxTestHelper.assertValues(source, 1111, 1115); + } + + @Test + public void fourthShorter() { + + Ix source = Ix.zip( + Ix.range(1, 3), Ix.range(10, 3), Ix.range(100, 3), Ix.range(1000, 2), sum); + + IxTestHelper.assertValues(source, 1111, 1115); + } + + @Test + public void allEmpty() { + + Ix source = Ix.zip( + Ix.empty(), Ix.empty(), Ix.empty(), Ix.empty(), sum); + + IxTestHelper.assertValues(source); + } + +} diff --git a/src/test/java/ix/ZipArrayTest.java b/src/test/java/ix/ZipArrayTest.java new file mode 100644 index 0000000..f517c10 --- /dev/null +++ b/src/test/java/ix/ZipArrayTest.java @@ -0,0 +1,76 @@ +/* + * Copyright 2011-2016 David Karnok + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ix; + +import org.junit.Test; + +import rx.functions.FuncN; + +public class ZipArrayTest { + + FuncN zipper = new FuncN() { + @Override + public Integer call(Object... a) { + return (Integer)a[0] + (Integer)a[1]; + } + }; + + @SuppressWarnings("unchecked") + @Test + public void normal() { + + Ix source = Ix.zip(new Iterable[] { + Ix.range(1, 2), Ix.range(10, 2) }, + zipper); + + IxTestHelper.assertValues(source, 11, 13); + } + + @SuppressWarnings("unchecked") + @Test + public void firstShorter() { + + Ix source = Ix.zip(new Iterable[] { + Ix.range(1, 1), Ix.range(10, 2) }, + zipper); + + IxTestHelper.assertValues(source, 11); + } + + @SuppressWarnings("unchecked") + @Test + public void secondShorter() { + + Ix source = Ix.zip(new Iterable[] { + Ix.range(1, 3), Ix.range(10, 2) }, + zipper); + + IxTestHelper.assertValues(source, 11, 13); + } + + @SuppressWarnings("unchecked") + @Test + public void bothEmpty() { + + Ix source = Ix.zip(new Iterable[] { + Ix.empty(), Ix.empty() }, + zipper); + + IxTestHelper.assertValues(source); + } + +} diff --git a/src/test/java/ix/ZipIterableTest.java b/src/test/java/ix/ZipIterableTest.java new file mode 100644 index 0000000..7d653d6 --- /dev/null +++ b/src/test/java/ix/ZipIterableTest.java @@ -0,0 +1,99 @@ +/* + * Copyright 2011-2016 David Karnok + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ix; + +import java.util.Arrays; + +import org.junit.Test; + +import rx.functions.FuncN; + +public class ZipIterableTest { + + FuncN zipper = new FuncN() { + @Override + public Integer call(Object... a) { + int s = 0; + for (Object o : a) { + s += (Integer)o; + } + return s; + } + }; + + @SuppressWarnings("unchecked") + @Test + public void normal() { + + Ix source = Ix.zip(Arrays.asList( + Ix.range(1, 2), Ix.range(10, 2)), + zipper); + + IxTestHelper.assertValues(source, 11, 13); + } + + @SuppressWarnings("unchecked") + @Test + public void normalMany() { + + Ix source = Ix.zip(Arrays.asList( + Ix.range(1, 2), Ix.range(1, 2), + Ix.range(1, 2), Ix.range(1, 2), + Ix.range(1, 2), Ix.range(1, 2), + Ix.range(1, 2), Ix.range(1, 2), + Ix.range(1, 2), Ix.range(1, 2), + Ix.range(1, 2), Ix.range(1, 2) + ), + zipper); + + IxTestHelper.assertValues(source, 12, 24); + } + + @SuppressWarnings("unchecked") + @Test + public void firstShorter() { + + Ix source = Ix.zip(Arrays.asList( + Ix.range(1, 1), Ix.range(10, 2) ), + zipper); + + IxTestHelper.assertValues(source, 11); + } + + @SuppressWarnings("unchecked") + @Test + public void secondShorter() { + + Ix source = Ix.zip(Arrays.asList( + Ix.range(1, 3), Ix.range(10, 2) ), + zipper); + + IxTestHelper.assertValues(source, 11, 13); + } + + @SuppressWarnings("unchecked") + @Test + public void bothEmpty() { + + Ix source = Ix.zip(Arrays.asList( + Ix.empty(), Ix.empty() ), + zipper); + + IxTestHelper.assertValues(source); + } + +} From a1c95ebcc90ead18853b20bc17f4b7e3740a4b08 Mon Sep 17 00:00:00 2001 From: akarnokd Date: Wed, 13 Jul 2016 16:27:17 +0200 Subject: [PATCH 18/66] + any, +all, +compose, +forloop, +repeat; fix take remove() passthrough --- src/main/java/ix/Ix.java | 34 +++---- src/main/java/ix/IxAll.java | 65 +++++++++++++ src/main/java/ix/IxAny.java | 65 +++++++++++++ src/main/java/ix/IxCompose.java | 22 +++++ src/main/java/ix/IxForloop.java | 88 ++++++++++++++++++ src/main/java/ix/IxRepeat.java | 57 ++++++++++++ src/main/java/ix/IxRepeatCount.java | 68 ++++++++++++++ src/main/java/ix/IxRepeatPredicate.java | 60 ++++++++++++ src/main/java/ix/IxTake.java | 5 + src/test/java/ix/AnyAllTest.java | 54 +++++++++++ src/test/java/ix/AsComposeTest.java | 56 ++++++++++++ src/test/java/ix/ForloopTest.java | 72 +++++++++++++++ src/test/java/ix/IxTestHelper.java | 2 +- src/test/java/ix/RepeatTest.java | 116 ++++++++++++++++++++++++ src/test/java/ix/TakeTest.java | 13 ++- 15 files changed, 755 insertions(+), 22 deletions(-) create mode 100644 src/main/java/ix/IxAll.java create mode 100644 src/main/java/ix/IxAny.java create mode 100644 src/main/java/ix/IxCompose.java create mode 100644 src/main/java/ix/IxForloop.java create mode 100644 src/main/java/ix/IxRepeat.java create mode 100644 src/main/java/ix/IxRepeatCount.java create mode 100644 src/main/java/ix/IxRepeatPredicate.java create mode 100644 src/test/java/ix/AnyAllTest.java create mode 100644 src/test/java/ix/AsComposeTest.java create mode 100644 src/test/java/ix/ForloopTest.java create mode 100644 src/test/java/ix/RepeatTest.java diff --git a/src/main/java/ix/Ix.java b/src/main/java/ix/Ix.java index 8ac4fd8..aaee3de 100644 --- a/src/main/java/ix/Ix.java +++ b/src/main/java/ix/Ix.java @@ -161,24 +161,22 @@ public static Ix zip( return new IxZip4(it1, it2, it3, it4, zipper); } - public static Ix repeat(T value) { - // TODO implement - throw new UnsupportedOperationException(); + public static Ix repeatValue(T value) { + return new IxRepeat(value); } - public static Ix repeat(T value, long count) { - // TODO implement - throw new UnsupportedOperationException(); + public static Ix repeatValue(T value, long count) { + return new IxRepeatCount(value, count); } - public static Ix repeat(T value, Pred0 stopPredicate) { - // TODO implement - throw new UnsupportedOperationException(); + public static Ix repeatValue(T value, Pred0 stopPredicate) { + return new IxRepeatPredicate(value, stopPredicate); } - public static Ix forloop(T seed, Pred condition, Func1 next) { - // TODO implement - throw new UnsupportedOperationException(); + public static Ix forloop(T seed, Pred condition, + Func1 next, + Func1 selector) { + return new IxForloop(seed, condition, selector, next); } //--------------------------------------------------------------------------------------- @@ -186,24 +184,20 @@ public static Ix forloop(T seed, Pred condition, Func1 R as(Func1, R> transformer) { - // TODO implement - throw new UnsupportedOperationException(); + return transformer.call(this); } public final Ix compose(Func1, ? extends Iterable> transformer) { - // TODO implement - throw new UnsupportedOperationException(); + return new IxCompose(this, transformer); } public final Ix any(Pred predicate) { - // TODO implement - throw new UnsupportedOperationException(); + return new IxAny(this, predicate); } public final Ix all(Pred predicate) { - // TODO implement - throw new UnsupportedOperationException(); + return new IxAll(this, predicate); } public final Ix hasElements() { diff --git a/src/main/java/ix/IxAll.java b/src/main/java/ix/IxAll.java new file mode 100644 index 0000000..be72ccb --- /dev/null +++ b/src/main/java/ix/IxAll.java @@ -0,0 +1,65 @@ +/* + * Copyright 2011-2016 David Karnok + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ix; + +import java.util.Iterator; + +final class IxAll extends IxSource { + + final Pred predicate; + + public IxAll(Iterable source, Pred predicate) { + super(source); + this.predicate = predicate; + } + + @Override + public Iterator iterator() { + return new AllIterator(source.iterator(), predicate); + } + + static final class AllIterator extends IxSourceIterator { + + final Pred predicate; + + public AllIterator(Iterator it, Pred predicate) { + super(it); + this.predicate = predicate; + } + + @Override + protected boolean moveNext() { + Iterator it = this.it; + Pred pred = predicate; + + while (it.hasNext()) { + if (!pred.test(it.next())) { + hasValue = true; + value = false; + done = true; + return true; + } + } + + hasValue = true; + value = true; + done = true; + return true; + } + + } +} diff --git a/src/main/java/ix/IxAny.java b/src/main/java/ix/IxAny.java new file mode 100644 index 0000000..201ddf3 --- /dev/null +++ b/src/main/java/ix/IxAny.java @@ -0,0 +1,65 @@ +/* + * Copyright 2011-2016 David Karnok + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ix; + +import java.util.Iterator; + +final class IxAny extends IxSource { + + final Pred predicate; + + public IxAny(Iterable source, Pred predicate) { + super(source); + this.predicate = predicate; + } + + @Override + public Iterator iterator() { + return new AnyIterator(source.iterator(), predicate); + } + + static final class AnyIterator extends IxSourceIterator { + + final Pred predicate; + + public AnyIterator(Iterator it, Pred predicate) { + super(it); + this.predicate = predicate; + } + + @Override + protected boolean moveNext() { + Iterator it = this.it; + Pred pred = predicate; + + while (it.hasNext()) { + if (pred.test(it.next())) { + hasValue = true; + value = true; + done = true; + return true; + } + } + + hasValue = true; + value = false; + done = true; + return true; + } + + } +} diff --git a/src/main/java/ix/IxCompose.java b/src/main/java/ix/IxCompose.java new file mode 100644 index 0000000..272cd78 --- /dev/null +++ b/src/main/java/ix/IxCompose.java @@ -0,0 +1,22 @@ +package ix; + +import java.util.Iterator; + +import rx.functions.Func1; + +final class IxCompose extends IxSource { + + final Func1, ? extends Iterable> transformer; + + public IxCompose(Iterable source, Func1, ? extends Iterable> transformer) { + super(source); + this.transformer = transformer; + } + + @SuppressWarnings("unchecked") + @Override + public Iterator iterator() { + return (Iterator)transformer.call(from(source)).iterator(); + } + +} diff --git a/src/main/java/ix/IxForloop.java b/src/main/java/ix/IxForloop.java new file mode 100644 index 0000000..acf1cf1 --- /dev/null +++ b/src/main/java/ix/IxForloop.java @@ -0,0 +1,88 @@ +/* + * Copyright 2011-2016 David Karnok + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ix; + +import java.util.Iterator; + +import rx.functions.Func1; + +final class IxForloop extends Ix { + + final T seed; + + final Pred condition; + + final Func1 selector; + + final Func1 next; + + public IxForloop(T seed, Pred condition, Func1 selector, + Func1 next) { + this.seed = seed; + this.condition = condition; + this.selector = selector; + this.next = next; + } + + @Override + public Iterator iterator() { + return new ForloopIterator(seed, condition, selector, next); + } + + static final class ForloopIterator extends IxBaseIterator { + + T index; + + final Pred condition; + + final Func1 selector; + + final Func1 next; + + boolean exceptFirst; + + public ForloopIterator(T index, Pred condition, Func1 selector, + Func1 next) { + this.index = index; + this.condition = condition; + this.selector = selector; + this.next = next; + } + + @Override + protected boolean moveNext() { + T i = index; + + if (exceptFirst) { + i = next.call(i); + index = i; + } else { + exceptFirst = true; + } + + if (!condition.test(i)) { + done = true; + return false; + } + + value = selector.call(i); + hasValue = true; + + return true; + } + } +} diff --git a/src/main/java/ix/IxRepeat.java b/src/main/java/ix/IxRepeat.java new file mode 100644 index 0000000..481af71 --- /dev/null +++ b/src/main/java/ix/IxRepeat.java @@ -0,0 +1,57 @@ +/* + * Copyright 2011-2016 David Karnok + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ix; + +import java.util.Iterator; + +final class IxRepeat extends Ix { + + final T value; + + public IxRepeat(T value) { + this.value = value; + } + + @Override + public Iterator iterator() { + return new RepeatIterator(value); + } + + static final class RepeatIterator implements Iterator { + + final T value; + + public RepeatIterator(T value) { + this.value = value; + } + + @Override + public boolean hasNext() { + return true; + } + + @Override + public T next() { + return value; + } + + @Override + public void remove() { + throw new UnsupportedOperationException(); + } + } +} diff --git a/src/main/java/ix/IxRepeatCount.java b/src/main/java/ix/IxRepeatCount.java new file mode 100644 index 0000000..4e07497 --- /dev/null +++ b/src/main/java/ix/IxRepeatCount.java @@ -0,0 +1,68 @@ +/* + * Copyright 2011-2016 David Karnok + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ix; + +import java.util.*; + +final class IxRepeatCount extends Ix { + + final T value; + + final long count; + + public IxRepeatCount(T value, long count) { + this.value = value; + this.count = count; + } + + @Override + public Iterator iterator() { + return new RepeatCountIterator(value, count); + } + + static final class RepeatCountIterator implements Iterator { + + final T value; + + long count; + + public RepeatCountIterator(T value, long count) { + this.value = value; + this.count = count; + } + + @Override + public boolean hasNext() { + return count != 0L; + } + + @Override + public T next() { + long c = count; + if (c != 0L) { + count = c - 1; + return value; + } + throw new NoSuchElementException(); + } + + @Override + public void remove() { + throw new UnsupportedOperationException(); + } + } +} diff --git a/src/main/java/ix/IxRepeatPredicate.java b/src/main/java/ix/IxRepeatPredicate.java new file mode 100644 index 0000000..957df9d --- /dev/null +++ b/src/main/java/ix/IxRepeatPredicate.java @@ -0,0 +1,60 @@ +/* + * Copyright 2011-2016 David Karnok + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ix; + +import java.util.*; + +final class IxRepeatPredicate extends Ix { + + final T value; + + final Pred0 stopPredicate; + + public IxRepeatPredicate(T value, Pred0 stopPredicate) { + this.value = value; + this.stopPredicate = stopPredicate; + } + + @Override + public Iterator iterator() { + return new RepeatPredicateIterator(value, stopPredicate); + } + + static final class RepeatPredicateIterator extends IxBaseIterator { + + final T valueToRepeat; + + final Pred0 stopPredicate; + + public RepeatPredicateIterator(T value, Pred0 stopPredicate) { + this.valueToRepeat = value; + this.stopPredicate = stopPredicate; + } + + @Override + protected boolean moveNext() { + if (!stopPredicate.getAsBoolean()) { + value = valueToRepeat; + hasValue = true; + return true; + } + done = true; + return false; + } + + } +} diff --git a/src/main/java/ix/IxTake.java b/src/main/java/ix/IxTake.java index 24d2d00..93e0ca6 100644 --- a/src/main/java/ix/IxTake.java +++ b/src/main/java/ix/IxTake.java @@ -54,6 +54,11 @@ protected boolean moveNext() { return true; } + + @Override + public void remove() { + it.remove(); + } } } diff --git a/src/test/java/ix/AnyAllTest.java b/src/test/java/ix/AnyAllTest.java new file mode 100644 index 0000000..da2e7cb --- /dev/null +++ b/src/test/java/ix/AnyAllTest.java @@ -0,0 +1,54 @@ +/* + * Copyright 2011-2016 David Karnok + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ix; + +import org.junit.Test; + +public class AnyAllTest { + + @Test + public void anyFound() { + + } + + @Test + public void anyNotFound() { + + } + + @Test + public void anyEmpty() { + + } + + @Test + public void allTrue() { + + } + + @Test + public void allFalse() { + + } + + @Test + public void allEmpty() { + + } + + +} diff --git a/src/test/java/ix/AsComposeTest.java b/src/test/java/ix/AsComposeTest.java new file mode 100644 index 0000000..4e32ebb --- /dev/null +++ b/src/test/java/ix/AsComposeTest.java @@ -0,0 +1,56 @@ +/* + * Copyright 2011-2016 David Karnok + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ix; + +import org.junit.*; + +import rx.functions.Func1; + +public class AsComposeTest { + + @Test + public void normal() { + Integer value = Ix.range(1, 5).as(new Func1, Integer>() { + @Override + public Integer call(Ix ix) { + return ix.first(); + } + }); + + Assert.assertEquals(1, value.intValue()); + } + + @Test + public void compose() { + Ix source = Ix.range(1, 5).compose(new Func1, Iterable>() { + @Override + public Iterable call(Ix ix) { + final int[] index = { 1 }; + return ix.map(new Func1() { + @Override + public String call(Integer v) { + return v + "-" + (index[0]++); + } + }); + } + }); + + IxTestHelper.assertValues(source, "1-1", "2-2", "3-3", "4-4", "5-5"); + + IxTestHelper.assertValues(source, "1-1", "2-2", "3-3", "4-4", "5-5"); + } +} diff --git a/src/test/java/ix/ForloopTest.java b/src/test/java/ix/ForloopTest.java new file mode 100644 index 0000000..8db6fdf --- /dev/null +++ b/src/test/java/ix/ForloopTest.java @@ -0,0 +1,72 @@ +/* + * Copyright 2011-2016 David Karnok + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ix; + +import org.junit.Test; + +import rx.functions.Func1; + +public class ForloopTest { + + @Test + public void normal() { + Ix source = Ix.forloop(1, new Pred() { + @Override + public boolean test(Integer i) { + return i <= 5; + } + }, new Func1() { + @Override + public Integer call(Integer i) { + return i + 1; + } + }, new Func1() { + @Override + public Integer call(Integer i) { + return i * i; + } + }); + + IxTestHelper.assertValues(source, 1, 4, 9, 16, 25); + + IxTestHelper.assertNoRemove(source); + } + + @Test + public void empty() { + Ix source = Ix.forloop(1, new Pred() { + @Override + public boolean test(Integer i) { + return false; + } + }, new Func1() { + @Override + public Integer call(Integer i) { + return i + 1; + } + }, new Func1() { + @Override + public Integer call(Integer i) { + return i * i; + } + }); + + IxTestHelper.assertValues(source); + + IxTestHelper.assertNoRemove(source); + } +} diff --git a/src/test/java/ix/IxTestHelper.java b/src/test/java/ix/IxTestHelper.java index cfdc589..02ba24d 100644 --- a/src/test/java/ix/IxTestHelper.java +++ b/src/test/java/ix/IxTestHelper.java @@ -66,7 +66,7 @@ public static void assertValues(Iterable source, T... values) { } if (i != values.length) { - throw new AssertionError("The source is shorter than " + values.length); + throw new AssertionError("The source is shorter than " + values.length + ": " + i); } try { diff --git a/src/test/java/ix/RepeatTest.java b/src/test/java/ix/RepeatTest.java new file mode 100644 index 0000000..8cb62d4 --- /dev/null +++ b/src/test/java/ix/RepeatTest.java @@ -0,0 +1,116 @@ +/* + * Copyright 2011-2016 David Karnok + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ix; + +import org.junit.Test; + +public class RepeatTest { + + @Test + public void normal() { + Ix source = Ix.repeatValue(1).take(5); + + IxTestHelper.assertValues(source, 1, 1, 1, 1, 1); + + IxTestHelper.assertNoRemove(source); + } + + @Test + public void normalLimited() { + Ix source = Ix.repeatValue(1, 5); + + IxTestHelper.assertValues(source, 1, 1, 1, 1, 1); + + IxTestHelper.assertNoRemove(source); + } + + @Test + public void neverRepeat() { + Ix source = Ix.repeatValue(1, 0); + + IxTestHelper.assertValues(source); + + IxTestHelper.assertNoRemove(source); + } + + @Test + public void repeatOnce() { + Ix source = Ix.repeatValue(1, 1); + + IxTestHelper.assertValues(source, 1); + + IxTestHelper.assertNoRemove(source); + } + + @Test + public void predicateLimited() { + Ix source = Ix.repeatValue(1, new Pred0() { + int count = 5; + @Override + public boolean getAsBoolean() { + return count-- == 0; + } + }); + + IxTestHelper.assertValues(source, 1, 1, 1, 1, 1); + + IxTestHelper.assertNoRemove(source); + } + + @Test + public void predicateNeverRepeat() { + Ix source = Ix.repeatValue(1, new Pred0() { + @Override + public boolean getAsBoolean() { + return true; + } + }); + + IxTestHelper.assertValues(source); + + IxTestHelper.assertNoRemove(source); + } + + @Test + public void predicateRepeatOnce() { + Ix source = Ix.repeatValue(1, new Pred0() { + int count = 1; + @Override + public boolean getAsBoolean() { + return count-- == 0; + } + }); + + IxTestHelper.assertValues(source, 1); + + IxTestHelper.assertNoRemove(source); + } + + @Test + public void predicateInfinite() { + Ix source = Ix.repeatValue(1, new Pred0() { + @Override + public boolean getAsBoolean() { + return false; + } + }).take(5); + + IxTestHelper.assertValues(source, 1, 1, 1, 1, 1); + + IxTestHelper.assertNoRemove(source); +} +} diff --git a/src/test/java/ix/TakeTest.java b/src/test/java/ix/TakeTest.java index 1b46053..cdf769a 100644 --- a/src/test/java/ix/TakeTest.java +++ b/src/test/java/ix/TakeTest.java @@ -16,7 +16,9 @@ package ix; -import org.junit.Test; +import java.util.*; + +import org.junit.*; public class TakeTest { @@ -61,5 +63,14 @@ public void empty() { IxTestHelper.assertValues(source); } + + @Test + public void removeComposes() { + List list = Ix.range(1, 10).toList().first(); + + Ix.from(list).take(5).removeAll(); + + Assert.assertEquals(Arrays.asList(6, 7, 8, 9, 10), list); + } } From beca0e84e3359894e2e043ef6198940679cd9b86 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?D=C3=A1vid=20Karnok?= Date: Wed, 13 Jul 2016 20:47:19 +0200 Subject: [PATCH 19/66] A bunch of operators. --- src/main/java/ix/EqualityHelper.java | 26 ++++ src/main/java/ix/GroupedIx.java | 16 ++ src/main/java/ix/Ix.java | 88 +++++------ src/main/java/ix/IxCompose.java | 16 ++ src/main/java/ix/IxContains.java | 66 +++++++++ src/main/java/ix/IxCount.java | 55 +++++++ src/main/java/ix/IxCountLong.java | 55 +++++++ src/main/java/ix/IxDefer.java | 16 ++ src/main/java/ix/IxDistinct.java | 68 +++++++++ src/main/java/ix/IxDistinctUntilChanged.java | 97 ++++++++++++ src/main/java/ix/IxDoOn.java | 49 +++++++ src/main/java/ix/IxEmptyAction.java | 11 +- src/main/java/ix/IxHasElements.java | 46 ++++++ src/main/java/ix/IxIgnoreElements.java | 51 +++++++ src/main/java/ix/IxJoin.java | 67 +++++++++ src/main/java/ix/IxMinMax.java | 81 ++++++++++ src/main/java/ix/SelfComparator.java | 31 ++++ src/test/java/ix/AnyAllTest.java | 54 +++++++ src/test/java/ix/ConcatArrayTest.java | 55 +++++++ src/test/java/ix/ContainsTest.java | 85 +++++++++++ src/test/java/ix/CountTest.java | 77 ++++++++++ src/test/java/ix/DistinctTest.java | 50 +++++++ .../java/ix/DistinctUntilChangedTest.java | 71 +++++++++ src/test/java/ix/DoOnTest.java | 68 +++++++++ src/test/java/ix/EmptyActionTest.java | 31 ++++ src/test/java/ix/EqualityHelperTest.java | 39 +++++ src/test/java/ix/HasElementsTest.java | 37 +++++ src/test/java/ix/IgnoreElementsTest.java | 41 ++++++ src/test/java/ix/JoinTest.java | 77 ++++++++++ src/test/java/ix/MinMaxTest.java | 138 ++++++++++++++++++ src/test/java/ix/SelfComparatorTest.java | 39 +++++ 31 files changed, 1645 insertions(+), 56 deletions(-) create mode 100644 src/main/java/ix/EqualityHelper.java create mode 100644 src/main/java/ix/IxContains.java create mode 100644 src/main/java/ix/IxCount.java create mode 100644 src/main/java/ix/IxCountLong.java create mode 100644 src/main/java/ix/IxDistinct.java create mode 100644 src/main/java/ix/IxDistinctUntilChanged.java create mode 100644 src/main/java/ix/IxDoOn.java create mode 100644 src/main/java/ix/IxHasElements.java create mode 100644 src/main/java/ix/IxIgnoreElements.java create mode 100644 src/main/java/ix/IxJoin.java create mode 100644 src/main/java/ix/IxMinMax.java create mode 100644 src/main/java/ix/SelfComparator.java create mode 100644 src/test/java/ix/ContainsTest.java create mode 100644 src/test/java/ix/CountTest.java create mode 100644 src/test/java/ix/DistinctTest.java create mode 100644 src/test/java/ix/DistinctUntilChangedTest.java create mode 100644 src/test/java/ix/DoOnTest.java create mode 100644 src/test/java/ix/EmptyActionTest.java create mode 100644 src/test/java/ix/EqualityHelperTest.java create mode 100644 src/test/java/ix/HasElementsTest.java create mode 100644 src/test/java/ix/IgnoreElementsTest.java create mode 100644 src/test/java/ix/JoinTest.java create mode 100644 src/test/java/ix/MinMaxTest.java create mode 100644 src/test/java/ix/SelfComparatorTest.java diff --git a/src/main/java/ix/EqualityHelper.java b/src/main/java/ix/EqualityHelper.java new file mode 100644 index 0000000..9d51f0a --- /dev/null +++ b/src/main/java/ix/EqualityHelper.java @@ -0,0 +1,26 @@ +/* + * Copyright 2011-2016 David Karnok + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ix; + +enum EqualityHelper implements Pred2 { + INSTANCE; + + @Override + public boolean test(Object t, Object u) { + return (t == u) || (t != null && t.equals(u)); + } +} diff --git a/src/main/java/ix/GroupedIx.java b/src/main/java/ix/GroupedIx.java index a4d405c..18672e2 100644 --- a/src/main/java/ix/GroupedIx.java +++ b/src/main/java/ix/GroupedIx.java @@ -1,3 +1,19 @@ +/* + * Copyright 2011-2016 David Karnok + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package ix; /** diff --git a/src/main/java/ix/Ix.java b/src/main/java/ix/Ix.java index aaee3de..517d4c8 100644 --- a/src/main/java/ix/Ix.java +++ b/src/main/java/ix/Ix.java @@ -201,108 +201,87 @@ public final Ix all(Pred predicate) { } public final Ix hasElements() { - // TODO implement - throw new UnsupportedOperationException(); + return new IxHasElements(this); } public final Ix ignoreElements() { - // TODO implement - throw new UnsupportedOperationException(); + return new IxIgnoreElements(this); } public final Ix max(Comparator comparator) { - // TODO implement - throw new UnsupportedOperationException(); + return new IxMinMax(this, comparator, -1); } + @SuppressWarnings({ "rawtypes", "unchecked" }) public final Ix max() { - // TODO implement - throw new UnsupportedOperationException(); + return max((Comparator)SelfComparator.INSTANCE); } public final Ix min(Comparator comparator) { - // TODO implement - throw new UnsupportedOperationException(); + return new IxMinMax(this, comparator, 1); } + @SuppressWarnings({ "rawtypes", "unchecked" }) public final Ix min() { - // TODO implement - throw new UnsupportedOperationException(); + return min((Comparator)SelfComparator.INSTANCE); } public final Ix contains(Object o) { - // TODO implement - throw new UnsupportedOperationException(); + return new IxContains(this, o); } public final Ix count() { - // TODO implement - throw new UnsupportedOperationException(); + return new IxCount(this); } public final Ix countLong() { - // TODO implement - throw new UnsupportedOperationException(); + return new IxCountLong(this); } public final Ix distinct() { - // TODO implement - throw new UnsupportedOperationException(); - } - - public final Ix distinct(Pred2 comparer) { - // TODO implement - throw new UnsupportedOperationException(); + return distinct(IdentityHelper.instance()); } public final Ix distinct(Func1 keySelector) { - // TODO implement - throw new UnsupportedOperationException(); + return new IxDistinct(this, keySelector); } public final Ix distinctUntilChanged() { - // TODO implement - throw new UnsupportedOperationException(); + return distinctUntilChanged(IdentityHelper.instance()); } public final Ix distinctUntilChanged(Pred2 comparer) { - // TODO implement - throw new UnsupportedOperationException(); + return new IxDistinctUntilChanged(this, IdentityHelper.instance(), comparer); } public final Ix distinctUntilChanged(Func1 keySelector) { - // TODO implement - throw new UnsupportedOperationException(); + return new IxDistinctUntilChanged(this, keySelector, EqualityHelper.INSTANCE); } public final Ix doOnNext(Action1 action) { - // TODO implement - throw new UnsupportedOperationException(); + return new IxDoOn(this, action, IxEmptyAction.instance0()); } - public final Ix doOnCompleted(Action1 action) { - // TODO implement - throw new UnsupportedOperationException(); + public final Ix doOnCompleted(Action0 action) { + return new IxDoOn(this, IxEmptyAction.instance1(), action); } - public final Ix startWith(T... value) { - // TODO implement - throw new UnsupportedOperationException(); + @SuppressWarnings("unchecked") + public final Ix startWith(T... values) { + return concatArray(fromArray(values), this); } - public final Ix endWith(T... value) { - // TODO implement - throw new UnsupportedOperationException(); + @SuppressWarnings("unchecked") + public final Ix endWith(T... values) { + return concatArray(this, fromArray(values)); } public final Ix join() { - // TODO implement - throw new UnsupportedOperationException(); + return join(", "); } public final Ix join(CharSequence separator) { - // TODO implement - throw new UnsupportedOperationException(); + return new IxJoin(this, separator); } public final Ix map(Func1 mapper) { @@ -515,18 +494,17 @@ public final Ix> window(int size, int skip) { throw new UnsupportedOperationException(); } - public final Ix concatWith(Iterator other) { - // TODO implement - throw new UnsupportedOperationException(); + @SuppressWarnings("unchecked") + public final Ix concatWith(Iterable other) { + return concatArray(this, other); } - public final Ix mergeWith(Iterator other) { + public final Ix mergeWith(Iterable other) { return concatWith(other); } - public final Ix zipWith(Iterator other, Func2 zipper) { - // TODO implement - throw new UnsupportedOperationException(); + public final Ix zipWith(Iterable other, Func2 zipper) { + return zip(this, other, zipper); } public final Ix orderBy() { diff --git a/src/main/java/ix/IxCompose.java b/src/main/java/ix/IxCompose.java index 272cd78..03775a9 100644 --- a/src/main/java/ix/IxCompose.java +++ b/src/main/java/ix/IxCompose.java @@ -1,3 +1,19 @@ +/* + * Copyright 2011-2016 David Karnok + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package ix; import java.util.Iterator; diff --git a/src/main/java/ix/IxContains.java b/src/main/java/ix/IxContains.java new file mode 100644 index 0000000..b9f58aa --- /dev/null +++ b/src/main/java/ix/IxContains.java @@ -0,0 +1,66 @@ +/* + * Copyright 2011-2016 David Karnok + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ix; + +import java.util.Iterator; + +final class IxContains extends IxSource { + + final Object o; + + public IxContains(Iterable source, Object o) { + super(source); + this.o = o; + } + + @Override + public Iterator iterator() { + return new ContainsIterator(source.iterator(), o); + } + + static final class ContainsIterator extends IxSourceIterator { + + final Object o; + + public ContainsIterator(Iterator it, Object o) { + super(it); + this.o = o; + } + + @Override + protected boolean moveNext() { + Iterator it = this.it; + Object o = this.o; + + while (it.hasNext()) { + T v = it.next(); + if (o == v || (o != null && o.equals(v))) { + value = true; + hasValue = true; + done = true; + return true; + } + } + + value = false; + hasValue = true; + done = true; + return true; + } + } + +} diff --git a/src/main/java/ix/IxCount.java b/src/main/java/ix/IxCount.java new file mode 100644 index 0000000..2866a5d --- /dev/null +++ b/src/main/java/ix/IxCount.java @@ -0,0 +1,55 @@ +/* + * Copyright 2011-2016 David Karnok + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ix; + +import java.util.Iterator; + +final class IxCount extends IxSource { + + public IxCount(Iterable source) { + super(source); + } + + @Override + public Iterator iterator() { + return new CountIterator(source.iterator()); + } + + static final class CountIterator extends IxSourceIterator { + + public CountIterator(Iterator it) { + super(it); + } + + @Override + protected boolean moveNext() { + int c = 0; + + Iterator it = this.it; + + while (it.hasNext()) { + it.next(); + c++; + } + + value = c; + hasValue = true; + done = true; + return true; + } + } +} diff --git a/src/main/java/ix/IxCountLong.java b/src/main/java/ix/IxCountLong.java new file mode 100644 index 0000000..240fde1 --- /dev/null +++ b/src/main/java/ix/IxCountLong.java @@ -0,0 +1,55 @@ +/* + * Copyright 2011-2016 David Karnok + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ix; + +import java.util.Iterator; + +final class IxCountLong extends IxSource { + + public IxCountLong(Iterable source) { + super(source); + } + + @Override + public Iterator iterator() { + return new CountLongIterator(source.iterator()); + } + + static final class CountLongIterator extends IxSourceIterator { + + public CountLongIterator(Iterator it) { + super(it); + } + + @Override + protected boolean moveNext() { + long c = 0; + + Iterator it = this.it; + + while (it.hasNext()) { + it.next(); + c++; + } + + value = c; + hasValue = true; + done = true; + return true; + } + } +} diff --git a/src/main/java/ix/IxDefer.java b/src/main/java/ix/IxDefer.java index c9ba8fc..af03c3c 100644 --- a/src/main/java/ix/IxDefer.java +++ b/src/main/java/ix/IxDefer.java @@ -1,3 +1,19 @@ +/* + * Copyright 2011-2016 David Karnok + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package ix; import java.util.Iterator; diff --git a/src/main/java/ix/IxDistinct.java b/src/main/java/ix/IxDistinct.java new file mode 100644 index 0000000..97a13d0 --- /dev/null +++ b/src/main/java/ix/IxDistinct.java @@ -0,0 +1,68 @@ +/* + * Copyright 2011-2016 David Karnok + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ix; + +import java.util.*; + +import rx.functions.Func1; + +final class IxDistinct extends IxSource { + + final Func1 keySelector; + + public IxDistinct(Iterable source, Func1 keySelector) { + super(source); + this.keySelector = keySelector; + } + + @Override + public Iterator iterator() { + return new DistinctIterator(source.iterator(), keySelector); + } + + static final class DistinctIterator extends IxSourceIterator { + final Func1 keySelector; + + final Set set; + + public DistinctIterator(Iterator it, Func1 keySelector) { + super(it); + this.keySelector = keySelector; + this.set = new HashSet(); + } + + @Override + protected boolean moveNext() { + Iterator it = this.it; + + while (it.hasNext()) { + T v = it.next(); + + K k = keySelector.call(v); + + if (set.add(k)) { + value = v; + hasValue = true; + return true; + } + } + + done = true; + return false; + } + } +} diff --git a/src/main/java/ix/IxDistinctUntilChanged.java b/src/main/java/ix/IxDistinctUntilChanged.java new file mode 100644 index 0000000..9915650 --- /dev/null +++ b/src/main/java/ix/IxDistinctUntilChanged.java @@ -0,0 +1,97 @@ +/* + * Copyright 2011-2016 David Karnok + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ix; + +import java.util.Iterator; + +import rx.functions.Func1; + +final class IxDistinctUntilChanged extends IxSource { + + final Func1 keySelector; + + final Pred2 comparer; + + public IxDistinctUntilChanged(Iterable source, Func1 keySelector, + Pred2 comparer) { + super(source); + this.keySelector = keySelector; + this.comparer = comparer; + } + + @Override + public Iterator iterator() { + return new DistinctUntilChangedIterator(source.iterator(), keySelector, comparer); + } + + static final class DistinctUntilChangedIterator extends IxSourceIterator { + + final Func1 keySelector; + + final Pred2 comparer; + + K last; + + boolean once; + + public DistinctUntilChangedIterator(Iterator it, Func1 keySelector, + Pred2 comparer) { + super(it); + this.keySelector = keySelector; + this.comparer = comparer; + } + + @Override + protected boolean moveNext() { + Iterator it = this.it; + + K prev = last; + K curr = null; + + while (it.hasNext()) { + T v = it.next(); + curr = keySelector.call(v); + + if (!once) { + once = true; + + last = curr; + + value = v; + hasValue = true; + return true; + } + + if (!comparer.test(prev, curr)) { + last = curr; + + value = v; + hasValue = true; + return true; + } + + prev = curr; + } + + + done = true; + return false; + } + + + } +} diff --git a/src/main/java/ix/IxDoOn.java b/src/main/java/ix/IxDoOn.java new file mode 100644 index 0000000..68e430b --- /dev/null +++ b/src/main/java/ix/IxDoOn.java @@ -0,0 +1,49 @@ +package ix; + +import java.util.Iterator; + +import rx.functions.*; + +final class IxDoOn extends IxSource { + + final Action1 onNext; + + final Action0 onCompleted; + + public IxDoOn(Iterable source, Action1 onNext, Action0 onCompleted) { + super(source); + this.onNext = onNext; + this.onCompleted = onCompleted; + } + + @Override + public Iterator iterator() { + return new DoOnIterator(source.iterator(), onNext, onCompleted); + } + + static final class DoOnIterator extends IxSourceIterator { + final Action1 onNext; + + final Action0 onCompleted; + + public DoOnIterator(Iterator it, Action1 onNext, Action0 onCompleted) { + super(it); + this.onNext = onNext; + this.onCompleted = onCompleted; + } + + @Override + protected boolean moveNext() { + if (it.hasNext()) { + T v = it.next(); + value = v; + hasValue = true; + onNext.call(v); + return true; + } + onCompleted.call(); + done = true; + return false; + } + } +} diff --git a/src/main/java/ix/IxEmptyAction.java b/src/main/java/ix/IxEmptyAction.java index 1dfd0c4..dcd81f3 100644 --- a/src/main/java/ix/IxEmptyAction.java +++ b/src/main/java/ix/IxEmptyAction.java @@ -18,7 +18,7 @@ import rx.functions.*; -enum IxEmptyAction implements Action1 { +enum IxEmptyAction implements Action1, Action0 { INSTANCE; @SuppressWarnings("unchecked") @@ -26,9 +26,18 @@ public static Action1 instance1() { return (Action1)INSTANCE; } + public static Action0 instance0() { + return INSTANCE; + } + @Override public void call(Object t) { // deliberately no op } + @Override + public void call() { + // deliberately no op + } + } diff --git a/src/main/java/ix/IxHasElements.java b/src/main/java/ix/IxHasElements.java new file mode 100644 index 0000000..3b6405c --- /dev/null +++ b/src/main/java/ix/IxHasElements.java @@ -0,0 +1,46 @@ +/* + * Copyright 2011-2016 David Karnok + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ix; + +import java.util.Iterator; + +final class IxHasElements extends IxSource { + + public IxHasElements(Iterable source) { + super(source); + } + + @Override + public Iterator iterator() { + return new HasElementsIterator(source.iterator()); + } + + static final class HasElementsIterator extends IxSourceIterator { + + public HasElementsIterator(Iterator it) { + super(it); + } + + @Override + protected boolean moveNext() { + value = it.hasNext(); + hasValue = true; + done = true; + return true; + } + } +} diff --git a/src/main/java/ix/IxIgnoreElements.java b/src/main/java/ix/IxIgnoreElements.java new file mode 100644 index 0000000..f431128 --- /dev/null +++ b/src/main/java/ix/IxIgnoreElements.java @@ -0,0 +1,51 @@ +/* + * Copyright 2011-2016 David Karnok + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ix; + +import java.util.Iterator; + +final class IxIgnoreElements extends IxSource { + + public IxIgnoreElements(Iterable source) { + super(source); + } + + @Override + public Iterator iterator() { + return new IgnoreElementsIterator(source.iterator()); + } + + static final class IgnoreElementsIterator extends IxSourceIterator { + + public IgnoreElementsIterator(Iterator it) { + super(it); + } + + @Override + protected boolean moveNext() { + Iterator it = this.it; + + while (it.hasNext()) { + it.next(); + } + + done = true; + return false; + } + + } +} diff --git a/src/main/java/ix/IxJoin.java b/src/main/java/ix/IxJoin.java new file mode 100644 index 0000000..4142c06 --- /dev/null +++ b/src/main/java/ix/IxJoin.java @@ -0,0 +1,67 @@ +/* + * Copyright 2011-2016 David Karnok + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ix; + +import java.util.Iterator; + +final class IxJoin extends IxSource { + + final CharSequence separator; + + public IxJoin(Iterable source, CharSequence separator) { + super(source); + this.separator = separator; + } + + @Override + public Iterator iterator() { + return new JoinIterator(source.iterator(), separator); + } + + static final class JoinIterator extends IxSourceIterator { + final CharSequence separator; + + public JoinIterator(Iterator it, CharSequence separator) { + super(it); + this.separator = separator; + } + + @Override + protected boolean moveNext() { + CharSequence sep = separator; + + Iterator it = this.it; + + StringBuilder b = new StringBuilder(); + + if (it.hasNext()) { + b.append(it.next()); + + while (it.hasNext()) { + b.append(sep); + b.append(it.next()); + } + } + + value = b.toString(); + hasValue = true; + done = true; + return true; + } + } + +} diff --git a/src/main/java/ix/IxMinMax.java b/src/main/java/ix/IxMinMax.java new file mode 100644 index 0000000..1adf261 --- /dev/null +++ b/src/main/java/ix/IxMinMax.java @@ -0,0 +1,81 @@ +/* + * Copyright 2011-2016 David Karnok + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ix; + +import java.util.*; + +final class IxMinMax extends IxSource { + + final Comparator comparator; + + final int flag; + + public IxMinMax(Iterable source, Comparator comparator, int flag) { + super(source); + this.comparator = comparator; + this.flag = flag; + } + + @Override + public Iterator iterator() { + return new MinMaxIterator(source.iterator(), comparator, flag); + } + + static final class MinMaxIterator extends IxSourceIterator { + + final Comparator comparator; + + final int flag; + + public MinMaxIterator(Iterator it, Comparator comparator, int flag) { + super(it); + this.comparator = comparator; + this.flag = flag; + } + + @Override + protected boolean moveNext() { + T v; + + Iterator it = this.it; + + if (!it.hasNext()) { + done = true; + return false; + } + + v = it.next(); + + Comparator f = comparator; + int g = flag; + + while (it.hasNext()) { + T w = it.next(); + if (f.compare(v, w) * g > 0) { + v = w; + } + } + + value = v; + hasValue = true; + done = true; + return true; + } + + } + +} diff --git a/src/main/java/ix/SelfComparator.java b/src/main/java/ix/SelfComparator.java new file mode 100644 index 0000000..75f3368 --- /dev/null +++ b/src/main/java/ix/SelfComparator.java @@ -0,0 +1,31 @@ +/* + * Copyright 2011-2016 David Karnok + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ix; + +import java.util.Comparator; + +@SuppressWarnings("rawtypes") +enum SelfComparator implements Comparator { + INSTANCE + ; + + @SuppressWarnings("unchecked") + @Override + public int compare(Comparable o1, Comparable o2) { + return o1.compareTo(o2); + } +} diff --git a/src/test/java/ix/AnyAllTest.java b/src/test/java/ix/AnyAllTest.java index da2e7cb..295e26b 100644 --- a/src/test/java/ix/AnyAllTest.java +++ b/src/test/java/ix/AnyAllTest.java @@ -22,32 +22,86 @@ public class AnyAllTest { @Test public void anyFound() { + Ix source = Ix.range(1, 5).any(new Pred() { + @Override + public boolean test(Integer v) { + return v == 3; + } + }); + IxTestHelper.assertValues(source, true); + + IxTestHelper.assertNoRemove(source); } @Test public void anyNotFound() { + Ix source = Ix.range(1, 5).any(new Pred() { + @Override + public boolean test(Integer v) { + return v == 0; + } + }); + + IxTestHelper.assertValues(source, false); + IxTestHelper.assertNoRemove(source); } @Test public void anyEmpty() { + Ix source = Ix.empty().any(new Pred() { + @Override + public boolean test(Integer v) { + return v == 3; + } + }); + + IxTestHelper.assertValues(source, false); + IxTestHelper.assertNoRemove(source); } @Test public void allTrue() { + Ix source = Ix.range(1, 5).all(new Pred() { + @Override + public boolean test(Integer v) { + return v < 6; + } + }); + IxTestHelper.assertValues(source, true); + + IxTestHelper.assertNoRemove(source); } @Test public void allFalse() { + Ix source = Ix.range(1, 5).all(new Pred() { + @Override + public boolean test(Integer v) { + return false; + } + }); + + IxTestHelper.assertValues(source, false); + IxTestHelper.assertNoRemove(source); } @Test public void allEmpty() { + Ix source = Ix.empty().all(new Pred() { + @Override + public boolean test(Integer v) { + return false; + } + }); + + IxTestHelper.assertValues(source, true); + IxTestHelper.assertNoRemove(source); } diff --git a/src/test/java/ix/ConcatArrayTest.java b/src/test/java/ix/ConcatArrayTest.java index aba429f..22cfc7d 100644 --- a/src/test/java/ix/ConcatArrayTest.java +++ b/src/test/java/ix/ConcatArrayTest.java @@ -113,4 +113,59 @@ public void concatIterableViaMerge() { IxTestHelper.assertValues(source, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10); } + @Test + public void startWith() { + Ix source = Ix.range(1, 5).startWith(5, 4, 3, 2, 1); + + IxTestHelper.assertValues(source, 5, 4, 3, 2, 1, 1, 2, 3, 4, 5); + } + + @Test + public void startWithEmpty() { + Ix source = Ix.range(1, 5).startWith(); + + IxTestHelper.assertValues(source, 1, 2, 3, 4, 5); + } + + @Test + public void endWith() { + Ix source = Ix.range(1, 5).endWith(5, 4, 3, 2, 1); + + IxTestHelper.assertValues(source, 1, 2, 3, 4, 5, 5, 4, 3, 2, 1); + } + + @Test + public void endWithEmpty() { + Ix source = Ix.range(1, 5).endWith(); + + IxTestHelper.assertValues(source, 1, 2, 3, 4, 5); + } + + @Test + public void concatWith() { + Ix source = Ix.range(1, 5).concatWith(Ix.range(6, 5)); + + IxTestHelper.assertValues(source, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10); + } + + @Test + public void concatWithEmpty() { + Ix source = Ix.range(1, 5).concatWith(Ix.empty()); + + IxTestHelper.assertValues(source, 1, 2, 3, 4, 5); + } + + @Test + public void mergeWith() { + Ix source = Ix.range(1, 5).mergeWith(Ix.range(6, 5)); + + IxTestHelper.assertValues(source, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10); + } + + @Test + public void mergeWithEmpty() { + Ix source = Ix.range(1, 5).mergeWith(Ix.empty()); + + IxTestHelper.assertValues(source, 1, 2, 3, 4, 5); + } } diff --git a/src/test/java/ix/ContainsTest.java b/src/test/java/ix/ContainsTest.java new file mode 100644 index 0000000..504520b --- /dev/null +++ b/src/test/java/ix/ContainsTest.java @@ -0,0 +1,85 @@ +/* + * Copyright 2011-2016 David Karnok + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ix; + +import org.junit.Test; + +public class ContainsTest { + + @Test + public void normal() { + Ix source = Ix.range(1, 5).contains(3); + + IxTestHelper.assertValues(source, true); + + IxTestHelper.assertNoRemove(source); + } + + @Test + public void normalNoReferenceEquals() { + Ix source = Ix.range(1, 5).contains(new Integer(3)); + + IxTestHelper.assertValues(source, true); + + IxTestHelper.assertNoRemove(source); + } + + @Test + public void doesntContain() { + Ix source = Ix.range(1, 5).contains(6); + + IxTestHelper.assertValues(source, false); + + IxTestHelper.assertNoRemove(source); + } + + @Test + public void doesntContainNull() { + Ix source = Ix.range(1, 5).contains(null); + + IxTestHelper.assertValues(source, false); + + IxTestHelper.assertNoRemove(source); + } + + @Test + public void empty() { + Ix source = Ix.empty().contains(6); + + IxTestHelper.assertValues(source, false); + + IxTestHelper.assertNoRemove(source); + } + + @Test + public void justNull() { + Ix source = Ix.just(null).contains(6); + + IxTestHelper.assertValues(source, false); + + IxTestHelper.assertNoRemove(source); + } + + @Test + public void justNullContains() { + Ix source = Ix.just(null).contains(null); + + IxTestHelper.assertValues(source, true); + + IxTestHelper.assertNoRemove(source); + } +} diff --git a/src/test/java/ix/CountTest.java b/src/test/java/ix/CountTest.java new file mode 100644 index 0000000..99935ab --- /dev/null +++ b/src/test/java/ix/CountTest.java @@ -0,0 +1,77 @@ +/* + * Copyright 2011-2016 David Karnok + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ix; + +import org.junit.Test; + +public class CountTest { + + @Test + public void normal() { + Ix source = Ix.range(1, 5).count(); + + IxTestHelper.assertValues(source, 5); + + IxTestHelper.assertNoRemove(source); + } + + @Test + public void just() { + Ix source = Ix.just(1).count(); + + IxTestHelper.assertValues(source, 1); + + IxTestHelper.assertNoRemove(source); + } + + @Test + public void empty() { + Ix source = Ix.empty().count(); + + IxTestHelper.assertValues(source, 0); + + IxTestHelper.assertNoRemove(source); + } + + @Test + public void normalLong() { + Ix source = Ix.range(1, 5).countLong(); + + IxTestHelper.assertValues(source, 5L); + + IxTestHelper.assertNoRemove(source); + } + + @Test + public void justLong() { + Ix source = Ix.just(1).countLong(); + + IxTestHelper.assertValues(source, 1L); + + IxTestHelper.assertNoRemove(source); + } + + @Test + public void emptyLong() { + Ix source = Ix.empty().countLong(); + + IxTestHelper.assertValues(source, 0L); + + IxTestHelper.assertNoRemove(source); + } + +} diff --git a/src/test/java/ix/DistinctTest.java b/src/test/java/ix/DistinctTest.java new file mode 100644 index 0000000..070d9be --- /dev/null +++ b/src/test/java/ix/DistinctTest.java @@ -0,0 +1,50 @@ +/* + * Copyright 2011-2016 David Karnok + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ix; + +import org.junit.Test; + +import rx.functions.Func1; + +public class DistinctTest { + + @Test + public void normal() { + Ix source = Ix.fromArray(1, 2, 2, 1, 3, 4, 2).distinct(); + + IxTestHelper.assertValues(source, 1, 2, 3, 4); + } + + @Test + public void empty() { + Ix source = Ix.empty().distinct(); + + IxTestHelper.assertValues(source); + } + + @Test + public void normalSelector() { + Ix source = Ix.fromArray(1, 2, 2, 1, 3, 4, 2).distinct(new Func1() { + @Override + public Object call(Integer v) { + return v & 1; + } + }); + + IxTestHelper.assertValues(source, 1, 2); + } +} diff --git a/src/test/java/ix/DistinctUntilChangedTest.java b/src/test/java/ix/DistinctUntilChangedTest.java new file mode 100644 index 0000000..324c97a --- /dev/null +++ b/src/test/java/ix/DistinctUntilChangedTest.java @@ -0,0 +1,71 @@ +/* + * Copyright 2011-2016 David Karnok + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ix; + +import org.junit.Test; + +import rx.functions.Func1; + +public class DistinctUntilChangedTest { + + @Test + public void normal() { + Ix source = Ix.fromArray(1, 2, 2, 1, 3, 1, 1, 4, 4).distinctUntilChanged(); + + IxTestHelper.assertValues(source, 1, 2, 1, 3, 1, 4); + + IxTestHelper.assertNoRemove(source); + } + + @Test + public void normalComparer() { + Ix source = Ix.fromArray(1, 2, 2, 1, 3, 1, 1, 4, 4).distinctUntilChanged(new Pred2() { + @Override + public boolean test(Integer a, Integer b) { + return (a & 1) == (b & 1); + } + }); + + IxTestHelper.assertValues(source, 1, 2, 1, 4); + + IxTestHelper.assertNoRemove(source); + } + + @Test + public void normalSelector() { + Ix source = Ix.fromArray(1, 2, 2, 1, 3, 1, 1, 4, 4) + .distinctUntilChanged(new Func1() { + @Override + public Object call(Integer v) { + return v & 1; + } + }); + + IxTestHelper.assertValues(source, 1, 2, 1, 4); + + IxTestHelper.assertNoRemove(source); + } + + @Test + public void empty() { + Ix source = Ix.empty().distinctUntilChanged(); + + IxTestHelper.assertValues(source); + + IxTestHelper.assertNoRemove(source); + } +} diff --git a/src/test/java/ix/DoOnTest.java b/src/test/java/ix/DoOnTest.java new file mode 100644 index 0000000..fc6860e --- /dev/null +++ b/src/test/java/ix/DoOnTest.java @@ -0,0 +1,68 @@ +/* + * Copyright 2011-2016 David Karnok + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ix; + +import java.util.*; + +import org.junit.*; + +import rx.functions.*; + +public class DoOnTest { + + @Test + public void normal() { + final List values = new ArrayList(); + Ix source = Ix.range(1, 5) + .doOnNext(new Action1() { + @Override + public void call(Integer v) { + values.add(v); + } + }) + .doOnCompleted(new Action0() { + @Override + public void call() { + values.add(100); + } + }) + ; + IxTestHelper.assertValues(source, 1, 2, 3, 4, 5); + Assert.assertEquals(Arrays.asList(1, 2, 3, 4, 5, 100), values); + } + + @Test + public void empty() { + final List values = new ArrayList(); + Ix source = Ix.empty() + .doOnNext(new Action1() { + @Override + public void call(Integer v) { + values.add(v); + } + }) + .doOnCompleted(new Action0() { + @Override + public void call() { + values.add(100); + } + }) + ; + IxTestHelper.assertValues(source); + Assert.assertEquals(Arrays.asList(100), values); + } +} diff --git a/src/test/java/ix/EmptyActionTest.java b/src/test/java/ix/EmptyActionTest.java new file mode 100644 index 0000000..534350f --- /dev/null +++ b/src/test/java/ix/EmptyActionTest.java @@ -0,0 +1,31 @@ +/* + * Copyright 2011-2016 David Karnok + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ix; + +import org.junit.Test; + +import static org.junit.Assert.*; + +public class EmptyActionTest { + + @Test + public void normal() { + assertNotNull(IxEmptyAction.valueOf("INSTANCE")); + + assertEquals(1, IxEmptyAction.values().length); + } +} diff --git a/src/test/java/ix/EqualityHelperTest.java b/src/test/java/ix/EqualityHelperTest.java new file mode 100644 index 0000000..d3ae6fd --- /dev/null +++ b/src/test/java/ix/EqualityHelperTest.java @@ -0,0 +1,39 @@ +/* + * Copyright 2011-2016 David Karnok + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ix; + +import org.junit.Test; + +import static org.junit.Assert.*; +import static ix.EqualityHelper.INSTANCE; + +public class EqualityHelperTest { + + @Test + public void normal() { + assertTrue(INSTANCE.test(1, 1)); + assertTrue(INSTANCE.test(1, new Integer(1))); + + assertFalse(INSTANCE.test(null, 1)); + assertFalse(INSTANCE.test(1, null)); + assertFalse(INSTANCE.test(1, 2)); + + assertNotNull(EqualityHelper.valueOf("INSTANCE")); + + assertEquals(1, EqualityHelper.values().length); + } +} diff --git a/src/test/java/ix/HasElementsTest.java b/src/test/java/ix/HasElementsTest.java new file mode 100644 index 0000000..18afdca --- /dev/null +++ b/src/test/java/ix/HasElementsTest.java @@ -0,0 +1,37 @@ +/* + * Copyright 2011-2016 David Karnok + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ix; + +import org.junit.Test; + +public class HasElementsTest { + + @Test + public void empty() { + Ix source = Ix.empty().hasElements(); + + IxTestHelper.assertValues(source, false); + } + + @Test + public void nonempty() { + Ix source = Ix.just(1).hasElements(); + + IxTestHelper.assertValues(source, true); + } + +} diff --git a/src/test/java/ix/IgnoreElementsTest.java b/src/test/java/ix/IgnoreElementsTest.java new file mode 100644 index 0000000..786186f --- /dev/null +++ b/src/test/java/ix/IgnoreElementsTest.java @@ -0,0 +1,41 @@ +/* + * Copyright 2011-2016 David Karnok + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ix; + +import org.junit.Test; + +public class IgnoreElementsTest { + + @Test + public void range() { + Ix source = Ix.range(1, 5).ignoreElements(); + + IxTestHelper.assertValues(source); + + IxTestHelper.assertNoRemove(source); + } + + @Test + public void empty() { + Ix source = Ix.empty().ignoreElements(); + + IxTestHelper.assertValues(source); + + IxTestHelper.assertNoRemove(source); + } + +} diff --git a/src/test/java/ix/JoinTest.java b/src/test/java/ix/JoinTest.java new file mode 100644 index 0000000..aa97e0d --- /dev/null +++ b/src/test/java/ix/JoinTest.java @@ -0,0 +1,77 @@ +/* + * Copyright 2011-2016 David Karnok + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ix; + +import org.junit.Test; + +public class JoinTest { + + @Test + public void normal() { + Ix source = Ix.range(1, 5).join(); + + IxTestHelper.assertValues(source, "1, 2, 3, 4, 5"); + + IxTestHelper.assertNoRemove(source); + } + + @Test + public void just() { + Ix source = Ix.just(1).join(); + + IxTestHelper.assertValues(source, "1"); + + IxTestHelper.assertNoRemove(source); + } + + @Test + public void empty() { + Ix source = Ix.empty().join(); + + IxTestHelper.assertValues(source, ""); + + IxTestHelper.assertNoRemove(source); + } + + @Test + public void normalSeparator() { + Ix source = Ix.range(1, 5).join("|"); + + IxTestHelper.assertValues(source, "1|2|3|4|5"); + + IxTestHelper.assertNoRemove(source); + } + + @Test + public void justSeparator() { + Ix source = Ix.just(1).join("|"); + + IxTestHelper.assertValues(source, "1"); + + IxTestHelper.assertNoRemove(source); + } + + @Test + public void emptySeparator() { + Ix source = Ix.empty().join("|"); + + IxTestHelper.assertValues(source, ""); + + IxTestHelper.assertNoRemove(source); + } + +} diff --git a/src/test/java/ix/MinMaxTest.java b/src/test/java/ix/MinMaxTest.java new file mode 100644 index 0000000..741f8f3 --- /dev/null +++ b/src/test/java/ix/MinMaxTest.java @@ -0,0 +1,138 @@ +/* + * Copyright 2011-2016 David Karnok + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ix; + +import java.util.Comparator; + +import org.junit.Test; + +public class MinMaxTest { + + @Test + public void minComparator() { + Ix source = Ix.range(1, 5).min(new Comparator() { + @Override + public int compare(Integer a, Integer b) { + return b.compareTo(a); + } + }); + + IxTestHelper.assertValues(source, 5); + } + + @Test + public void minComparatorEmpty() { + Ix source = Ix.empty().min(new Comparator() { + @Override + public int compare(Integer a, Integer b) { + return b.compareTo(a); + } + }); + + IxTestHelper.assertValues(source); + } + + @Test + public void minComparatorJust() { + Ix source = Ix.just(1).min(new Comparator() { + @Override + public int compare(Integer a, Integer b) { + return b.compareTo(a); + } + }); + + IxTestHelper.assertValues(source, 1); + } + + @Test + public void maxComparator() { + Ix source = Ix.range(1, 5).max(new Comparator() { + @Override + public int compare(Integer a, Integer b) { + return b.compareTo(a); + } + }); + + IxTestHelper.assertValues(source, 1); + } + + @Test + public void maxComparatorEmpty() { + Ix source = Ix.empty().max(new Comparator() { + @Override + public int compare(Integer a, Integer b) { + return b.compareTo(a); + } + }); + + IxTestHelper.assertValues(source); + } + + @Test + public void maxComparatorJust() { + Ix source = Ix.just(1).max(new Comparator() { + @Override + public int compare(Integer a, Integer b) { + return b.compareTo(a); + } + }); + + IxTestHelper.assertValues(source, 1); + } + + @Test + public void min() { + Ix source = Ix.range(1, 5).min(); + + IxTestHelper.assertValues(source, 1); + } + + @Test + public void minEmpty() { + Ix source = Ix.empty().min(); + + IxTestHelper.assertValues(source); + } + + @Test + public void minJust() { + Ix source = Ix.just(1).min(); + + IxTestHelper.assertValues(source, 1); + } + + @Test + public void max() { + Ix source = Ix.range(1, 5).max(); + + IxTestHelper.assertValues(source, 5); + } + + @Test + public void maxEmpty() { + Ix source = Ix.empty().max(); + + IxTestHelper.assertValues(source); + } + + @Test + public void maxJust() { + Ix source = Ix.just(1).max(); + + IxTestHelper.assertValues(source, 1); + } +} diff --git a/src/test/java/ix/SelfComparatorTest.java b/src/test/java/ix/SelfComparatorTest.java new file mode 100644 index 0000000..b23c801 --- /dev/null +++ b/src/test/java/ix/SelfComparatorTest.java @@ -0,0 +1,39 @@ +/* + * Copyright 2011-2016 David Karnok + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ix; + +import org.junit.Test; + +import static org.junit.Assert.*; +import static ix.SelfComparator.INSTANCE; + +public class SelfComparatorTest { + + @Test + public void normal() { + assertEquals(0, INSTANCE.compare(1, 1)); + assertEquals(0, INSTANCE.compare(1, new Integer(1))); + + assertTrue(INSTANCE.compare(1, 2) < 0); + + assertTrue(INSTANCE.compare(2, 1) > 0); + + assertNotNull(SelfComparator.valueOf("INSTANCE")); + + assertEquals(1, SelfComparator.values().length); + } +} From 73eea4c5674637eeda3d9af82c011c692d2c6eea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?D=C3=A1vid=20Karnok?= Date: Wed, 13 Jul 2016 22:20:32 +0200 Subject: [PATCH 20/66] More operators, improve coverage --- README.md | 9 +- src/main/java/ix/Ix.java | 38 +- src/main/java/ix/IxBuffer.java | 70 +++ src/main/java/ix/IxBufferOverlap.java | 96 ++++ src/main/java/ix/IxBufferSkip.java | 90 ++++ src/main/java/ix/IxDoOn.java | 16 + src/main/java/ix/IxRepeatPredicate.java | 15 +- src/main/java/ix/IxSourceQueuedIterator.java | 27 ++ src/test/java/ix/BufferTest.java | 162 +++++++ src/test/java/ix/ForeachTest.java | 13 + src/test/java/ix/LeavingTest.java | 414 ++++++++++++++++++ src/test/java/ix/RepeatTest.java | 126 +++++- .../java/ix/SourceQueuedIteratorTest.java | 18 + src/test/java/ix/Zip2Test.java | 8 + 14 files changed, 1076 insertions(+), 26 deletions(-) create mode 100644 src/main/java/ix/IxBuffer.java create mode 100644 src/main/java/ix/IxBufferOverlap.java create mode 100644 src/main/java/ix/IxBufferSkip.java create mode 100644 src/test/java/ix/BufferTest.java create mode 100644 src/test/java/ix/LeavingTest.java diff --git a/README.md b/README.md index cfaba77..b282b82 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,10 @@ ixjava ================= + +[![codecov.io](http://codecov.io/github/akarnokd/ixjava/coverage.svg?branch=1.x)](http://codecov.io/github/akarnokd/ixjava?branch=1.x) +[![Maven Central](https://maven-badges.herokuapp.com/maven-central/com.github.akarnokd/ixjava/badge.svg)](https://maven-badges.herokuapp.com/maven-central/com.github.akarnokd/ixjava) + Interactive Extensions for Java, the dual of RxJava. Originally implemented in the Reactive4Java framework, now converted to work with RxJava. The aim is to provide pull-based datastream support with the same naming as in RxJava mainly for the pre-Java-8 world. The Stream API in Java 8 is not exactly the same thing because Streams can be only consumed once while Iterables can be consumed many times. Google Guava features a lot of Iterable operators but without method chaining support. @@ -10,11 +14,6 @@ and interactive dataflows.** # Releases - -[![codecov.io](http://codecov.io/github/akarnokd/ixjava/coverage.svg?branch=1.x)](http://codecov.io/github/akarnokd/ixjava?branch=1.x) -[![Maven Central](https://maven-badges.herokuapp.com/maven-central/com.github.akarnokd/ixjava/badge.svg)](https://maven-badges.herokuapp.com/maven-central/com.github.akarnokd/ixjava) - - **gradle** ``` diff --git a/src/main/java/ix/Ix.java b/src/main/java/ix/Ix.java index 517d4c8..067f7f4 100644 --- a/src/main/java/ix/Ix.java +++ b/src/main/java/ix/Ix.java @@ -170,9 +170,13 @@ public static Ix repeatValue(T value, long count) { } public static Ix repeatValue(T value, Pred0 stopPredicate) { - return new IxRepeatPredicate(value, stopPredicate); + return repeatValue(value, Long.MAX_VALUE, stopPredicate); } - + + public static Ix repeatValue(T value, long count, Pred0 stopPredicate) { + return new IxRepeatPredicate(value, count, stopPredicate); + } + public static Ix forloop(T seed, Pred condition, Func1 next, Func1 selector) { @@ -395,18 +399,21 @@ public final Ix takeUntil(Pred stopPredicate) { } public final Ix> buffer(int size) { - // TODO implement - throw new UnsupportedOperationException(); + return new IxBuffer(this, size); } public final Ix> buffer(int size, int skip) { - // TODO implement - throw new UnsupportedOperationException(); + if (size == skip) { + return buffer(size); + } + if (size < skip) { + return new IxBufferSkip(this, size, skip); + } + return new IxBufferOverlap(this, size, skip); } public final Ix> groupBy(Func1 keySelector) { - // TODO implement - throw new UnsupportedOperationException(); + return groupBy(keySelector, IdentityHelper.instance()); } public final Ix> groupBy(Func1 keySelector, @@ -416,23 +423,19 @@ public final Ix> groupBy(Func1 ke } public final Ix repeat() { - // TODO implement - throw new UnsupportedOperationException(); + return concat(repeatValue(this)); } public final Ix repeat(long times) { - // TODO implement - throw new UnsupportedOperationException(); + return concat(repeatValue(this, times)); } public final Ix repeat(Pred0 predicate) { - // TODO implement - throw new UnsupportedOperationException(); + return concat(repeatValue(this, predicate)); } public final Ix repeat(long times, Pred0 predicate) { - // TODO implement - throw new UnsupportedOperationException(); + return concat(repeatValue(this, times, predicate)); } public final Ix publish() { @@ -659,6 +662,9 @@ public final void print(CharSequence separator, int charsPerLine) { System.out.println();; System.out.print(s); len = s.length(); + } else { + System.out.print(s); + len += s.length(); } } diff --git a/src/main/java/ix/IxBuffer.java b/src/main/java/ix/IxBuffer.java new file mode 100644 index 0000000..cb0ee10 --- /dev/null +++ b/src/main/java/ix/IxBuffer.java @@ -0,0 +1,70 @@ +/* + * Copyright 2011-2016 David Karnok + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ix; + +import java.util.*; + +final class IxBuffer extends IxSource> { + + final int size; + + public IxBuffer(Iterable source, int size) { + super(source); + this.size = size; + } + + @Override + public Iterator> iterator() { + return new BufferIterator(source.iterator(), size); + } + + static final class BufferIterator extends IxSourceIterator> { + final int size; + + public BufferIterator(Iterator it, int size) { + super(it); + this.size = size; + } + + @Override + protected boolean moveNext() { + int s = size; + + Iterator it = this.it; + + List list = new ArrayList(); + + while (s != 0 && it.hasNext()) { + list.add(it.next()); + s--; + } + + if (list.isEmpty()) { + done = true; + return false; + } + value = list; + hasValue = true; + if (s != 0) { + done = true; + } + return true; + } + + + } +} diff --git a/src/main/java/ix/IxBufferOverlap.java b/src/main/java/ix/IxBufferOverlap.java new file mode 100644 index 0000000..ebbc07e --- /dev/null +++ b/src/main/java/ix/IxBufferOverlap.java @@ -0,0 +1,96 @@ +/* + * Copyright 2011-2016 David Karnok + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ix; + +import java.util.*; + +import rx.functions.Action2; + +final class IxBufferOverlap extends IxSource> { + + final int size; + + final int skip; + + public IxBufferOverlap(Iterable source, int size, int skip) { + super(source); + this.size = size; + this.skip = skip; + } + + @Override + public Iterator> iterator() { + return new BufferIterator(source.iterator(), size, skip); + } + + static final class BufferIterator extends IxSourceQueuedIterator, List> + implements Action2, T> { + final int size; + + final int skip; + + int index; + + public BufferIterator(Iterator it, int size, int skip) { + super(it); + this.size = size; + this.skip = skip; + } + + @SuppressWarnings("unchecked") + @Override + protected boolean moveNext() { + Iterator it = this.it; + + int s = size; + int k = skip; + + int i = index; + + while (it.hasNext()) { + if (i == 0) { + offer(new ArrayList()); + } + T v = it.next(); + foreach(this, v); + if (++i == k) { + i = 0; + } + + if (((List)peek()).size() == s) { + break; + } + } + index = i; + + List list = fromObject(poll()); + if (list == null) { + done = true; + return false; + } + + value = list; + hasValue = true; + return true; + } + + @Override + public void call(List t1, T t2) { + t1.add(t2); + } + } +} diff --git a/src/main/java/ix/IxBufferSkip.java b/src/main/java/ix/IxBufferSkip.java new file mode 100644 index 0000000..e275be1 --- /dev/null +++ b/src/main/java/ix/IxBufferSkip.java @@ -0,0 +1,90 @@ +/* + * Copyright 2011-2016 David Karnok + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ix; + +import java.util.*; + +final class IxBufferSkip extends IxSource> { + + final int size; + + final int skip; + + public IxBufferSkip(Iterable source, int size, int skip) { + super(source); + this.size = size; + this.skip = skip; + } + + @Override + public Iterator> iterator() { + return new BufferSkipIterator(source.iterator(), size, skip); + } + + static final class BufferSkipIterator extends IxSourceIterator> { + final int size; + + final int skip; + + boolean once; + + public BufferSkipIterator(Iterator it, int size, int skip) { + super(it); + this.size = size; + this.skip = skip; + } + + @Override + protected boolean moveNext() { + Iterator it = this.it; + + int s = size; + + if (once) { + int k = skip - s; + while (k != 0 && it.hasNext()) { + it.next(); + k--; + } + + } else { + once = true; + } + + List list = new ArrayList(); + + while (s != 0 && it.hasNext()) { + list.add(it.next()); + s--; + } + + + if (list.isEmpty()) { + done = true; + return false; + } + value = list; + hasValue = true; + if (s != 0) { + done = true; + } + return true; + } + + + } +} diff --git a/src/main/java/ix/IxDoOn.java b/src/main/java/ix/IxDoOn.java index 68e430b..d4c74b9 100644 --- a/src/main/java/ix/IxDoOn.java +++ b/src/main/java/ix/IxDoOn.java @@ -1,3 +1,19 @@ +/* + * Copyright 2011-2016 David Karnok + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package ix; import java.util.Iterator; diff --git a/src/main/java/ix/IxRepeatPredicate.java b/src/main/java/ix/IxRepeatPredicate.java index 957df9d..c6780e0 100644 --- a/src/main/java/ix/IxRepeatPredicate.java +++ b/src/main/java/ix/IxRepeatPredicate.java @@ -22,32 +22,39 @@ final class IxRepeatPredicate extends Ix { final T value; + final long count; + final Pred0 stopPredicate; - public IxRepeatPredicate(T value, Pred0 stopPredicate) { + public IxRepeatPredicate(T value, long count, Pred0 stopPredicate) { this.value = value; this.stopPredicate = stopPredicate; + this.count = count; } @Override public Iterator iterator() { - return new RepeatPredicateIterator(value, stopPredicate); + return new RepeatPredicateIterator(value, count, stopPredicate); } static final class RepeatPredicateIterator extends IxBaseIterator { final T valueToRepeat; + long count; + final Pred0 stopPredicate; - public RepeatPredicateIterator(T value, Pred0 stopPredicate) { + public RepeatPredicateIterator(T value, long count, Pred0 stopPredicate) { this.valueToRepeat = value; this.stopPredicate = stopPredicate; + this.count = count; } @Override protected boolean moveNext() { - if (!stopPredicate.getAsBoolean()) { + long c = count--; + if (c != 0L && !stopPredicate.getAsBoolean()) { value = valueToRepeat; hasValue = true; return true; diff --git a/src/main/java/ix/IxSourceQueuedIterator.java b/src/main/java/ix/IxSourceQueuedIterator.java index fd16f35..05e10e7 100644 --- a/src/main/java/ix/IxSourceQueuedIterator.java +++ b/src/main/java/ix/IxSourceQueuedIterator.java @@ -18,6 +18,8 @@ import java.util.Iterator; +import rx.functions.*; + /** * A base iterator that extends a custom ArrayDeque, references an upstream iterator * and manages the state between hasNext() and the next() calls; plus defines @@ -109,6 +111,18 @@ protected final Object poll() { return null; } + protected final Object peek() { + Object[] a = array; + if (a != null) { + int m = a.length - 1; + int ci = consumerIndex; + int offset = ci & m; + + return a[offset]; + } + return null; + } + protected final boolean isEmpty() { return consumerIndex == producerIndex; } @@ -118,4 +132,17 @@ protected final void clear() { consumerIndex = 0; producerIndex = 0; } + + protected final void foreach(Action2 action, S state) { + Object[] a = array; + if (a != null) { + int m = a.length - 1; + int pi = producerIndex; + for (int ci = consumerIndex; ci != pi; ci++) { + int offset = ci & m; + Object o = a[offset]; + action.call(fromObject(o), state); + } + } + } } diff --git a/src/test/java/ix/BufferTest.java b/src/test/java/ix/BufferTest.java new file mode 100644 index 0000000..9a2d28d --- /dev/null +++ b/src/test/java/ix/BufferTest.java @@ -0,0 +1,162 @@ +/* + * Copyright 2011-2016 David Karnok + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ix; + +import java.util.*; + +import org.junit.Test; + +public class BufferTest { + + @SuppressWarnings("unchecked") + @Test + public void normal() { + Ix> source = Ix.range(1, 5).buffer(2); + + IxTestHelper.assertValues(source, Arrays.asList(1, 2), Arrays.asList(3, 4), Arrays.asList(5)); + + IxTestHelper.assertNoRemove(source); + } + + @SuppressWarnings("unchecked") + @Test + public void normalExactLength() { + Ix> source = Ix.range(1, 6).buffer(2); + + IxTestHelper.assertValues(source, Arrays.asList(1, 2), Arrays.asList(3, 4), Arrays.asList(5, 6)); + + IxTestHelper.assertNoRemove(source); + } + + @SuppressWarnings("unchecked") + @Test + public void normalSameSkip() { + Ix> source = Ix.range(1, 5).buffer(2, 2); + + IxTestHelper.assertValues(source, Arrays.asList(1, 2), Arrays.asList(3, 4), Arrays.asList(5)); + + IxTestHelper.assertNoRemove(source); + } + + @SuppressWarnings("unchecked") + @Test + public void normalSameSkipExactLength() { + Ix> source = Ix.range(1, 6).buffer(2, 2); + + IxTestHelper.assertValues(source, Arrays.asList(1, 2), Arrays.asList(3, 4), Arrays.asList(5, 6)); + + IxTestHelper.assertNoRemove(source); + } + + @SuppressWarnings("unchecked") + @Test + public void normalSkip() { + Ix> source = Ix.range(1, 5).buffer(2, 3); + + IxTestHelper.assertValues(source, Arrays.asList(1, 2), Arrays.asList(4, 5)); + + IxTestHelper.assertNoRemove(source); + } + + @SuppressWarnings("unchecked") + @Test + public void normalSkipShorter() { + Ix> source = Ix.range(1, 4).buffer(2, 3); + + IxTestHelper.assertValues(source, Arrays.asList(1, 2), Arrays.asList(4)); + + IxTestHelper.assertNoRemove(source); + } + + @SuppressWarnings("unchecked") + @Test + public void normalSkipShortest() { + Ix> source = Ix.range(1, 3).buffer(2, 3); + + IxTestHelper.assertValues(source, Arrays.asList(1, 2)); + + IxTestHelper.assertNoRemove(source); + } + + @SuppressWarnings("unchecked") + @Test + public void normalOverlap() { + Ix> source = Ix.range(1, 5).buffer(2, 1); + + IxTestHelper.assertValues(source, + Arrays.asList(1, 2), + Arrays.asList(2, 3), + Arrays.asList(3, 4), + Arrays.asList(4, 5), + Arrays.asList(5)); + + IxTestHelper.assertNoRemove(source); + } + + @SuppressWarnings("unchecked") + @Test + public void normalOverlapLonger() { + Ix> source = Ix.range(1, 10).buffer(3, 1); + + IxTestHelper.assertValues(source, + Arrays.asList(1, 2, 3), + Arrays.asList(2, 3, 4), + Arrays.asList(3, 4, 5), + Arrays.asList(4, 5, 6), + Arrays.asList(5, 6, 7), + Arrays.asList(6, 7, 8), + Arrays.asList(7, 8, 9), + Arrays.asList(8, 9, 10), + Arrays.asList(9, 10), + Arrays.asList(10) + ); + + IxTestHelper.assertNoRemove(source); + } + + @SuppressWarnings("unchecked") + @Test + public void normalOverlapSorter() { + Ix> source = Ix.range(1, 2).buffer(3, 2); + + IxTestHelper.assertValues(source, + Arrays.asList(1, 2) + ); + + IxTestHelper.assertNoRemove(source); + } + + @SuppressWarnings("unchecked") + @Test + public void normalOverlapEmpty() { + Ix> source = Ix.empty().buffer(3, 2); + + IxTestHelper.assertValues(source); + + IxTestHelper.assertNoRemove(source); + } + + @SuppressWarnings("unchecked") + @Test + public void normalOverlapJust() { + Ix> source = Ix.just(1).buffer(3, 2); + + IxTestHelper.assertValues(source, Arrays.asList(1)); + + IxTestHelper.assertNoRemove(source); + } +} diff --git a/src/test/java/ix/ForeachTest.java b/src/test/java/ix/ForeachTest.java index 51943c2..d71dac5 100644 --- a/src/test/java/ix/ForeachTest.java +++ b/src/test/java/ix/ForeachTest.java @@ -60,4 +60,17 @@ public void normalWhile() { Assert.assertEquals(Arrays.asList(1, 2, 3, 4, 5), list); } + @Test + public void normalWhileAll() { + Ix source = Ix.range(1, 5); + + source.foreachWhile(new Pred() { + @Override + public boolean test(Integer v) { + return true; + } + }); + + IxTestHelper.assertValues(source, 1, 2, 3, 4, 5); + } } diff --git a/src/test/java/ix/LeavingTest.java b/src/test/java/ix/LeavingTest.java new file mode 100644 index 0000000..79c2290 --- /dev/null +++ b/src/test/java/ix/LeavingTest.java @@ -0,0 +1,414 @@ +/* + * Copyright 2011-2016 David Karnok + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ix; + +import java.io.*; +import java.util.*; + +import org.junit.*; + +import rx.functions.*; +import rx.observers.TestSubscriber; + +public class LeavingTest { + + @Test + public void normal() { + List list = new ArrayList(); + + Ix.range(1, 5).into(list); + + Assert.assertEquals(Arrays.asList(1, 2, 3, 4, 5), list); + } + + @Test + public void print() throws Exception { + PrintStream old = System.out; + ByteArrayOutputStream bout = new ByteArrayOutputStream(); + System.setOut(new PrintStream(bout)); + try { + Ix.range(1, 30).print(); + + System.out.flush(); + } finally { + System.setOut(old); + } + + String[] s = bout.toString("UTF-8").split(System.getProperty("line.separator")); + + Assert.assertEquals(Ix.range(1, 23).join().first() + ", ", s[0]); + Assert.assertEquals(Ix.range(24, 7).join().first(), s[1]); + } + + @Test + public void print40() throws Exception { + PrintStream old = System.out; + ByteArrayOutputStream bout = new ByteArrayOutputStream(); + System.setOut(new PrintStream(bout)); + try { + Ix.range(1, 30).print(",", 40); + + System.out.flush(); + } finally { + System.setOut(old); + } + + String[] s = bout.toString("UTF-8").split(System.getProperty("line.separator")); + + Assert.assertEquals(Ix.range(1, 17).join(",").first() + ",", s[0]); + Assert.assertEquals(Ix.range(18, 13).join(",").first(), s[1]); + } + + @Test + public void println() throws Exception { + PrintStream old = System.out; + ByteArrayOutputStream bout = new ByteArrayOutputStream(); + System.setOut(new PrintStream(bout)); + try { + Ix.range(1, 3).println(); + + System.out.flush(); + } finally { + System.setOut(old); + } + + String[] s = bout.toString("UTF-8").split(System.getProperty("line.separator")); + + Assert.assertEquals("1", s[0]); + Assert.assertEquals("2", s[1]); + Assert.assertEquals("3", s[2]); + } + + @Test + public void printlnPrefix() throws Exception { + PrintStream old = System.out; + ByteArrayOutputStream bout = new ByteArrayOutputStream(); + System.setOut(new PrintStream(bout)); + try { + Ix.range(1, 3).println("--"); + + System.out.flush(); + } finally { + System.setOut(old); + } + + String[] s = bout.toString("UTF-8").split(System.getProperty("line.separator")); + + Assert.assertEquals("--1", s[0]); + Assert.assertEquals("--2", s[1]); + Assert.assertEquals("--3", s[2]); + } + + @Test + public void run() { + final List list = new ArrayList(); + + Ix.range(1, 5).doOnNext(new Action1() { + @Override + public void call(Integer v) { + list.add(v); + } + }).run(); + + Assert.assertEquals(Arrays.asList(1, 2, 3, 4, 5), list); + } + + @Test + public void subscribe() { + final List list = new ArrayList(); + + Ix.range(1, 5).doOnNext(new Action1() { + @Override + public void call(Integer v) { + list.add(v); + } + }).subscribe(); + + Assert.assertEquals(Arrays.asList(1, 2, 3, 4, 5), list); + } + + @Test + public void subscribeAction1() { + final List list = new ArrayList(); + + Ix.range(1, 5).subscribe(new Action1() { + @Override + public void call(Integer v) { + list.add(v); + } + }); + + Assert.assertEquals(Arrays.asList(1, 2, 3, 4, 5), list); + } + + @Test + public void subscribeAction1Action1() { + final List list = new ArrayList(); + + Ix.range(1, 5).subscribe(new Action1() { + @Override + public void call(Integer v) { + list.add(v); + } + }, new Action1() { + @Override + public void call(Throwable t) { + + } + }); + + Assert.assertEquals(Arrays.asList(1, 2, 3, 4, 5), list); + } + + @Test + public void subscribeAction1Action1Throws() { + final List list = new ArrayList(); + + final Throwable[] error = { null }; + + Ix.range(1, 5).subscribe(new Action1() { + @Override + public void call(Integer v) { + if (v == 5) { + throw new IllegalStateException(); + } + list.add(v); + } + }, new Action1() { + @Override + public void call(Throwable t) { + error[0] = t; + } + }); + + Assert.assertEquals(Arrays.asList(1, 2, 3, 4), list); + Assert.assertTrue(String.valueOf(error[0]), error[0] instanceof IllegalStateException); + } + + @Test + public void subscribeAction1Action1Action0() { + final List list = new ArrayList(); + + Ix.range(1, 5).subscribe(new Action1() { + @Override + public void call(Integer v) { + list.add(v); + } + }, new Action1() { + @Override + public void call(Throwable t) { + + } + }, new Action0() { + @Override + public void call() { + list.add(100); + } + }); + + Assert.assertEquals(Arrays.asList(1, 2, 3, 4, 5, 100), list); + } + + @Test + public void subscribeAction1Action1Action0Throws() { + final List list = new ArrayList(); + + final Throwable[] error = { null }; + + Ix.range(1, 5).subscribe(new Action1() { + @Override + public void call(Integer v) { + if (v == 5) { + throw new IllegalStateException(); + } + list.add(v); + } + }, new Action1() { + @Override + public void call(Throwable t) { + error[0] = t; + } + }, new Action0() { + @Override + public void call() { + list.add(100); + } + }); + + Assert.assertEquals(Arrays.asList(1, 2, 3, 4), list); + Assert.assertTrue(String.valueOf(error[0]), error[0] instanceof IllegalStateException); + } + + @Test + public void subscribeObserver() { + TestSubscriber ts = new TestSubscriber(); + Ix.range(1, 5).subscribe((rx.Observer)ts); + + ts.assertValues(1, 2, 3, 4, 5); + ts.assertNoErrors(); + ts.assertCompleted(); + } + + @Test + public void subscribeObserverThrows() { + TestSubscriber ts = new TestSubscriber(); + Ix.range(1, 5) + .doOnNext(new Action1() { + @Override + public void call(Integer v) { + if (v == 5) { + throw new IllegalStateException(); + } + } + }) + .subscribe((rx.Observer)ts); + + ts.assertValues(1, 2, 3, 4); + ts.assertError(IllegalStateException.class); + ts.assertNotCompleted(); + } + + @Test + public void subscribeSubscriber() { + TestSubscriber ts = new TestSubscriber(); + Ix.range(1, 5).subscribe(ts); + + ts.assertValues(1, 2, 3, 4, 5); + ts.assertNoErrors(); + ts.assertCompleted(); + } + + @Test + public void subscribeSubscriberTakeLess() { + TestSubscriber ts = new TestSubscriber() { + @Override + public void onNext(Integer t) { + super.onNext(t); + if (t == 4) { + unsubscribe(); + } + } + }; + Ix.range(1, 5).subscribe(ts); + + ts.assertValues(1, 2, 3, 4); + ts.assertNoErrors(); + ts.assertNotCompleted(); + } + + @Test + public void subscribeSubscriberTakeLessAndThrow() { + TestSubscriber ts = new TestSubscriber() { + @Override + public void onNext(Integer t) { + super.onNext(t); + if (t == 4) { + unsubscribe(); + throw new IllegalStateException(); + } + } + }; + Ix.range(1, 5).subscribe(ts); + + ts.assertValues(1, 2, 3, 4); + ts.assertNoErrors(); + ts.assertNotCompleted(); + } + + @Test + public void subscribeSubscriberThrow() { + TestSubscriber ts = new TestSubscriber() { + @Override + public void onNext(Integer t) { + super.onNext(t); + if (t == 4) { + throw new IllegalStateException(); + } + } + }; + Ix.range(1, 5).subscribe(ts); + + ts.assertValues(1, 2, 3, 4); + ts.assertError(IllegalStateException.class); + ts.assertNotCompleted(); + } + + @Test + public void subscribeSubscriberThrows() { + TestSubscriber ts = new TestSubscriber(); + Ix.range(1, 5) + .doOnNext(new Action1() { + @Override + public void call(Integer v) { + if (v == 5) { + throw new IllegalStateException(); + } + } + }) + .subscribe(ts); + + ts.assertValues(1, 2, 3, 4); + ts.assertError(IllegalStateException.class); + ts.assertNotCompleted(); + } + + @Test + public void subscribeSubscriberTakeExact() { + TestSubscriber ts = new TestSubscriber() { + @Override + public void onNext(Integer t) { + super.onNext(t); + if (t == 5) { + unsubscribe(); + } + } + }; + Ix.range(1, 5).subscribe(ts); + + ts.assertValues(1, 2, 3, 4, 5); + ts.assertNoErrors(); + ts.assertNotCompleted(); + } + + @Test + public void retainAll() { + List list = Ix.range(1, 10).toList().first(); + + Ix.from(list).retainAll(new Pred() { + @Override + public boolean test(Integer v) { + return (v & 1) == 0; + } + }); + + Assert.assertEquals(Arrays.asList(2, 4, 6, 8, 10), list); + } + + @Test + public void removeAll() { + List list = Ix.range(1, 10).toList().first(); + + Ix.from(list).removeAll(new Pred() { + @Override + public boolean test(Integer v) { + return (v & 1) == 1; + } + }); + + Assert.assertEquals(Arrays.asList(2, 4, 6, 8, 10), list); + } +} diff --git a/src/test/java/ix/RepeatTest.java b/src/test/java/ix/RepeatTest.java index 8cb62d4..aa61b48 100644 --- a/src/test/java/ix/RepeatTest.java +++ b/src/test/java/ix/RepeatTest.java @@ -112,5 +112,129 @@ public boolean getAsBoolean() { IxTestHelper.assertValues(source, 1, 1, 1, 1, 1); IxTestHelper.assertNoRemove(source); -} + } + + @Test + public void predicateCountedLimited() { + Ix source = Ix.repeatValue(1, 3L, new Pred0() { + int count = 5; + @Override + public boolean getAsBoolean() { + return count-- == 0; + } + }); + + IxTestHelper.assertValues(source, 1, 1, 1); + + IxTestHelper.assertNoRemove(source); + } + + @Test + public void normalInstance() { + Ix source = Ix.just(1).repeat().take(5); + + IxTestHelper.assertValues(source, 1, 1, 1, 1, 1); + + IxTestHelper.assertNoRemove(source); + } + + @Test + public void normalInstanceLimited() { + Ix source = Ix.just(1).repeat(5); + + IxTestHelper.assertValues(source, 1, 1, 1, 1, 1); + + IxTestHelper.assertNoRemove(source); + } + + @Test + public void neverRepeatInstance() { + Ix source = Ix.just(1).repeat(0); + + IxTestHelper.assertValues(source); + + IxTestHelper.assertNoRemove(source); + } + + @Test + public void repeatOnceInstance() { + Ix source = Ix.just(1).repeat(1); + + IxTestHelper.assertValues(source, 1); + + IxTestHelper.assertNoRemove(source); + } + + @Test + public void predicateLimitedInstance() { + Ix source = Ix.just(1).repeat(new Pred0() { + int count = 5; + @Override + public boolean getAsBoolean() { + return count-- == 0; + } + }); + + IxTestHelper.assertValues(source, 1, 1, 1, 1, 1); + + IxTestHelper.assertNoRemove(source); + } + + @Test + public void predicateNeverRepeatInstance() { + Ix source = Ix.just(1).repeat(new Pred0() { + @Override + public boolean getAsBoolean() { + return true; + } + }); + + IxTestHelper.assertValues(source); + + IxTestHelper.assertNoRemove(source); + } + + @Test + public void predicateRepeatOnceInstance() { + Ix source = Ix.just(1).repeat(new Pred0() { + int count = 1; + @Override + public boolean getAsBoolean() { + return count-- == 0; + } + }); + + IxTestHelper.assertValues(source, 1); + + IxTestHelper.assertNoRemove(source); + } + + @Test + public void predicateInfiniteInstance() { + Ix source = Ix.just(1).repeat(new Pred0() { + @Override + public boolean getAsBoolean() { + return false; + } + }).take(5); + + IxTestHelper.assertValues(source, 1, 1, 1, 1, 1); + + IxTestHelper.assertNoRemove(source); + } + + @Test + public void predicateCountedLimitedInstance() { + Ix source = Ix.just(1).repeat(3L, new Pred0() { + int count = 5; + @Override + public boolean getAsBoolean() { + return count-- == 0; + } + }); + + IxTestHelper.assertValues(source, 1, 1, 1); + + IxTestHelper.assertNoRemove(source); + } } diff --git a/src/test/java/ix/SourceQueuedIteratorTest.java b/src/test/java/ix/SourceQueuedIteratorTest.java index c3b1d84..a1ab17f 100644 --- a/src/test/java/ix/SourceQueuedIteratorTest.java +++ b/src/test/java/ix/SourceQueuedIteratorTest.java @@ -18,6 +18,8 @@ import org.junit.*; +import rx.functions.Action2; + public class SourceQueuedIteratorTest { IxSourceQueuedIterator it; @@ -36,13 +38,16 @@ protected boolean moveNext() { @Test public void normal() { Assert.assertTrue(it.isEmpty()); + Assert.assertEquals(null, it.peek()); it.offer(1); Assert.assertFalse(it.isEmpty()); + Assert.assertEquals(1, it.peek()); Assert.assertEquals(1, it.poll()); Assert.assertTrue(it.isEmpty()); + Assert.assertEquals(null, it.peek()); Assert.assertNull(it.poll()); Assert.assertTrue(it.isEmpty()); @@ -76,4 +81,17 @@ public void nullWraps() { public void nullUnwraps() { Assert.assertNull(it.fromObject(IxSourceQueuedIterator.NULL)); } + + @Test + public void foreach() { + final int[] count = { 0 }; + it.foreach(new Action2() { + @Override + public void call(Integer a, Object b) { + count[0]++; + } + }, null); + + Assert.assertEquals(0, count[0]); + } } diff --git a/src/test/java/ix/Zip2Test.java b/src/test/java/ix/Zip2Test.java index c8ab782..1c2f629 100644 --- a/src/test/java/ix/Zip2Test.java +++ b/src/test/java/ix/Zip2Test.java @@ -65,4 +65,12 @@ public void bothEmpty() { IxTestHelper.assertValues(source); } + @Test + public void normalWith() { + + Ix source = Ix.range(1, 2).zipWith(Ix.range(10, 2), sum); + + IxTestHelper.assertValues(source, 11, 13); + } + } From 0cda7faa0ca818b5da22956ab21ba9dcbf5086a2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?D=C3=A1vid=20Karnok?= Date: Wed, 13 Jul 2016 22:40:48 +0200 Subject: [PATCH 21/66] +split, Milestone 1 --- gradle.properties | 2 +- src/main/java/ix/Ix.java | 4 ++ src/main/java/ix/IxSplit.java | 51 +++++++++++++++++++++++++ src/test/java/ix/SplitTest.java | 67 +++++++++++++++++++++++++++++++++ 4 files changed, 123 insertions(+), 1 deletion(-) create mode 100644 src/main/java/ix/IxSplit.java create mode 100644 src/test/java/ix/SplitTest.java diff --git a/gradle.properties b/gradle.properties index 07533ff..fa6096c 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1 +1 @@ -version=1.0.0-M0 +version=1.0.0-M1 diff --git a/src/main/java/ix/Ix.java b/src/main/java/ix/Ix.java index 067f7f4..70d12b5 100644 --- a/src/main/java/ix/Ix.java +++ b/src/main/java/ix/Ix.java @@ -182,6 +182,10 @@ public static Ix forloop(T seed, Pred condition, Func1 selector) { return new IxForloop(seed, condition, selector, next); } + + public static Ix split(String string, String by) { + return new IxSplit(string, by); + } //--------------------------------------------------------------------------------------- // Instance operators diff --git a/src/main/java/ix/IxSplit.java b/src/main/java/ix/IxSplit.java new file mode 100644 index 0000000..f13fb26 --- /dev/null +++ b/src/main/java/ix/IxSplit.java @@ -0,0 +1,51 @@ +package ix; + +import java.util.Iterator; + +final class IxSplit extends Ix { + + final String string; + + final String by; + + public IxSplit(String string, String by) { + this.string = string; + this.by = by; + } + + @Override + public Iterator iterator() { + return new SplitIterator(string, by); + } + + static final class SplitIterator extends IxBaseIterator { + final String string; + + final String by; + + int index; + + public SplitIterator(String string, String by) { + this.string = string; + this.by = by; + } + + @Override + protected boolean moveNext() { + int i = index; + int j = string.indexOf(by, i); + + if (j < 0) { + value = string.substring(i); + hasValue = true; + done = true; + return true; + } + + hasValue = true; + index = j + by.length(); + value = string.substring(i, j); + return true; + } + } +} diff --git a/src/test/java/ix/SplitTest.java b/src/test/java/ix/SplitTest.java new file mode 100644 index 0000000..da1c4c5 --- /dev/null +++ b/src/test/java/ix/SplitTest.java @@ -0,0 +1,67 @@ +/* + * Copyright 2011-2016 David Karnok + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ix; + +import org.junit.Test; + +public class SplitTest { + + @Test + public void normal() { + Ix source = Ix.split("a|b|c|d", "|"); + + IxTestHelper.assertValues(source, "a", "b", "c", "d"); + + IxTestHelper.assertNoRemove(source); + } + + @Test + public void normal2() { + Ix source = Ix.split("a|b|c|", "|"); + + IxTestHelper.assertValues(source, "a", "b", "c", ""); + + IxTestHelper.assertNoRemove(source); + } + + @Test + public void normal3() { + Ix source = Ix.split("a1|b2|c3", "|"); + + IxTestHelper.assertValues(source, "a1", "b2", "c3"); + + IxTestHelper.assertNoRemove(source); + } + + @Test + public void normal4() { + Ix source = Ix.split("a1| source = Ix.split("", "|"); + + IxTestHelper.assertValues(source, ""); + + IxTestHelper.assertNoRemove(source); + } +} From d6185c46ac0f9dbcc10b80251d660100c84cb532 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?D=C3=A1vid=20Karnok?= Date: Thu, 14 Jul 2016 00:07:21 +0200 Subject: [PATCH 22/66] + groupBy --- src/main/java/ix/Ix.java | 3 +- src/main/java/ix/IxGroupBy.java | 194 +++++++++++++++++++++ src/main/java/ix/IxSplit.java | 16 ++ src/test/java/ix/GroupByTest.java | 278 ++++++++++++++++++++++++++++++ 4 files changed, 489 insertions(+), 2 deletions(-) create mode 100644 src/main/java/ix/IxGroupBy.java create mode 100644 src/test/java/ix/GroupByTest.java diff --git a/src/main/java/ix/Ix.java b/src/main/java/ix/Ix.java index 70d12b5..a2d3eaf 100644 --- a/src/main/java/ix/Ix.java +++ b/src/main/java/ix/Ix.java @@ -422,8 +422,7 @@ public final Ix> groupBy(Func1 keySe public final Ix> groupBy(Func1 keySelector, Func1 valueSelector) { - // TODO implement - throw new UnsupportedOperationException(); + return new IxGroupBy(this, keySelector, valueSelector); } public final Ix repeat() { diff --git a/src/main/java/ix/IxGroupBy.java b/src/main/java/ix/IxGroupBy.java new file mode 100644 index 0000000..93e3da7 --- /dev/null +++ b/src/main/java/ix/IxGroupBy.java @@ -0,0 +1,194 @@ +/* + * Copyright 2011-2016 David Karnok + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ix; + +import java.util.*; + +import rx.functions.Func1; + +final class IxGroupBy extends IxSource> { + + static final Object NULL = new Object(); + + final Func1 keySelector; + + final Func1 valueSelector; + + public IxGroupBy(Iterable source, Func1 keySelector, + Func1 valueSelector) { + super(source); + this.keySelector = keySelector; + this.valueSelector = valueSelector; + } + + @Override + public Iterator> iterator() { + return new GroupByIterator(source.iterator(), keySelector, valueSelector); + } + + static final class GroupByIterator extends IxSourceIterator> { + final Func1 keySelector; + + final Func1 valueSelector; + + final Map> groups; + + final Queue> queue; + + public GroupByIterator(Iterator it, Func1 keySelector, + Func1 valueSelector) { + super(it); + this.keySelector = keySelector; + this.valueSelector = valueSelector; + this.groups = new HashMap>(); + this.queue = new ArrayDeque>(); + } + + @Override + protected boolean moveNext() { + GroupedIterable g = queue.poll(); + if (g != null) { + value = g; + hasValue = true; + return true; + } + if (mainMoveNext()) { + g = queue.poll(); + value = g; + hasValue = true; + return true; + } + done = true; + return false; + } + + boolean mainMoveNext() { + for (;;) { + if (!it.hasNext()) { + groups.clear(); + return false; + } + + T v = it.next(); + + K key = keySelector.call(v); + V val = valueSelector.call(v); + + GroupedIterable g = groups.get(key); + if (g == null) { + g = new GroupedIterable(key, this); + groups.put(key, g); + g.iterator.queue.offer(val != null ? val : NULL); + + queue.offer(g); + return true; + } else { + g.iterator.queue.offer(val != null ? val : NULL); + } + } + } + + boolean groupMoveNext(GroupByGroupIterator groupIterator) { + if (done) { + return false; + } + for (;;) { + if (!it.hasNext()) { + groups.clear(); + return false; + } + + T v = it.next(); + + K key = keySelector.call(v); + V val = valueSelector.call(v); + + GroupedIterable g = groups.get(key); + if (g == null) { + g = new GroupedIterable(key, this); + groups.put(key, g); + g.iterator.queue.offer(val != null ? val : NULL); + queue.offer(g); + } else { + g.iterator.queue.offer(val != null ? val : NULL); + if (EqualityHelper.INSTANCE.test(key, groupIterator.key)) { + return true; + } + } + } + } + } + + static final class GroupedIterable extends GroupedIx { + + final GroupByGroupIterator iterator; + + boolean once; + + public GroupedIterable(K key, GroupByIterator parent) { + super(key); + this.iterator = new GroupByGroupIterator(parent, key); + } + + @Override + public Iterator iterator() { + if (!once) { + once = true; + return iterator; + } + throw new IllegalStateException("This GroupedIx iterable can be consumed only once."); + } + + @Override + public String toString() { + return "GroupedIterable[key=" + iterator.key + ", queue=" + iterator.queue.size() + "]"; + } + } + + static final class GroupByGroupIterator extends IxBaseIterator { + final GroupByIterator parent; + + final K key; + + final ArrayDeque queue; + + public GroupByGroupIterator(GroupByIterator parent, K key) { + this.parent = parent; + this.key = key; + this.queue = new ArrayDeque(); + } + + @SuppressWarnings("unchecked") + @Override + protected boolean moveNext() { + Object o = queue.poll(); + if (o != null) { + value = o == NULL ? null : (V)o; + hasValue = true; + return true; + } + if (parent.groupMoveNext(this)) { + o = queue.poll(); + value = o == NULL ? null : (V)o; + hasValue = true; + return true; + } + done = true; + return false; + } + } +} diff --git a/src/main/java/ix/IxSplit.java b/src/main/java/ix/IxSplit.java index f13fb26..bee3e0a 100644 --- a/src/main/java/ix/IxSplit.java +++ b/src/main/java/ix/IxSplit.java @@ -1,3 +1,19 @@ +/* + * Copyright 2011-2016 David Karnok + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package ix; import java.util.Iterator; diff --git a/src/test/java/ix/GroupByTest.java b/src/test/java/ix/GroupByTest.java new file mode 100644 index 0000000..c646747 --- /dev/null +++ b/src/test/java/ix/GroupByTest.java @@ -0,0 +1,278 @@ +/* + * Copyright 2011-2016 David Karnok + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ix; + +import java.util.*; + +import org.junit.*; + +import rx.functions.*; + +public class GroupByTest { + + @Test + public void normal() { + Ix source = Ix.range(1, 10).groupBy(new Func1() { + @Override + public Object call(Integer v) { + return v % 3; + } + }).flatMap(new Func1, Iterable>() { + @Override + public Iterable call(GroupedIx v) { + return v; + } + }); + + IxTestHelper.assertValues(source, 1, 4, 7, 10, 2, 5, 8, 3, 6, 9); + + IxTestHelper.assertNoRemove(source); + } + + @Test + public void uniqueGroups() { + Ix source = Ix.range(1, 10).groupBy(new Func1() { + @Override + public Object call(Integer v) { + return v; + } + }, + new Func1() { + @Override + public Integer call(Integer v) { + return v * 10; + } + } + ).flatMap(new Func1, Iterable>() { + @Override + public Iterable call(GroupedIx v) { + return v; + } + }); + + IxTestHelper.assertValues(source, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100); + + IxTestHelper.assertNoRemove(source); + } + + @Test + public void just() { + Ix source = Ix.just(1).groupBy(new Func1() { + @Override + public Object call(Integer v) { + return v % 3; + } + }).flatMap(new Func1, Iterable>() { + @Override + public Iterable call(GroupedIx v) { + return v; + } + }); + + IxTestHelper.assertValues(source, 1); + + IxTestHelper.assertNoRemove(source); + } + + @Test + public void justNull() { + Ix source = Ix.just(null).groupBy(new Func1() { + @Override + public Object call(Integer v) { + return 1; + } + }).flatMap(new Func1, Iterable>() { + @Override + public Iterable call(GroupedIx v) { + return v; + } + }); + + IxTestHelper.assertValues(source, (Integer)null); + + IxTestHelper.assertNoRemove(source); + } + + @Test + public void empty() { + Ix source = Ix.empty().groupBy(new Func1() { + @Override + public Object call(Integer v) { + return v % 3; + } + }).flatMap(new Func1, Iterable>() { + @Override + public Iterable call(GroupedIx v) { + return v; + } + }); + + IxTestHelper.assertValues(source); + + IxTestHelper.assertNoRemove(source); + } + + @SuppressWarnings("unchecked") + @Test + public void lockstep() { + final Iterator[] its = new Iterator[3]; + + Iterator main = Ix.range(1, 10).groupBy(new Func1() { + @Override + public Integer call(Integer v) { + return v % 3; + } + }).doOnNext(new Action1>() { + @Override + public void call(GroupedIx g) { + its[g.key()] = g.iterator(); + } + }) + .iterator(); + + Assert.assertNotNull(main.next()); + + Assert.assertEquals(1, its[1].next().intValue()); + + Assert.assertNotNull(main.next()); + + Assert.assertEquals(2, its[2].next().intValue()); + + Assert.assertTrue(its[2].hasNext()); + Assert.assertNotNull(main.next()); + + Assert.assertEquals(3, its[0].next().intValue()); + Assert.assertEquals(4, its[1].next().intValue()); + Assert.assertEquals(5, its[2].next().intValue()); + Assert.assertEquals(6, its[0].next().intValue()); + + Assert.assertEquals(7, its[1].next().intValue()); + Assert.assertEquals(8, its[2].next().intValue()); + Assert.assertEquals(9, its[0].next().intValue()); + Assert.assertEquals(10, its[1].next().intValue()); + + Assert.assertFalse(main.hasNext()); + Assert.assertFalse(its[0].hasNext()); + Assert.assertFalse(its[1].hasNext()); + Assert.assertFalse(its[2].hasNext()); + } + + + @SuppressWarnings("unchecked") + @Test + public void lockstepNull() { + final Iterator[] its = new Iterator[3]; + + Iterator main = Ix.range(1, 10).groupBy(new Func1() { + @Override + public Integer call(Integer v) { + return v % 3; + } + }, new Func1() { + @Override + public Integer call(Integer v) { + return null; + } + }).doOnNext(new Action1>() { + @Override + public void call(GroupedIx g) { + its[g.key()] = g.iterator(); + } + }) + .iterator(); + + Assert.assertNotNull(main.next()); + + Assert.assertNull(its[1].next()); + + Assert.assertNotNull(main.next()); + + Assert.assertNull(its[2].next()); + + Assert.assertTrue(its[2].hasNext()); + Assert.assertNotNull(main.next()); + + Assert.assertNull(its[0].next()); + Assert.assertNull(its[1].next()); + Assert.assertNull(its[2].next()); + Assert.assertNull(its[0].next()); + + Assert.assertNull(its[1].next()); + Assert.assertNull(its[2].next()); + Assert.assertNull(its[0].next()); + Assert.assertNull(its[1].next()); + + Assert.assertFalse(main.hasNext()); + Assert.assertFalse(its[0].hasNext()); + Assert.assertFalse(its[1].hasNext()); + Assert.assertFalse(its[2].hasNext()); + } + @Test + public void sameGroupSubsequently() { + Ix> source = Ix.range(1, 5).groupBy(new Func1() { + @Override + public Integer call(Integer v) { + return 1; + } + }); + + List> list = source.toList().first(); + + IxTestHelper.assertValues(Ix.concat(list), 1, 2, 3, 4, 5); + } + + @Test + public void sameGroupSubsequentlyNullValue() { + Ix> source = Ix.range(1, 5).groupBy(new Func1() { + @Override + public Integer call(Integer v) { + return 1; + } + }, new Func1() { + @Override + public Integer call(Integer v) { + return null; + } + }); + + List> list = source.toList().first(); + + IxTestHelper.assertValues(Ix.concat(list), null, null, null, null, null); + } + + @Test(expected = IllegalStateException.class) + public void iteratorOnce() { + Ix> source = Ix.range(1, 5).groupBy(new Func1() { + @Override + public Integer call(Integer v) { + return 1; + } + }, new Func1() { + @Override + public Integer call(Integer v) { + return null; + } + }); + + List> list = source.toList().first(); + + Assert.assertEquals("GroupedIterable[key=1, queue=5]", list.get(0).toString()); + + IxTestHelper.assertValues(list.get(0), null, null, null, null, null); + IxTestHelper.assertValues(list.get(0), null, null, null, null, null); + } +} From 01ff630689f39975b0252211104b112f21192019 Mon Sep 17 00:00:00 2001 From: akarnokd Date: Fri, 15 Jul 2016 11:22:30 +0200 Subject: [PATCH 23/66] Add several simpler operators --- gradle.properties | 2 +- src/main/java/ix/Ix.java | 35 ++--- src/main/java/ix/IxLift.java | 37 +++++ src/main/java/ix/IxOrderBy.java | 100 ++++++++++++++ src/main/java/ix/IxRemove.java | 70 ++++++++++ src/main/java/ix/IxRetain.java | 70 ++++++++++ src/main/java/ix/IxScan.java | 81 +++++++++++ src/main/java/ix/IxScanSeed.java | 78 +++++++++++ src/main/java/ix/IxToMap.java | 78 +++++++++++ src/main/java/ix/IxToMultimap.java | 84 +++++++++++ src/main/java/ix/IxTransformer.java | 74 ++++++++++ src/test/java/ix/LiftTest.java | 55 ++++++++ src/test/java/ix/OrderByTest.java | 82 +++++++++++ src/test/java/ix/RemoveRetainTest.java | 184 +++++++++++++++++++++++++ src/test/java/ix/ScanTest.java | 123 +++++++++++++++++ src/test/java/ix/ToMapTest.java | 136 ++++++++++++++++++ src/test/java/ix/TransformTest.java | 97 +++++++++++++ 17 files changed, 1365 insertions(+), 21 deletions(-) create mode 100644 src/main/java/ix/IxLift.java create mode 100644 src/main/java/ix/IxOrderBy.java create mode 100644 src/main/java/ix/IxRemove.java create mode 100644 src/main/java/ix/IxRetain.java create mode 100644 src/main/java/ix/IxScan.java create mode 100644 src/main/java/ix/IxScanSeed.java create mode 100644 src/main/java/ix/IxToMap.java create mode 100644 src/main/java/ix/IxToMultimap.java create mode 100644 src/main/java/ix/IxTransformer.java create mode 100644 src/test/java/ix/LiftTest.java create mode 100644 src/test/java/ix/OrderByTest.java create mode 100644 src/test/java/ix/RemoveRetainTest.java create mode 100644 src/test/java/ix/ScanTest.java create mode 100644 src/test/java/ix/ToMapTest.java create mode 100644 src/test/java/ix/TransformTest.java diff --git a/gradle.properties b/gradle.properties index fa6096c..cb204eb 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1 +1 @@ -version=1.0.0-M1 +version=1.0.0-M2 diff --git a/src/main/java/ix/Ix.java b/src/main/java/ix/Ix.java index a2d3eaf..2dfb185 100644 --- a/src/main/java/ix/Ix.java +++ b/src/main/java/ix/Ix.java @@ -477,8 +477,7 @@ public final Ix> toMap(Func1 keySelector) } public final Ix> toMap(Func1 keySelector, Func1 valueSelector) { - // TODO implement - throw new UnsupportedOperationException(); + return new IxToMap(this, keySelector, valueSelector); } public final Ix>> toMultimap(Func1 keySelector) { @@ -487,8 +486,7 @@ public final Ix>> toMultimap(Func1 Ix>> toMultimap(Func1 keySelector, Func1 valueSelector) { - // TODO implement - throw new UnsupportedOperationException(); + return new IxToMultimap(this, keySelector, valueSelector); } public final Ix> window(int size) { @@ -513,44 +511,41 @@ public final Ix zipWith(Iterable other, Func2 orderBy() { - // TODO implement - throw new UnsupportedOperationException(); + return orderBy((Comparator)SelfComparator.INSTANCE); } public final Ix orderBy(Comparator comparator) { - // TODO implement - throw new UnsupportedOperationException(); + return new IxOrderBy(this, IdentityHelper.instance(), comparator); } public final > Ix orderBy(Func1 keySelector) { - // TODO implement - throw new UnsupportedOperationException(); + return new IxOrderBy(this, keySelector, SelfComparator.INSTANCE); } public final Ix scan(Func2 scanner) { - // TODO implement - throw new UnsupportedOperationException(); + return new IxScan(this, scanner); } public final Ix scan(Func0 initialFactory, Func2 scanner) { - // TODO implement - throw new UnsupportedOperationException(); + return new IxScanSeed(this, initialFactory, scanner); } public final Ix remove(Pred predicate) { - // TODO implement - throw new UnsupportedOperationException(); + return new IxRemove(this, predicate); + } + + public final Ix retain(Pred predicate) { + return new IxRetain(this, predicate); } public final Ix transform(IxTransform transformer) { - // TODO implement - throw new UnsupportedOperationException(); + return new IxTransformer(this, transformer); } public final Ix lift(Func1, ? extends Iterator> lifter) { - // TODO implement - throw new UnsupportedOperationException(); + return new IxLift(this, lifter); } //--------------------------------------------------------------------------------------- diff --git a/src/main/java/ix/IxLift.java b/src/main/java/ix/IxLift.java new file mode 100644 index 0000000..e3e14bc --- /dev/null +++ b/src/main/java/ix/IxLift.java @@ -0,0 +1,37 @@ +/* + * Copyright 2011-2016 David Karnok + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ix; + +import java.util.Iterator; + +import rx.functions.Func1; + +final class IxLift extends IxSource { + + final Func1, ? extends Iterator> lifter; + + public IxLift(Iterable source, Func1, ? extends Iterator> lifter) { + super(source); + this.lifter = lifter; + } + + @Override + public Iterator iterator() { + return lifter.call(source.iterator()); + } + +} diff --git a/src/main/java/ix/IxOrderBy.java b/src/main/java/ix/IxOrderBy.java new file mode 100644 index 0000000..782a1d3 --- /dev/null +++ b/src/main/java/ix/IxOrderBy.java @@ -0,0 +1,100 @@ +/* + * Copyright 2011-2016 David Karnok + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ix; + +import java.util.*; + +import rx.functions.Func1; + +final class IxOrderBy extends IxSource { + + final Func1 keySelector; + + final Comparator comparator; + + public IxOrderBy(Iterable source, Func1 keySelector, Comparator comparator) { + super(source); + this.keySelector = keySelector; + this.comparator = comparator; + } + + @Override + public Iterator iterator() { + return new OrderByIterator(source.iterator(), keySelector, comparator); + } + + static final class OrderByIterator extends IxSourceIterator implements Comparator { + + final Func1 keySelector; + + final Comparator comparator; + + List values; + + int index; + + public OrderByIterator(Iterator it, Func1 keySelector, Comparator comparator) { + super(it); + this.keySelector = keySelector; + this.comparator = comparator; + } + + @Override + protected boolean moveNext() { + + List list = values; + + if (list == null) { + list = new ArrayList(); + + Iterator it = this.it; + + while (it.hasNext()) { + list.add(it.next()); + } + + if (list.isEmpty()) { + done = true; + return false; + } + + Collections.sort(list, this); + + values = list; + } + + int i = index; + if (i != list.size()) { + index = i + 1; + value = list.get(i); + list.set(i, null); + hasValue = true; + return true; + } + done = true; + return false; + } + + @Override + public int compare(T o1, T o2) { + K k1 = keySelector.call(o1); + K k2 = keySelector.call(o2); + return comparator.compare(k1, k2); + } + } + +} diff --git a/src/main/java/ix/IxRemove.java b/src/main/java/ix/IxRemove.java new file mode 100644 index 0000000..fa3285e --- /dev/null +++ b/src/main/java/ix/IxRemove.java @@ -0,0 +1,70 @@ +/* + * Copyright 2011-2016 David Karnok + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ix; + +import java.util.Iterator; + +public class IxRemove extends IxSource { + + final Pred predicate; + + public IxRemove(Iterable source, Pred predicate) { + super(source); + this.predicate = predicate; + } + + @Override + public Iterator iterator() { + return new RemoveIterator(source.iterator(), predicate); + } + + static final class RemoveIterator extends IxSourceIterator { + final Pred predicate; + + public RemoveIterator(Iterator it, Pred predicate) { + super(it); + this.predicate = predicate; + } + + @Override + protected boolean moveNext() { + + for (;;) { + if (!it.hasNext()) { + done = true; + return false; + } + + T v = it.next(); + + if (predicate.test(v)) { + it.remove(); + } else { + value = v; + hasValue = true; + return true; + } + } + } + + @Override + public void remove() { + it.remove(); + } + } + +} diff --git a/src/main/java/ix/IxRetain.java b/src/main/java/ix/IxRetain.java new file mode 100644 index 0000000..274be72 --- /dev/null +++ b/src/main/java/ix/IxRetain.java @@ -0,0 +1,70 @@ +/* + * Copyright 2011-2016 David Karnok + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ix; + +import java.util.Iterator; + +public class IxRetain extends IxSource { + + final Pred predicate; + + public IxRetain(Iterable source, Pred predicate) { + super(source); + this.predicate = predicate; + } + + @Override + public Iterator iterator() { + return new RetainIterator(source.iterator(), predicate); + } + + static final class RetainIterator extends IxSourceIterator { + final Pred predicate; + + public RetainIterator(Iterator it, Pred predicate) { + super(it); + this.predicate = predicate; + } + + @Override + protected boolean moveNext() { + + for (;;) { + if (!it.hasNext()) { + done = true; + return false; + } + + T v = it.next(); + + if (predicate.test(v)) { + value = v; + hasValue = true; + return true; + } else { + it.remove(); + } + } + } + + @Override + public void remove() { + it.remove(); + } + } + +} diff --git a/src/main/java/ix/IxScan.java b/src/main/java/ix/IxScan.java new file mode 100644 index 0000000..d227995 --- /dev/null +++ b/src/main/java/ix/IxScan.java @@ -0,0 +1,81 @@ +/* + * Copyright 2011-2016 David Karnok + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ix; + +import java.util.Iterator; + +import rx.functions.Func2; + +final class IxScan extends IxSource { + + final Func2 scanner; + + public IxScan(Iterable source, Func2 scanner) { + super(source); + this.scanner = scanner; + } + + @Override + public Iterator iterator() { + return new ScanIterator(source.iterator(), scanner); + } + + static final class ScanIterator extends IxSourceIterator { + + final Func2 scanner; + + T last; + + boolean once; + + public ScanIterator(Iterator it, Func2 scanner) { + super(it); + this.scanner = scanner; + } + + @Override + protected boolean moveNext() { + if (!once) { + if (it.hasNext()) { + once = true; + T v = it.next(); + + last = v; + value = v; + hasValue = true; + return true; + } + done = true; + return false; + } + + if (it.hasNext()) { + T v = it.next(); + + v = scanner.call(last, v); + last = v; + value = v; + hasValue = true; + return true; + } + + last = null; + done = true; + return false; + } + } +} diff --git a/src/main/java/ix/IxScanSeed.java b/src/main/java/ix/IxScanSeed.java new file mode 100644 index 0000000..c44778a --- /dev/null +++ b/src/main/java/ix/IxScanSeed.java @@ -0,0 +1,78 @@ +/* + * Copyright 2011-2016 David Karnok + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ix; + +import java.util.Iterator; + +import rx.functions.*; + +final class IxScanSeed extends IxSource { + + final Func0 seed; + + final Func2 scanner; + + public IxScanSeed(Iterable source, Func0 seed, Func2 scanner) { + super(source); + this.seed = seed; + this.scanner = scanner; + } + + @Override + public Iterator iterator() { + return new ScanSeedIterator(source.iterator(), seed.call(), scanner); + } + + static final class ScanSeedIterator extends IxSourceIterator { + final Func2 scanner; + + R accumulator; + + boolean once; + + public ScanSeedIterator(Iterator it, R accumulator, Func2 scanner) { + super(it); + this.accumulator = accumulator; + this.scanner = scanner; + } + + @Override + protected boolean moveNext() { + if (!once) { + once = true; + value = accumulator; + hasValue = true; + return true; + } + + if (it.hasNext()) { + + R v = scanner.call(accumulator, it.next()); + + accumulator = v; + value = v; + hasValue = true; + return true; + } + + accumulator = null; + done = true; + return false; + } + } + +} diff --git a/src/main/java/ix/IxToMap.java b/src/main/java/ix/IxToMap.java new file mode 100644 index 0000000..deb8144 --- /dev/null +++ b/src/main/java/ix/IxToMap.java @@ -0,0 +1,78 @@ +/* + * Copyright 2011-2016 David Karnok + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ix; + +import java.util.*; + +import rx.functions.Func1; + +final class IxToMap extends IxSource> { + + final Func1 keySelector; + + final Func1 valueSelector; + + public IxToMap(Iterable source, Func1 keySelector, Func1 valueSelector) { + super(source); + this.keySelector = keySelector; + this.valueSelector = valueSelector; + } + + @Override + public Iterator> iterator() { + return new ToMapIterator(source.iterator(), keySelector, valueSelector); + } + + static final class ToMapIterator extends IxSourceIterator> { + + final Func1 keySelector; + + final Func1 valueSelector; + + public ToMapIterator(Iterator it, Func1 keySelector, Func1 valueSelector) { + super(it); + this.keySelector = keySelector; + this.valueSelector = valueSelector; + } + + @Override + protected boolean moveNext() { + Iterator it = this.it; + + Func1 keySelector = this.keySelector; + + Func1 valueSelector = this.valueSelector; + + Map result = new HashMap(); + + while (it.hasNext()) { + T t = it.next(); + + K k = keySelector.call(t); + + V v = valueSelector.call(t); + + result.put(k, v); + } + + value = result; + hasValue = true; + done = true; + return true; + } + } +} diff --git a/src/main/java/ix/IxToMultimap.java b/src/main/java/ix/IxToMultimap.java new file mode 100644 index 0000000..b4baecd --- /dev/null +++ b/src/main/java/ix/IxToMultimap.java @@ -0,0 +1,84 @@ +/* + * Copyright 2011-2016 David Karnok + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ix; + +import java.util.*; + +import rx.functions.Func1; + +final class IxToMultimap extends IxSource>> { + + final Func1 keySelector; + + final Func1 valueSelector; + + public IxToMultimap(Iterable source, Func1 keySelector, Func1 valueSelector) { + super(source); + this.keySelector = keySelector; + this.valueSelector = valueSelector; + } + + @Override + public Iterator>> iterator() { + return new ToMapIterator(source.iterator(), keySelector, valueSelector); + } + + static final class ToMapIterator extends IxSourceIterator>> { + + final Func1 keySelector; + + final Func1 valueSelector; + + public ToMapIterator(Iterator it, Func1 keySelector, Func1 valueSelector) { + super(it); + this.keySelector = keySelector; + this.valueSelector = valueSelector; + } + + @Override + protected boolean moveNext() { + Iterator it = this.it; + + Func1 keySelector = this.keySelector; + + Func1 valueSelector = this.valueSelector; + + Map> result = new HashMap>(); + + while (it.hasNext()) { + T t = it.next(); + + K k = keySelector.call(t); + + Collection coll = result.get(k); + if (coll == null) { + coll = new ArrayList(); + result.put(k, coll); + } + + V v = valueSelector.call(t); + + coll.add(v); + } + + value = result; + hasValue = true; + done = true; + return true; + } + } +} diff --git a/src/main/java/ix/IxTransformer.java b/src/main/java/ix/IxTransformer.java new file mode 100644 index 0000000..ebce7ad --- /dev/null +++ b/src/main/java/ix/IxTransformer.java @@ -0,0 +1,74 @@ +/* + * Copyright 2011-2016 David Karnok + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ix; + +import java.util.Iterator; + +import rx.functions.Action1; + +final class IxTransformer extends IxSource { + + final IxTransform transform; + + public IxTransformer(Iterable source, IxTransform transform) { + super(source); + this.transform = transform; + } + + @Override + public Iterator iterator() { + return new TransformerIterator(source.iterator(), transform); + } + + static final class TransformerIterator extends IxSourceIterator + implements Action1 { + + final IxTransform transform; + + public TransformerIterator(Iterator it, IxTransform transform) { + super(it); + this.transform = transform; + } + + @Override + protected boolean moveNext() { + int m = transform.moveNext(it, this); + if (m == IxTransform.LAST) { + done = true; + return true; + } + if (m == IxTransform.STOP) { + value = null; + done = true; + return false; + } + if (!hasValue) { + throw new IllegalStateException("No value set!"); + } + return true; + } + + @Override + public void call(R t) { + if (hasValue) { + throw new IllegalStateException("Value already set in this turn!"); + } + value = t; + hasValue = true; + } + } +} diff --git a/src/test/java/ix/LiftTest.java b/src/test/java/ix/LiftTest.java new file mode 100644 index 0000000..62e96ee --- /dev/null +++ b/src/test/java/ix/LiftTest.java @@ -0,0 +1,55 @@ +/* + * Copyright 2011-2016 David Karnok + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ix; + +import java.util.Iterator; + +import org.junit.Test; + +import rx.functions.Func1; + +public class LiftTest { + + @Test + public void normal() { + Ix source = Ix.just(1).lift(new Func1, Iterator>() { + @Override + public Iterator call(final Iterator it) { + return new Iterator() { + @Override + public boolean hasNext() { + return it.hasNext(); + } + + @Override + public Integer next() { + return it.next() + 10; + } + + @Override + public void remove() { + throw new UnsupportedOperationException(); + } + }; + } + }); + + IxTestHelper.assertValues(source, 11); + + IxTestHelper.assertNoRemove(source); + } +} diff --git a/src/test/java/ix/OrderByTest.java b/src/test/java/ix/OrderByTest.java new file mode 100644 index 0000000..ead8522 --- /dev/null +++ b/src/test/java/ix/OrderByTest.java @@ -0,0 +1,82 @@ +/* + * Copyright 2011-2016 David Karnok + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ix; + +import java.util.Comparator; + +import org.junit.Test; + +import rx.functions.Func1; + +public class OrderByTest { + + @Test + public void normal() { + Ix source = Ix.fromArray(5, 4, 3, 2, 1).orderBy(); + + IxTestHelper.assertValues(source, 1, 2, 3, 4, 5); + + IxTestHelper.assertNoRemove(source); + } + + @Test + public void normalComparator() { + Ix source = Ix.fromArray(1, 2, 3, 4, 5).orderBy(new Comparator() { + @Override + public int compare(Integer a, Integer b) { + return b.compareTo(a); + } + }); + + IxTestHelper.assertValues(source, 5, 4, 3, 2, 1); + + IxTestHelper.assertNoRemove(source); + } + + @Test + public void normalKeySelector() { + Ix source = Ix.fromArray(1, 2, 3, 4, 5).orderBy(new Func1() { + @Override + public Integer call(Integer v) { + return 3 - v; + } + }); + + IxTestHelper.assertValues(source, 5, 4, 3, 2, 1); + + IxTestHelper.assertNoRemove(source); + } + + @Test + public void empty() { + Ix source = Ix.empty().orderBy(); + + IxTestHelper.assertValues(source); + + IxTestHelper.assertNoRemove(source); + } + + @Test + public void just() { + Ix source = Ix.just(1).orderBy(); + + IxTestHelper.assertValues(source, 1); + + IxTestHelper.assertNoRemove(source); + } + +} diff --git a/src/test/java/ix/RemoveRetainTest.java b/src/test/java/ix/RemoveRetainTest.java new file mode 100644 index 0000000..16448fb --- /dev/null +++ b/src/test/java/ix/RemoveRetainTest.java @@ -0,0 +1,184 @@ +/* + * Copyright 2011-2016 David Karnok + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ix; + +import java.util.List; + +import org.junit.Test; + +public class RemoveRetainTest { + + @Test + public void removeNormal() { + List list = IxTestHelper.range(1, 10); + + Ix source = Ix.from(list).remove(new Pred() { + @Override + public boolean test(Integer v) { + return (v & 1) != 0; + } + }); + + IxTestHelper.assertValues(source, 2, 4, 6, 8, 10); + IxTestHelper.assertValues(list, 2, 4, 6, 8, 10); + } + + @Test + public void removeAll() { + List list = IxTestHelper.range(1, 10); + + Ix source = Ix.from(list).remove(new Pred() { + @Override + public boolean test(Integer v) { + return true; + } + }); + + IxTestHelper.assertValues(source); + IxTestHelper.assertValues(list); + } + + @Test + public void removeNone() { + List list = IxTestHelper.range(1, 10); + + Ix source = Ix.from(list).remove(new Pred() { + @Override + public boolean test(Integer v) { + return false; + } + }); + + IxTestHelper.assertValues(source, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10); + IxTestHelper.assertValues(list, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10); + } + + @Test + public void removeEmpty() { + List list = IxTestHelper.range(1, 0); + + Ix source = Ix.from(list).remove(new Pred() { + @Override + public boolean test(Integer v) { + return true; + } + }); + + IxTestHelper.assertValues(source); + IxTestHelper.assertValues(list); + } + + @Test + public void retainNormal() { + List list = IxTestHelper.range(1, 10); + + Ix source = Ix.from(list).retain(new Pred() { + @Override + public boolean test(Integer v) { + return (v & 1) != 0; + } + }); + + IxTestHelper.assertValues(source, 1, 3, 5, 7, 9); + IxTestHelper.assertValues(list, 1, 3, 5, 7, 9); + } + + @Test + public void retainAll() { + List list = IxTestHelper.range(1, 10); + + Ix source = Ix.from(list).retain(new Pred() { + @Override + public boolean test(Integer v) { + return true; + } + }); + + IxTestHelper.assertValues(source, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10); + IxTestHelper.assertValues(list, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10); + } + + @Test + public void retainNone() { + List list = IxTestHelper.range(1, 10); + + Ix source = Ix.from(list).retain(new Pred() { + @Override + public boolean test(Integer v) { + return false; + } + }); + + IxTestHelper.assertValues(source); + IxTestHelper.assertValues(list); + } + + @Test + public void retainEmpty() { + List list = IxTestHelper.range(1, 0); + + Ix source = Ix.from(list).retain(new Pred() { + @Override + public boolean test(Integer v) { + return false; + } + }); + + IxTestHelper.assertValues(source); + IxTestHelper.assertValues(list); + } + + @Test + public void removeAllDouble() { + List list = IxTestHelper.range(1, 10); + + Ix source = Ix.from(list).remove(new Pred() { + @Override + public boolean test(Integer v) { + return (v & 1) != 0; + } + }).remove(new Pred() { + @Override + public boolean test(Integer v) { + return (v & 1) == 0; + } + }); + + IxTestHelper.assertValues(source); + IxTestHelper.assertValues(list); + } + + @Test + public void retainNoneDouble() { + List list = IxTestHelper.range(1, 10); + + Ix source = Ix.from(list).retain(new Pred() { + @Override + public boolean test(Integer v) { + return (v & 1) != 0; + } + }).retain(new Pred() { + @Override + public boolean test(Integer v) { + return (v & 1) == 0; + } + }); + + IxTestHelper.assertValues(source); + IxTestHelper.assertValues(list); + } +} diff --git a/src/test/java/ix/ScanTest.java b/src/test/java/ix/ScanTest.java new file mode 100644 index 0000000..3b5e3a6 --- /dev/null +++ b/src/test/java/ix/ScanTest.java @@ -0,0 +1,123 @@ +/* + * Copyright 2011-2016 David Karnok + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ix; + +import org.junit.Test; + +import rx.functions.*; + +public class ScanTest { + + @Test + public void normal() { + Ix source = Ix.range(1, 5).scan(new Func2() { + @Override + public Integer call(Integer t1, Integer t2) { + return t1 + t2; + } + }); + + IxTestHelper.assertValues(source, 1, 3, 6, 10, 15); + + IxTestHelper.assertNoRemove(source); + } + + @Test + public void just() { + Ix source = Ix.just(1).scan(new Func2() { + @Override + public Integer call(Integer t1, Integer t2) { + return t1 + t2; + } + }); + + IxTestHelper.assertValues(source, 1); + + IxTestHelper.assertNoRemove(source); + } + + @Test + public void empty() { + Ix source = Ix.empty().scan(new Func2() { + @Override + public Integer call(Integer t1, Integer t2) { + return t1 + t2; + } + }); + + IxTestHelper.assertValues(source); + + IxTestHelper.assertNoRemove(source); + } + + @Test + public void normalSeed() { + Ix source = Ix.range(1, 5).scan(new Func0() { + @Override + public Integer call() { + return 100; + } + },new Func2() { + @Override + public Integer call(Integer t1, Integer t2) { + return t1 + t2; + } + }); + + IxTestHelper.assertValues(source, 100, 101, 103, 106, 110, 115); + + IxTestHelper.assertNoRemove(source); + } + + @Test + public void justSeed() { + Ix source = Ix.just(1).scan(new Func0() { + @Override + public Integer call() { + return 100; + } + }, new Func2() { + @Override + public Integer call(Integer t1, Integer t2) { + return t1 + t2; + } + }); + + IxTestHelper.assertValues(source, 100, 101); + + IxTestHelper.assertNoRemove(source); + } + + @Test + public void emptySeed() { + Ix source = Ix.empty().scan(new Func0() { + @Override + public Integer call() { + return 100; + } + }, new Func2() { + @Override + public Integer call(Integer t1, Integer t2) { + return t1 + t2; + } + }); + + IxTestHelper.assertValues(source, 100); + + IxTestHelper.assertNoRemove(source); + } +} diff --git a/src/test/java/ix/ToMapTest.java b/src/test/java/ix/ToMapTest.java new file mode 100644 index 0000000..e4b39bb --- /dev/null +++ b/src/test/java/ix/ToMapTest.java @@ -0,0 +1,136 @@ +/* + * Copyright 2011-2016 David Karnok + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ix; + +import java.util.*; + +import org.junit.Test; + +import rx.functions.Func1; + +public class ToMapTest { + + @SuppressWarnings("unchecked") + @Test + public void normal() { + Ix> source = Ix.range(1, 5).toMap(new Func1() { + @Override + public Integer call(Integer v) { + return v % 3; + } + }); + + Map map = new HashMap(); + map.put(1, 4); + map.put(0, 3); + map.put(2, 5); + + IxTestHelper.assertValues(source, map); + } + + @SuppressWarnings("unchecked") + @Test + public void normalValueSelector() { + Ix> source = Ix.range(1, 5).toMap(new Func1() { + @Override + public Integer call(Integer v) { + return v % 3; + } + }, new Func1() { + @Override + public Integer call(Integer v) { + return v * v; + } + }); + + Map map = new HashMap(); + map.put(1, 16); + map.put(0, 9); + map.put(2, 25); + + IxTestHelper.assertValues(source, map); + } + @SuppressWarnings("unchecked") + @Test + public void empty() { + Ix> source = Ix.empty().toMap(new Func1() { + @Override + public Integer call(Integer v) { + return v % 3; + } + }); + + Map map = new HashMap(); + + IxTestHelper.assertValues(source, map); + } + + @SuppressWarnings("unchecked") + @Test + public void multimap() { + Ix>> source = Ix.range(1, 5).toMultimap(new Func1() { + @Override + public Integer call(Integer v) { + return v % 3; + } + }); + + Map> map = new HashMap>(); + map.put(1, Arrays.asList(1, 4)); + map.put(0, Arrays.asList(3)); + map.put(2, Arrays.asList(2, 5)); + + IxTestHelper.assertValues(source, map); + } + + @SuppressWarnings("unchecked") + @Test + public void multimapValueSelector() { + Ix>> source = Ix.range(1, 5).toMultimap(new Func1() { + @Override + public Integer call(Integer v) { + return v % 3; + } + }, new Func1() { + @Override + public Integer call(Integer v) { + return v * v; + } + }); + + Map> map = new HashMap>(); + map.put(1, Arrays.asList(1, 16)); + map.put(0, Arrays.asList(9)); + map.put(2, Arrays.asList(4, 25)); + + IxTestHelper.assertValues(source, map); + } + @SuppressWarnings("unchecked") + @Test + public void multimapEmpty() { + Ix>> source = Ix.empty().toMultimap(new Func1() { + @Override + public Integer call(Integer v) { + return v % 3; + } + }); + + Map> map = new HashMap>(); + + IxTestHelper.assertValues(source, map); + } +} diff --git a/src/test/java/ix/TransformTest.java b/src/test/java/ix/TransformTest.java new file mode 100644 index 0000000..450d1dc --- /dev/null +++ b/src/test/java/ix/TransformTest.java @@ -0,0 +1,97 @@ +/* + * Copyright 2011-2016 David Karnok + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ix; + +import java.util.Iterator; + +import org.junit.*; + +import rx.functions.Action1; + +public class TransformTest { + + @Test + public void normal() { + Ix source = Ix.just(1).transform(new IxTransform() { + @Override + public int moveNext(Iterator it, Action1 out) { + if (it.hasNext()) { + out.call(it.next() + 10); + return IxTransform.NEXT; + } + out.call(12); + return IxTransform.LAST; + } + }); + + IxTestHelper.assertValues(source, 11, 12); + + IxTestHelper.assertNoRemove(source); + } + + @Test + public void stop() { + Ix source = Ix.just(1).transform(new IxTransform() { + @Override + public int moveNext(Iterator it, Action1 out) { + return IxTransform.STOP; + } + }); + + IxTestHelper.assertValues(source); + + IxTestHelper.assertNoRemove(source); + } + + @Test + public void doubleNext() { + try { + Ix source = Ix.just(1).transform(new IxTransform() { + @Override + public int moveNext(Iterator it, Action1 out) { + out.call(1); + out.call(2); + return IxTransform.NEXT; + } + }); + + IxTestHelper.assertValues(source); + + Assert.fail("Failed to throw IllegalStateException"); + } catch (IllegalStateException ex) { + Assert.assertEquals("Value already set in this turn!", ex.getMessage()); + } + } + + @Test + public void returnNextWithoutValue() { + try { + Ix source = Ix.just(1).transform(new IxTransform() { + @Override + public int moveNext(Iterator it, Action1 out) { + return IxTransform.NEXT; + } + }); + + IxTestHelper.assertValues(source); + + Assert.fail("Failed to throw IllegalStateException"); + } catch (IllegalStateException ex) { + Assert.assertEquals("No value set!", ex.getMessage()); + } + } +} From 62a5eca52bdecaabf5ce5cb1b6751c6dbb48c75f Mon Sep 17 00:00:00 2001 From: akarnokd Date: Fri, 15 Jul 2016 13:58:24 +0200 Subject: [PATCH 24/66] + window --- src/main/java/ix/Ix.java | 11 +- src/main/java/ix/IxWindow.java | 163 +++++++++++ src/main/java/ix/IxWindowOverlap.java | 211 ++++++++++++++ src/main/java/ix/IxWindowSkip.java | 169 ++++++++++++ src/test/java/ix/WindowTest.java | 381 ++++++++++++++++++++++++++ 5 files changed, 932 insertions(+), 3 deletions(-) create mode 100644 src/main/java/ix/IxWindow.java create mode 100644 src/main/java/ix/IxWindowOverlap.java create mode 100644 src/main/java/ix/IxWindowSkip.java create mode 100644 src/test/java/ix/WindowTest.java diff --git a/src/main/java/ix/Ix.java b/src/main/java/ix/Ix.java index 2dfb185..d2cc625 100644 --- a/src/main/java/ix/Ix.java +++ b/src/main/java/ix/Ix.java @@ -490,12 +490,17 @@ public final Ix>> toMultimap(Func1> window(int size) { - return window(size, size); + return new IxWindow(this, size); } public final Ix> window(int size, int skip) { - // TODO implement - throw new UnsupportedOperationException(); + if (size == skip) { + return window(size); + } + if (size < skip) { + return new IxWindowSkip(this, size, skip); + } + return new IxWindowOverlap(this, size, skip); } @SuppressWarnings("unchecked") diff --git a/src/main/java/ix/IxWindow.java b/src/main/java/ix/IxWindow.java new file mode 100644 index 0000000..5a50837 --- /dev/null +++ b/src/main/java/ix/IxWindow.java @@ -0,0 +1,163 @@ +/* + * Copyright 2011-2016 David Karnok + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ix; + +import java.util.*; + +final class IxWindow extends IxSource> { + + final int size; + + static final Object NULL = new Object(); + + public IxWindow(Iterable source, int size) { + super(source); + this.size = size; + } + + @Override + public Iterator> iterator() { + return new WindowIterator(source.iterator(), size); + } + + static final class WindowIterator extends IxSourceIterator> { + + final int size; + + int index; + + WindowIterable current; + + public WindowIterator(Iterator it, int size) { + super(it); + this.size = size; + } + + @Override + protected boolean moveNext() { + int i = index; + for (;;) { + if (!it.hasNext()) { + done = true; + return false; + } + + T v = it.next(); + + WindowIterable c; + if (i++ == 0) { + if (i == size) { + index = 0; + } else { + index = i; + } + c = new WindowIterable(this, size); + current = c; + c.iterator.queue.offer(v != null ? v : NULL); + value = c; + hasValue = true; + return true; + } + + current.iterator.queue.offer(v != null ? v : NULL); + + if (i == size) { + i = 0; + } + } + } + + boolean moveInner() { + if (!it.hasNext()) { + return false; + } + + T v = it.next(); + + current.iterator.queue.offer(v != null ? v : NULL); + + int i = index + 1; + if (i == size) { + current = null; + index = 0; + } else { + index = i; + } + return true; + } + } + + static final class WindowIterable extends Ix { + + final WindowInnerIterator iterator; + + boolean once; + + public WindowIterable(WindowIterator parent, int size) { + this.iterator = new WindowInnerIterator(parent, size); + } + + @Override + public Iterator iterator() { + if (!once) { + once = true; + return iterator; + } + throw new IllegalStateException("This Window Ix iterable can be consumed only once."); + } + } + + static final class WindowInnerIterator extends IxBaseIterator { + + final WindowIterator parent; + + final ArrayDeque queue; + + int remaining; + + public WindowInnerIterator(WindowIterator parent, int remaining) { + this.parent = parent; + this.queue = new ArrayDeque(); + this.remaining = remaining; + } + + @SuppressWarnings("unchecked") + @Override + protected boolean moveNext() { + int r = remaining; + if (r == 0) { + done = true; + return false; + } + Object o = queue.poll(); + + if (o == null) { + if (!parent.moveInner()) { + done = true; + return false; + } + o = queue.poll(); + } + + value = o == NULL ? null : (T)o; + hasValue = true; + remaining = r - 1; + return true; + } + } + +} diff --git a/src/main/java/ix/IxWindowOverlap.java b/src/main/java/ix/IxWindowOverlap.java new file mode 100644 index 0000000..83f2b5f --- /dev/null +++ b/src/main/java/ix/IxWindowOverlap.java @@ -0,0 +1,211 @@ +/* + * Copyright 2011-2016 David Karnok + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ix; + +import java.util.*; + +final class IxWindowOverlap extends IxSource> { + + final int size; + + final int skip; + + static final Object NULL = new Object(); + + public IxWindowOverlap(Iterable source, int size, int skip) { + super(source); + this.size = size; + this.skip = skip; + } + + @Override + public Iterator> iterator() { + return new WindowIterator(source.iterator(), size, skip); + } + + static final class WindowIterator extends IxSourceIterator> { + + final int size; + + final int skip; + + final Queue> queue; + + final Queue> windows; + + int index; + + int headSize; + + public WindowIterator(Iterator it, int size, int skip) { + super(it); + this.size = size; + this.skip = skip; + this.queue = new ArrayDeque>(); + this.windows = new ArrayDeque>(); + } + + @Override + protected boolean moveNext() { + WindowIterable w = queue.poll(); + if (w == null) { + if (!moveMain()) { + done = true; + return false; + } + w = queue.poll(); + } + + value = w; + hasValue = true; + return true; + } + + boolean moveMain() { + int i = index; + for (;;) { + if (!it.hasNext()) { + return false; + } + + T v = it.next(); + + for (WindowIterable c : windows) { + c.iterator.offer(v); + } + + int j = headSize + 1; + if (j == size) { + windows.poll(); + headSize = j - skip; + } else { + headSize = j; + } + + if (i++ == 0) { + if (i == skip) { + index = 0; + } else { + index = i; + } + WindowIterable c = new WindowIterable(this, size); + c.iterator.offer(v); + queue.offer(c); + windows.offer(c); + + return true; + } + + if (i == skip) { + i = 0; + } + } + } + + boolean moveInner() { + int i = index; + if (!it.hasNext()) { + return false; + } + + T v = it.next(); + + for (WindowIterable c : windows) { + c.iterator.offer(v); + } + + int j = headSize + 1; + if (j == size) { + windows.poll(); + headSize = j - skip; + } else { + headSize = j; + } + + if (i++ == 0) { + WindowIterable c = new WindowIterable(this, size); + c.iterator.offer(v); + queue.offer(c); + windows.offer(c); + } + + if (i == skip) { + index = 0; + } + return true; + } + } + + static final class WindowIterable extends Ix { + + final WindowInnerIterator iterator; + + boolean once; + + public WindowIterable(WindowIterator parent, int size) { + this.iterator = new WindowInnerIterator(parent); + } + + @Override + public Iterator iterator() { + if (!once) { + once = true; + return iterator; + } + throw new IllegalStateException("This Window Ix iterable can be consumed only once."); + } + } + + static final class WindowInnerIterator extends IxBaseIterator { + + final WindowIterator parent; + + final ArrayDeque queue; + + public WindowInnerIterator(WindowIterator parent) { + this.parent = parent; + this.queue = new ArrayDeque(); + } + + @SuppressWarnings("unchecked") + @Override + protected boolean moveNext() { + Object o = queue.poll(); + + if (o == null) { + if (!parent.moveInner()) { + done = true; + return false; + } + o = queue.poll(); + if (o == null) { + done = true; + return false; + } + } + + value = o == NULL ? null : (T)o; + hasValue = true; + return true; + } + + void offer(T v) { + queue.offer(v != null ? v : NULL); + } + } + +} diff --git a/src/main/java/ix/IxWindowSkip.java b/src/main/java/ix/IxWindowSkip.java new file mode 100644 index 0000000..f3fcf6a --- /dev/null +++ b/src/main/java/ix/IxWindowSkip.java @@ -0,0 +1,169 @@ +/* + * Copyright 2011-2016 David Karnok + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ix; + +import java.util.*; + +final class IxWindowSkip extends IxSource> { + + final int size; + + final int skip; + + static final Object NULL = new Object(); + + public IxWindowSkip(Iterable source, int size, int skip) { + super(source); + this.size = size; + this.skip = skip; + } + + @Override + public Iterator> iterator() { + return new WindowIterator(source.iterator(), size, skip); + } + + static final class WindowIterator extends IxSourceIterator> { + + final int size; + + int index; + + final int skip; + + WindowIterable current; + + public WindowIterator(Iterator it, int size, int skip) { + super(it); + this.size = size; + this.skip = skip; + } + + @Override + protected boolean moveNext() { + int i = index; + for (;;) { + if (!it.hasNext()) { + done = true; + return false; + } + + T v = it.next(); + + if (i++ == 0) { + index = i; + WindowIterable c = new WindowIterable(this, size); + current = c; + c.iterator.offer(v); + value = c; + hasValue = true; + return true; + } + + WindowInnerIterator ci = current.iterator; + + if (ci.offered < size) { + ci.offer(v); + } + + if (i == skip) { + i = 0; + } + } + } + + boolean moveInner() { + if (!it.hasNext()) { + return false; + } + + T v = it.next(); + + current.iterator.offer(v); + + index++; + return true; + } + } + + static final class WindowIterable extends Ix { + + final WindowInnerIterator iterator; + + boolean once; + + public WindowIterable(WindowIterator parent, int size) { + this.iterator = new WindowInnerIterator(parent, size); + } + + @Override + public Iterator iterator() { + if (!once) { + once = true; + return iterator; + } + throw new IllegalStateException("This Window Ix iterable can be consumed only once."); + } + } + + static final class WindowInnerIterator extends IxBaseIterator { + + final WindowIterator parent; + + final ArrayDeque queue; + + int remaining; + + int offered; + + public WindowInnerIterator(WindowIterator parent, int size) { + this.parent = parent; + this.queue = new ArrayDeque(); + this.remaining = size; + } + + @SuppressWarnings("unchecked") + @Override + protected boolean moveNext() { + int r = remaining; + if (r == 0) { + done = true; + return false; + } + Object o = queue.poll(); + + if (o == null) { + if (!parent.moveInner()) { + done = true; + return false; + } + o = queue.poll(); + } + + value = o == NULL ? null : (T)o; + hasValue = true; + remaining = r - 1; + return true; + } + + void offer(T t) { + offered++; + queue.offer(t != null ? t : NULL); + } + } + +} diff --git a/src/test/java/ix/WindowTest.java b/src/test/java/ix/WindowTest.java new file mode 100644 index 0000000..d9974ea --- /dev/null +++ b/src/test/java/ix/WindowTest.java @@ -0,0 +1,381 @@ +/* + * Copyright 2011-2016 David Karnok + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ix; + +import java.util.*; + +import org.junit.*; + +public class WindowTest { + + @Test + public void normal() { + Ix> source = Ix.range(1, 5).window(2); + + List> list = source.toList().first(); + + Assert.assertEquals(3, list.size()); + IxTestHelper.assertValues(list.get(0), 1, 2); + IxTestHelper.assertValues(list.get(1), 3, 4); + IxTestHelper.assertValues(list.get(2), 5); + } + + @Test + public void normalSizeSkipSame() { + Ix> source = Ix.range(1, 5).window(2, 2); + + List> list = source.toList().first(); + + Assert.assertEquals(3, list.size()); + IxTestHelper.assertValues(list.get(0), 1, 2); + IxTestHelper.assertValues(list.get(1), 3, 4); + IxTestHelper.assertValues(list.get(2), 5); + } + + @Test + public void normalOne() { + Ix> source = Ix.range(1, 5).window(1); + + List> list = source.toList().first(); + + Assert.assertEquals(5, list.size()); + IxTestHelper.assertValues(list.get(0), 1); + IxTestHelper.assertValues(list.get(1), 2); + IxTestHelper.assertValues(list.get(2), 3); + IxTestHelper.assertValues(list.get(3), 4); + IxTestHelper.assertValues(list.get(4), 5); + } + + @Test + public void normalAll() { + Ix> source = Ix.range(1, 5).window(5); + + List> list = source.toList().first(); + + Assert.assertEquals(1, list.size()); + IxTestHelper.assertValues(list.get(0), 1, 2, 3, 4, 5); + } + + @Test + public void normalMore() { + Ix> source = Ix.range(1, 5).window(10); + + List> list = source.toList().first(); + + Assert.assertEquals(1, list.size()); + IxTestHelper.assertValues(list.get(0), 1, 2, 3, 4, 5); + } + + @Test + public void innerMovesParent() { + + Ix> source = Ix.range(1, 5).window(3); + + Iterator> it0 = source.iterator(); + + Ix inner = it0.next(); + + Iterator it1 = inner.iterator(); + + try { + inner.iterator(); + Assert.fail("Should have thrown IllegalStateException"); + } catch (IllegalStateException ex) { + Assert.assertEquals("This Window Ix iterable can be consumed only once.", ex.getMessage()); + } + Assert.assertEquals(1, it1.next().intValue()); + Assert.assertEquals(2, it1.next().intValue()); + Assert.assertEquals(3, it1.next().intValue()); + Assert.assertFalse(it1.hasNext()); + + } + + @Test + public void normalSkip() { + Ix> source = Ix.range(1, 5).window(2, 3); + + List> list = source.toList().first(); + + Assert.assertEquals(2, list.size()); + IxTestHelper.assertValues(list.get(0), 1, 2); + IxTestHelper.assertValues(list.get(1), 4, 5); + } + + @Test + public void normalSkip2() { + Ix> source = Ix.range(1, 5).window(1, 2); + + List> list = source.toList().first(); + + Assert.assertEquals(3, list.size()); + IxTestHelper.assertValues(list.get(0), 1); + IxTestHelper.assertValues(list.get(1), 3); + IxTestHelper.assertValues(list.get(2), 5); + } + + @Test + public void normalSkip3() { + Ix> source = Ix.range(1, 5).window(1, 6); + + List> list = source.toList().first(); + + Assert.assertEquals(1, list.size()); + IxTestHelper.assertValues(list.get(0), 1); + } + + @Test + public void normalAllSkip() { + Ix> source = Ix.range(1, 5).window(5, 10); + + List> list = source.toList().first(); + + Assert.assertEquals(1, list.size()); + IxTestHelper.assertValues(list.get(0), 1, 2, 3, 4, 5); + } + + @Test + public void normalMoreSkip() { + Ix> source = Ix.range(1, 5).window(10, 15); + + List> list = source.toList().first(); + + Assert.assertEquals(1, list.size()); + IxTestHelper.assertValues(list.get(0), 1, 2, 3, 4, 5); + } + + @Test + public void justSkip() { + Ix> source = Ix.just(1).window(2, 3); + + List> list = source.toList().first(); + + Assert.assertEquals(1, list.size()); + IxTestHelper.assertValues(list.get(0), 1); + } + + @Test + public void emptySkip() { + Ix> source = Ix.empty().window(2, 3); + + List> list = source.toList().first(); + + Assert.assertEquals(0, list.size()); + } + + @Test + public void skipInnerMovesParent() { + + Ix> source = Ix.range(1, 5).window(2, 3); + + Iterator> it0 = source.iterator(); + + Ix inner = it0.next(); + + Iterator it1 = inner.iterator(); + + try { + inner.iterator(); + Assert.fail("Should have thrown IllegalStateException"); + } catch (IllegalStateException ex) { + Assert.assertEquals("This Window Ix iterable can be consumed only once.", ex.getMessage()); + } + Assert.assertEquals(1, it1.next().intValue()); + Assert.assertEquals(2, it1.next().intValue()); + Assert.assertFalse(it1.hasNext()); + + inner = it0.next(); + it1 = inner.iterator(); + + Assert.assertEquals(4, it1.next().intValue()); + Assert.assertEquals(5, it1.next().intValue()); + Assert.assertFalse(it1.hasNext()); + + Assert.assertFalse(it0.hasNext()); + } + + @Test + public void normalOverlap() { + Ix> source = Ix.range(1, 5).window(2, 1); + + List> list = source.toList().first(); + + Assert.assertEquals(5, list.size()); + IxTestHelper.assertValues(list.get(0), 1, 2); + IxTestHelper.assertValues(list.get(1), 2, 3); + IxTestHelper.assertValues(list.get(2), 3, 4); + IxTestHelper.assertValues(list.get(3), 4, 5); + IxTestHelper.assertValues(list.get(4), 5); + } + + @Test + public void normalOverlap2() { + Ix> source = Ix.range(1, 5).window(3, 1); + + List> list = source.toList().first(); + + Assert.assertEquals(5, list.size()); + IxTestHelper.assertValues(list.get(0), 1, 2, 3); + IxTestHelper.assertValues(list.get(1), 2, 3, 4); + IxTestHelper.assertValues(list.get(2), 3, 4, 5); + IxTestHelper.assertValues(list.get(3), 4, 5); + IxTestHelper.assertValues(list.get(4), 5); + } + + @Test + public void normalOverlap3() { + Ix> source = Ix.range(1, 5).window(3, 2); + + List> list = source.toList().first(); + + Assert.assertEquals(3, list.size()); + IxTestHelper.assertValues(list.get(0), 1, 2, 3); + IxTestHelper.assertValues(list.get(1), 3, 4, 5); + IxTestHelper.assertValues(list.get(2), 5); + } + + @Test + public void nullExact() { + Ix> source = Ix.fromArray(null, null, null, null, null).window(2); + + List> list = source.toList().first(); + + Assert.assertEquals(3, list.size()); + IxTestHelper.assertValues(list.get(0), null, null); + IxTestHelper.assertValues(list.get(1), null, null); + IxTestHelper.assertValues(list.get(2), (Integer)null); + } + + @Test + public void nullExact2() { + Ix> source = Ix.fromArray(null, null, null, null, null).window(6); + + Iterator list = source.iterator().next().iterator(); + + Assert.assertNull(list.next()); + Assert.assertNull(list.next()); + Assert.assertNull(list.next()); + Assert.assertNull(list.next()); + Assert.assertNull(list.next()); + Assert.assertFalse(list.hasNext()); + } + + @Test + public void nullSkip() { + Ix> source = Ix.fromArray(null, null, null, null, null).window(2, 3); + + List> list = source.toList().first(); + + Assert.assertEquals(2, list.size()); + IxTestHelper.assertValues(list.get(0), null, null); + IxTestHelper.assertValues(list.get(1), null, null); + } + + @Test + public void nullOverlap() { + Ix> source = Ix.fromArray(null, null, null, null, null).window(2, 1); + + List> list = source.toList().first(); + + Assert.assertEquals(5, list.size()); + IxTestHelper.assertValues(list.get(0), null, null); + IxTestHelper.assertValues(list.get(1), null, null); + IxTestHelper.assertValues(list.get(2), null, null); + IxTestHelper.assertValues(list.get(3), null, null); + IxTestHelper.assertValues(list.get(4), (Integer)null); + } + + @Test + public void overlapInnerMovesParent() { + + Ix> source = Ix.range(1, 5).window(2, 1); + + Iterator> it0 = source.iterator(); + + Ix inner = it0.next(); + + Iterator it1 = inner.iterator(); + + try { + inner.iterator(); + Assert.fail("Should have thrown IllegalStateException"); + } catch (IllegalStateException ex) { + Assert.assertEquals("This Window Ix iterable can be consumed only once.", ex.getMessage()); + } + Assert.assertEquals(1, it1.next().intValue()); + Assert.assertEquals(2, it1.next().intValue()); + Assert.assertFalse(it1.hasNext()); + + inner = it0.next(); + it1 = inner.iterator(); + + Assert.assertEquals(2, it1.next().intValue()); + Assert.assertEquals(3, it1.next().intValue()); + Assert.assertFalse(it1.hasNext()); + + Assert.assertTrue(it0.hasNext()); + } + + @Test + public void overlapInnerMovesParent2() { + + Ix> source = Ix.range(1, 5).window(3, 2); + + Iterator> it0 = source.iterator(); + + Ix inner = it0.next(); + + Iterator it1 = inner.iterator(); + + try { + inner.iterator(); + Assert.fail("Should have thrown IllegalStateException"); + } catch (IllegalStateException ex) { + Assert.assertEquals("This Window Ix iterable can be consumed only once.", ex.getMessage()); + } + Assert.assertEquals(1, it1.next().intValue()); + Assert.assertEquals(2, it1.next().intValue()); + Assert.assertEquals(3, it1.next().intValue()); + Assert.assertFalse(it1.hasNext()); + + inner = it0.next(); + it1 = inner.iterator(); + + Assert.assertEquals(3, it1.next().intValue()); + Assert.assertEquals(4, it1.next().intValue()); + Assert.assertEquals(5, it1.next().intValue()); + Assert.assertFalse(it1.hasNext()); + + Assert.assertTrue(it0.hasNext()); + } + + @Test + public void overlapParentMoved() { + + Ix> source = Ix.range(1, 5).window(4, 3); + + Iterator> it0 = source.iterator(); + + Ix inner1 = it0.next(); + Ix inner2 = it0.next(); + + Assert.assertFalse(it0.hasNext()); + + IxTestHelper.assertValues(inner1, 1, 2, 3, 4); + IxTestHelper.assertValues(inner2, 4, 5); + } + +} From 87c8a4df8fd20e8876277f346237210af2e228ce Mon Sep 17 00:00:00 2001 From: akarnokd Date: Fri, 15 Jul 2016 16:05:17 +0200 Subject: [PATCH 25/66] Add final set of operators --- src/main/java/ix/Ix.java | 24 +-- src/main/java/ix/IxPublish.java | 39 ++++ src/main/java/ix/IxPublishSelector.java | 52 ++++++ src/main/java/ix/IxReplay.java | 84 +++++++++ src/main/java/ix/IxReplaySelector.java | 38 ++++ src/main/java/ix/IxReplaySize.java | 104 +++++++++++ src/main/java/ix/IxReplaySizeSelector.java | 42 +++++ src/main/java/ix/IxZip2.java | 6 +- src/main/java/ix/IxZip3.java | 8 +- src/main/java/ix/IxZip4.java | 10 +- src/test/java/ix/PublishTest.java | 94 ++++++++++ src/test/java/ix/ReplayTest.java | 201 +++++++++++++++++++++ 12 files changed, 684 insertions(+), 18 deletions(-) create mode 100644 src/main/java/ix/IxPublish.java create mode 100644 src/main/java/ix/IxPublishSelector.java create mode 100644 src/main/java/ix/IxReplay.java create mode 100644 src/main/java/ix/IxReplaySelector.java create mode 100644 src/main/java/ix/IxReplaySize.java create mode 100644 src/main/java/ix/IxReplaySizeSelector.java create mode 100644 src/test/java/ix/PublishTest.java create mode 100644 src/test/java/ix/ReplayTest.java diff --git a/src/main/java/ix/Ix.java b/src/main/java/ix/Ix.java index d2cc625..4215a6c 100644 --- a/src/main/java/ix/Ix.java +++ b/src/main/java/ix/Ix.java @@ -442,33 +442,27 @@ public final Ix repeat(long times, Pred0 predicate) { } public final Ix publish() { - // TODO implement - throw new UnsupportedOperationException(); + return new IxPublish(this); } - public final Ix publish(Func1, ? extends Iterator> transform) { - // TODO implement - throw new UnsupportedOperationException(); + public final Ix publish(Func1, ? extends Iterable> transform) { + return new IxPublishSelector(this, transform); } public final Ix replay() { - // TODO implement - throw new UnsupportedOperationException(); + return new IxReplay(this); } public final Ix replay(int size) { - // TODO implement - throw new UnsupportedOperationException(); + return new IxReplaySize(this, size); } - public final Ix replay(Func1, ? extends Iterator> transform) { - // TODO implement - throw new UnsupportedOperationException(); + public final Ix replay(Func1, ? extends Iterable> transform) { + return new IxReplaySelector(this, transform); } - public final Ix replay(int size, Func1, ? extends Iterator> transform) { - // TODO implement - throw new UnsupportedOperationException(); + public final Ix replay(int size, Func1, ? extends Iterable> transform) { + return new IxReplaySizeSelector(this, size, transform); } public final Ix> toMap(Func1 keySelector) { diff --git a/src/main/java/ix/IxPublish.java b/src/main/java/ix/IxPublish.java new file mode 100644 index 0000000..74651e6 --- /dev/null +++ b/src/main/java/ix/IxPublish.java @@ -0,0 +1,39 @@ +/* + * Copyright 2011-2016 David Karnok + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ix; + +import java.util.Iterator; + +final class IxPublish extends IxSource { + + Iterator current; + + public IxPublish(Iterable source) { + super(source); + } + + @Override + public Iterator iterator() { + Iterator c = current; + if (c == null) { + c = source.iterator(); + current = c; + } + return c; + } + +} diff --git a/src/main/java/ix/IxPublishSelector.java b/src/main/java/ix/IxPublishSelector.java new file mode 100644 index 0000000..7ae68d8 --- /dev/null +++ b/src/main/java/ix/IxPublishSelector.java @@ -0,0 +1,52 @@ +/* + * Copyright 2011-2016 David Karnok + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ix; + +import java.util.Iterator; + +import rx.functions.Func1; + +final class IxPublishSelector extends IxSource { + + final Func1, ? extends Iterable> selector; + + public IxPublishSelector(Iterable source, Func1, ? extends Iterable> selector) { + super(source); + this.selector = selector; + } + + @SuppressWarnings("unchecked") + @Override + public Iterator iterator() { + + return (Iterator)selector.call(new PublishSelectorIterable(source.iterator())).iterator(); + } + + static final class PublishSelectorIterable extends Ix { + + final Iterator source; + + public PublishSelectorIterable(Iterator source) { + this.source = source; + } + + @Override + public Iterator iterator() { + return source; + } + } +} diff --git a/src/main/java/ix/IxReplay.java b/src/main/java/ix/IxReplay.java new file mode 100644 index 0000000..7226409 --- /dev/null +++ b/src/main/java/ix/IxReplay.java @@ -0,0 +1,84 @@ +/* + * Copyright 2011-2016 David Karnok + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ix; + +import java.util.*; + +final class IxReplay extends IxSource { + + List list; + + Iterator it; + + public IxReplay(Iterable source) { + super(source); + } + + @Override + public Iterator iterator() { + if (it == null) { + it = source.iterator(); + } + return new ReplayIterator(this); + } + + boolean moveNext() { + if (!it.hasNext()) { + return false; + } + + List list = this.list; + if (list == null) { + list = new ArrayList(); + this.list = list; + } + + list.add(it.next()); + return true; + } + + static final class ReplayIterator extends IxBaseIterator { + + final IxReplay parent; + + int index; + + public ReplayIterator(IxReplay parent) { + this.parent = parent; + } + + @Override + protected boolean moveNext() { + int i = index; + List list = parent.list; + + if (list == null || i == list.size()) { + if (!parent.moveNext()) { + done = true; + return false; + } + if (list == null) { + list = parent.list; + } + } + index = i + 1; + value = list.get(i); + hasValue = true; + return true; + } + } +} diff --git a/src/main/java/ix/IxReplaySelector.java b/src/main/java/ix/IxReplaySelector.java new file mode 100644 index 0000000..d8041cb --- /dev/null +++ b/src/main/java/ix/IxReplaySelector.java @@ -0,0 +1,38 @@ +/* + * Copyright 2011-2016 David Karnok + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ix; + +import java.util.Iterator; + +import rx.functions.Func1; + +final class IxReplaySelector extends IxSource { + + final Func1, ? extends Iterable> selector; + + public IxReplaySelector(Iterable source, Func1, ? extends Iterable> selector) { + super(source); + this.selector = selector; + } + + @SuppressWarnings("unchecked") + @Override + public Iterator iterator() { + + return (Iterator)selector.call(new IxReplay(source)).iterator(); + } +} diff --git a/src/main/java/ix/IxReplaySize.java b/src/main/java/ix/IxReplaySize.java new file mode 100644 index 0000000..778e248 --- /dev/null +++ b/src/main/java/ix/IxReplaySize.java @@ -0,0 +1,104 @@ +/* + * Copyright 2011-2016 David Karnok + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ix; + +import java.util.Iterator; + +final class IxReplaySize extends IxSource { + + final int maxSize; + + Iterator it; + + Node head; + + Node tail; + + int size; + + public IxReplaySize(Iterable source, int maxSize) { + super(source); + this.maxSize = maxSize; + this.head = this.tail = new Node(null); + } + + @Override + public Iterator iterator() { + if (it == null) { + it = source.iterator(); + } + return new ReplaySizeIterator(this, head); + } + + boolean moveNext() { + if (!it.hasNext()) { + return false; + } + + Node n = new Node(it.next()); + tail.next = n; + tail = n; + + int s = size; + if (s != maxSize) { + size = s + 1; + } else { + head = head.next; + } + return true; + } + + static final class Node { + final T value; + + Node next; + + public Node(T value) { + this.value = value; + } + } + + static final class ReplaySizeIterator extends IxBaseIterator { + final IxReplaySize parent; + + Node node; + + public ReplaySizeIterator(IxReplaySize parent, Node node) { + this.parent = parent; + this.node = node; + } + + @Override + protected boolean moveNext() { + Node n = node; + + if (n.next == null) { + if (!parent.moveNext()) { + done = true; + return false; + } + } + n = n.next; + + value = n.value; + hasValue = true; + node = n; + + return true; + } + } +} diff --git a/src/main/java/ix/IxReplaySizeSelector.java b/src/main/java/ix/IxReplaySizeSelector.java new file mode 100644 index 0000000..11dca1d --- /dev/null +++ b/src/main/java/ix/IxReplaySizeSelector.java @@ -0,0 +1,42 @@ +/* + * Copyright 2011-2016 David Karnok + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ix; + +import java.util.Iterator; + +import rx.functions.Func1; + +final class IxReplaySizeSelector extends IxSource { + + final int maxSize; + + final Func1, ? extends Iterable> selector; + + public IxReplaySizeSelector(Iterable source, int maxSize, + Func1, ? extends Iterable> selector) { + super(source); + this.maxSize = maxSize; + this.selector = selector; + } + + @SuppressWarnings("unchecked") + @Override + public Iterator iterator() { + + return (Iterator)selector.call(new IxReplaySize(source, maxSize)).iterator(); + } +} diff --git a/src/main/java/ix/IxZip2.java b/src/main/java/ix/IxZip2.java index abd0629..3027463 100644 --- a/src/main/java/ix/IxZip2.java +++ b/src/main/java/ix/IxZip2.java @@ -60,12 +60,16 @@ protected boolean moveNext() { return false; } + T1 t1 = source1.next(); + if (!source2.hasNext()) { done = true; return false; } + + T2 t2 = source2.next(); - value = zipper.call(source1.next(), source2.next()); + value = zipper.call(t1, t2); hasValue = true; return true; } diff --git a/src/main/java/ix/IxZip3.java b/src/main/java/ix/IxZip3.java index 334fb7a..99b23e4 100644 --- a/src/main/java/ix/IxZip3.java +++ b/src/main/java/ix/IxZip3.java @@ -68,17 +68,23 @@ protected boolean moveNext() { return false; } + T1 t1 = source1.next(); + if (!source2.hasNext()) { done = true; return false; } + T2 t2 = source2.next(); + if (!source3.hasNext()) { done = true; return false; } - value = zipper.call(source1.next(), source2.next(), source3.next()); + T3 t3 = source3.next(); + + value = zipper.call(t1, t2, t3); hasValue = true; return true; } diff --git a/src/main/java/ix/IxZip4.java b/src/main/java/ix/IxZip4.java index d243217..b49d385 100644 --- a/src/main/java/ix/IxZip4.java +++ b/src/main/java/ix/IxZip4.java @@ -76,22 +76,30 @@ protected boolean moveNext() { return false; } + T1 t1 = source1.next(); + if (!source2.hasNext()) { done = true; return false; } + T2 t2 = source2.next(); + if (!source3.hasNext()) { done = true; return false; } + T3 t3 = source3.next(); + if (!source4.hasNext()) { done = true; return false; } - value = zipper.call(source1.next(), source2.next(), source3.next(), source4.next()); + T4 t4 = source4.next(); + + value = zipper.call(t1, t2, t3, t4); hasValue = true; return true; } diff --git a/src/test/java/ix/PublishTest.java b/src/test/java/ix/PublishTest.java new file mode 100644 index 0000000..4431c39 --- /dev/null +++ b/src/test/java/ix/PublishTest.java @@ -0,0 +1,94 @@ +/* + * Copyright 2011-2016 David Karnok + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ix; + +import java.util.Iterator; + +import org.junit.*; + +import rx.functions.*; + +public class PublishTest { + + @Test + public void normal() { + final int[] counter = { 0 }; + Ix source = Ix.range(1, 5) + .doOnNext(new Action1() { + @Override + public void call(Integer v) { + counter[0]++; + } + }) + .publish(); + + Iterator it1 = source.iterator(); + Iterator it2 = source.iterator(); + + Assert.assertEquals(1, it1.next().intValue()); + Assert.assertEquals(2, it2.next().intValue()); + Assert.assertEquals(3, it1.next().intValue()); + Assert.assertEquals(4, it2.next().intValue()); + Assert.assertEquals(5, it1.next().intValue()); + + Assert.assertFalse(it1.hasNext()); + Assert.assertFalse(it2.hasNext()); + + Iterator it3 = source.iterator(); + Assert.assertFalse(it3.hasNext()); + + Assert.assertEquals(5, counter[0]); + } + + @Test + public void selector() { + Ix source = Ix.range(1, 5).publish(new Func1, Iterable>() { + @Override + public Iterable call(Ix o) { + return Ix.zip(o, o.skip(1), new Func2() { + @Override + public Integer call(Integer t1, Integer t2) { + return t1 + t2; + } + }); + } + }) + ; + source.println(); + + IxTestHelper.assertValues(source, 4, 9); + } + + @Test + public void selector2() { + Ix source = Ix.range(1, 5).publish(new Func1, Iterable>() { + @Override + public Iterable call(Ix o) { + return Ix.zip(o, o, new Func2() { + @Override + public Integer call(Integer t1, Integer t2) { + return t1 + t2; + } + }); + } + }) + ; + + IxTestHelper.assertValues(source, 3, 7); + } + +} diff --git a/src/test/java/ix/ReplayTest.java b/src/test/java/ix/ReplayTest.java new file mode 100644 index 0000000..db0ac97 --- /dev/null +++ b/src/test/java/ix/ReplayTest.java @@ -0,0 +1,201 @@ +/* + * Copyright 2011-2016 David Karnok + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ix; + +import java.util.Iterator; + +import org.junit.*; + +import rx.functions.*; + +public class ReplayTest { + + @Test + public void normal() { + final int[] counter = { 0 }; + Ix source = Ix.range(1, 5) + .doOnNext(new Action1() { + @Override + public void call(Integer v) { + counter[0]++; + } + }) + .replay(); + + IxTestHelper.assertValues(source, 1, 2, 3, 4, 5); + IxTestHelper.assertValues(source, 1, 2, 3, 4, 5); + IxTestHelper.assertValues(source, 1, 2, 3, 4, 5); + + Assert.assertEquals(5, counter[0]); + } + + @Test + public void lockstep() { + final int[] counter = { 0 }; + Ix source = Ix.range(1, 5) + .doOnNext(new Action1() { + @Override + public void call(Integer v) { + counter[0]++; + } + }) + .replay(); + + Iterator it1 = source.iterator(); + Iterator it2 = source.iterator(); + + Assert.assertEquals(1, it1.next().intValue()); + Assert.assertEquals(1, it2.next().intValue()); + + Assert.assertEquals(2, it1.next().intValue()); + Assert.assertEquals(2, it2.next().intValue()); + + Assert.assertEquals(3, it1.next().intValue()); + Assert.assertEquals(3, it2.next().intValue()); + + Assert.assertEquals(4, it1.next().intValue()); + Assert.assertEquals(4, it2.next().intValue()); + + Assert.assertEquals(5, it1.next().intValue()); + Assert.assertEquals(5, it2.next().intValue()); + + Assert.assertFalse(it1.hasNext()); + Assert.assertFalse(it1.hasNext()); + + Assert.assertEquals(5, counter[0]); + + } + + @Test + public void empty() { + Ix source = Ix.empty().replay(); + + IxTestHelper.assertValues(source); + IxTestHelper.assertValues(source); + IxTestHelper.assertValues(source); + } + + @Test + public void replaySizeNormal() { + final int[] counter = { 0 }; + Ix source = Ix.range(1, 5) + .doOnNext(new Action1() { + @Override + public void call(Integer v) { + counter[0]++; + } + }) + .replay(10); + + IxTestHelper.assertValues(source, 1, 2, 3, 4, 5); + IxTestHelper.assertValues(source, 1, 2, 3, 4, 5); + IxTestHelper.assertValues(source, 1, 2, 3, 4, 5); + + Assert.assertEquals(5, counter[0]); + } + + @Test + public void replaySizeLimit() { + final int[] counter = { 0 }; + Ix source = Ix.range(1, 5) + .doOnNext(new Action1() { + @Override + public void call(Integer v) { + counter[0]++; + } + }) + .replay(2); + + IxTestHelper.assertValues(source, 1, 2, 3, 4, 5); + IxTestHelper.assertValues(source, 4, 5); + IxTestHelper.assertValues(source, 4, 5); + + Assert.assertEquals(5, counter[0]); + } + + @Test + public void replaySelectorNormal() { + + Ix source = Ix.range(1, 5).replay(new Func1, Iterable>() { + @Override + public Iterable call(Ix o) { + return Ix.zip(o, o.skip(1), new Func2() { + @Override + public Integer call(Integer t1, Integer t2) { + return t1 + t2; + } + }); + } + }); + + IxTestHelper.assertValues(source, 3, 5, 7, 9); + IxTestHelper.assertValues(source, 3, 5, 7, 9); + } + + @Test + public void replaySizeSelectorLarge() { + + Ix source = Ix.range(1, 5).replay(10, new Func1, Iterable>() { + @Override + public Iterable call(Ix o) { + return Ix.zip(o, o.skip(1), new Func2() { + @Override + public Integer call(Integer t1, Integer t2) { + return t1 + t2; + } + }); + } + }); + + IxTestHelper.assertValues(source, 3, 5, 7, 9); + IxTestHelper.assertValues(source, 3, 5, 7, 9); + } + + @Test + public void replaySizeSelectorSmall() { + + Ix source = Ix.range(1, 5).replay(2, new Func1, Iterable>() { + @Override + public Iterable call(Ix o) { + return Ix.zip(o, o.skip(1), new Func2() { + @Override + public Integer call(Integer t1, Integer t2) { + return t1 + t2; + } + }); + } + }); + + IxTestHelper.assertValues(source, 3, 5, 7, 9); + IxTestHelper.assertValues(source, 3, 5, 7, 9); + } + + @Test + public void replaySizeSelectorInnerEffect() { + + Ix source = Ix.range(1, 5).replay(2, new Func1, Iterable>() { + @SuppressWarnings("unchecked") + @Override + public Iterable call(Ix o) { + return Ix.concatArray(o, o); + } + }); + + IxTestHelper.assertValues(source, 1, 2, 3, 4, 5, 4, 5); + IxTestHelper.assertValues(source, 1, 2, 3, 4, 5, 4, 5); + } +} From 6c8cd22cf66270b938a2e58539a273376f71e2be Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?D=C3=A1vid=20Karnok?= Date: Fri, 15 Jul 2016 20:23:36 +0200 Subject: [PATCH 26/66] Added some operators from Ix.NET --- src/main/java/ix/Ix.java | 90 ++++++++++++++++++- src/main/java/ix/IxAverageDouble.java | 61 +++++++++++++ src/main/java/ix/IxAverageFloat.java | 61 +++++++++++++ src/main/java/ix/IxExcept.java | 98 ++++++++++++++++++++ src/main/java/ix/IxIntersect.java | 74 ++++++++++++++++ src/main/java/ix/IxOrderBy.java | 14 ++- src/main/java/ix/IxReverse.java | 66 ++++++++++++++ src/main/java/ix/IxSequenceEqual.java | 95 ++++++++++++++++++++ src/main/java/ix/IxSwitchIfEmpty.java | 99 +++++++++++++++++++++ src/main/java/ix/IxToSet.java | 55 ++++++++++++ src/main/java/ix/IxUnion.java | 82 +++++++++++++++++ src/test/java/ix/AverageTest.java | 77 ++++++++++++++++ src/test/java/ix/ExceptTest.java | 85 ++++++++++++++++++ src/test/java/ix/IntersectTest.java | 68 ++++++++++++++ src/test/java/ix/IxTestHelper.java | 2 +- src/test/java/ix/LeavingTest.java | 25 ++++++ src/test/java/ix/OrderByTest.java | 36 ++++++++ src/test/java/ix/ReverseTest.java | 41 +++++++++ src/test/java/ix/SequenceEqualTest.java | 70 +++++++++++++++ src/test/java/ix/SwitchIfEmptyTest.java | 79 +++++++++++++++++ src/test/java/ix/ToSetTest.java | 55 ++++++++++++ src/test/java/ix/UnionTest.java | 113 ++++++++++++++++++++++++ 22 files changed, 1438 insertions(+), 8 deletions(-) create mode 100644 src/main/java/ix/IxAverageDouble.java create mode 100644 src/main/java/ix/IxAverageFloat.java create mode 100644 src/main/java/ix/IxExcept.java create mode 100644 src/main/java/ix/IxIntersect.java create mode 100644 src/main/java/ix/IxReverse.java create mode 100644 src/main/java/ix/IxSequenceEqual.java create mode 100644 src/main/java/ix/IxSwitchIfEmpty.java create mode 100644 src/main/java/ix/IxToSet.java create mode 100644 src/main/java/ix/IxUnion.java create mode 100644 src/test/java/ix/AverageTest.java create mode 100644 src/test/java/ix/ExceptTest.java create mode 100644 src/test/java/ix/IntersectTest.java create mode 100644 src/test/java/ix/ReverseTest.java create mode 100644 src/test/java/ix/SequenceEqualTest.java create mode 100644 src/test/java/ix/SwitchIfEmptyTest.java create mode 100644 src/test/java/ix/ToSetTest.java create mode 100644 src/test/java/ix/UnionTest.java diff --git a/src/main/java/ix/Ix.java b/src/main/java/ix/Ix.java index 4215a6c..aaa85f5 100644 --- a/src/main/java/ix/Ix.java +++ b/src/main/java/ix/Ix.java @@ -25,7 +25,7 @@ import rx.functions.*; /** - * Base class and entry point for fluent iterables. + * Base class and entry point for fluent Iterables. * * @param the value type * @since 1.0 @@ -516,13 +516,26 @@ public final Ix orderBy() { } public final Ix orderBy(Comparator comparator) { - return new IxOrderBy(this, IdentityHelper.instance(), comparator); + return new IxOrderBy(this, IdentityHelper.instance(), comparator, 1); } public final > Ix orderBy(Func1 keySelector) { - return new IxOrderBy(this, keySelector, SelfComparator.INSTANCE); + return new IxOrderBy(this, keySelector, SelfComparator.INSTANCE, 1); + } + + @SuppressWarnings({ "unchecked", "rawtypes" }) + public final Ix orderByReverse() { + return orderByReverse((Comparator)SelfComparator.INSTANCE); } + public final Ix orderByReverse(Comparator comparator) { + return new IxOrderBy(this, IdentityHelper.instance(), comparator, -1); + } + + public final > Ix orderByReverse(Func1 keySelector) { + return new IxOrderBy(this, keySelector, SelfComparator.INSTANCE, -1); + } + public final Ix scan(Func2 scanner) { return new IxScan(this, scanner); } @@ -546,6 +559,52 @@ public final Ix transform(IxTransform transformer) { public final Ix lift(Func1, ? extends Iterator> lifter) { return new IxLift(this, lifter); } + + @SuppressWarnings("unchecked") + public final Ix averageFloat() { + return new IxAverageFloat((Iterable)this); + } + + @SuppressWarnings("unchecked") + public final Ix averageDouble() { + return new IxAverageDouble((Iterable)this); + } + + public final Ix defaultIfEmpty(T value) { + return switchIfEmpty(Ix.just(value)); + } + + public final Ix switchIfEmpty(Iterable other) { + return new IxSwitchIfEmpty(this, other); + } + + public final Ix except(Iterable other) { + return new IxExcept(this, other); + } + + public final Ix intersect(Iterable other) { + return new IxIntersect(this, other); + } + + public final Ix reverse() { + return new IxReverse(this); + } + + public final Ix sequenceEqual(Iterable other) { + return sequenceEqual(other, EqualityHelper.INSTANCE); + } + + public final Ix sequenceEqual(Iterable other, Pred2 comparer) { + return new IxSequenceEqual(this, other, comparer); + } + + public final Ix> toSet() { + return new IxToSet(this); + } + + public final Ix union(Iterable other) { + return new IxUnion(this, other); + } //--------------------------------------------------------------------------------------- // Leaving the Iterable world @@ -807,6 +866,31 @@ public final void removeAll(Pred predicate) { } } + + public final T single() { + Iterator it = iterator(); + if (it.hasNext()) { + T v = it.next(); + if (it.hasNext()) { + throw new IndexOutOfBoundsException("The source has more than one element."); + } + return v; + } + throw new NoSuchElementException("The source is empty."); + } + + public final T single(T defaultValue) { + Iterator it = iterator(); + if (it.hasNext()) { + T v = it.next(); + if (it.hasNext()) { + throw new IndexOutOfBoundsException("The source has more than one element."); + } + return v; + } + return defaultValue; + } + // -------------------------------------------------------------------------------------------- // Helper methods // -------------------------------------------------------------------------------------------- diff --git a/src/main/java/ix/IxAverageDouble.java b/src/main/java/ix/IxAverageDouble.java new file mode 100644 index 0000000..6de30b6 --- /dev/null +++ b/src/main/java/ix/IxAverageDouble.java @@ -0,0 +1,61 @@ +/* + * Copyright 2011-2016 David Karnok + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ix; + +import java.util.Iterator; + +final class IxAverageDouble extends IxSource { + + public IxAverageDouble(Iterable source) { + super(source); + } + + @Override + public Iterator iterator() { + return new AverageFloatIterator(source.iterator()); + } + + static final class AverageFloatIterator extends IxSourceIterator { + + public AverageFloatIterator(Iterator it) { + super(it); + } + + @Override + protected boolean moveNext() { + Iterator it = this.it; + + double accumulator = 0f; + long count = 0; + + if (!it.hasNext()) { + done = true; + return false; + } + + do { + accumulator += it.next().doubleValue(); + count++; + } while (it.hasNext()); + + value = accumulator / count; + hasValue = true; + done = true; + return true; + } + } +} diff --git a/src/main/java/ix/IxAverageFloat.java b/src/main/java/ix/IxAverageFloat.java new file mode 100644 index 0000000..cd3f05e --- /dev/null +++ b/src/main/java/ix/IxAverageFloat.java @@ -0,0 +1,61 @@ +/* + * Copyright 2011-2016 David Karnok + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ix; + +import java.util.Iterator; + +final class IxAverageFloat extends IxSource { + + public IxAverageFloat(Iterable source) { + super(source); + } + + @Override + public Iterator iterator() { + return new AverageFloatIterator(source.iterator()); + } + + static final class AverageFloatIterator extends IxSourceIterator { + + public AverageFloatIterator(Iterator it) { + super(it); + } + + @Override + protected boolean moveNext() { + Iterator it = this.it; + + float accumulator = 0f; + int count = 0; + + if (!it.hasNext()) { + done = true; + return false; + } + + do { + accumulator += it.next().floatValue(); + count++; + } while (it.hasNext()); + + value = accumulator / count; + hasValue = true; + done = true; + return true; + } + } +} diff --git a/src/main/java/ix/IxExcept.java b/src/main/java/ix/IxExcept.java new file mode 100644 index 0000000..a8380ee --- /dev/null +++ b/src/main/java/ix/IxExcept.java @@ -0,0 +1,98 @@ +/* + * Copyright 2011-2016 David Karnok + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ix; + +import java.util.*; +import java.util.Map.Entry; + +final class IxExcept extends IxSource { + + final Iterable other; + + public IxExcept(Iterable source, Iterable other) { + super(source); + this.other = other; + } + + @Override + public Iterator iterator() { + return new ExceptIterator(source.iterator(), other.iterator()); + } + + static final class ExceptIterator extends IxSourceIterator { + final Iterator other; + + final LinkedHashMap set; + + Iterator> setIterator; + + boolean once; + + boolean second; + + public ExceptIterator(Iterator it, Iterator other) { + super(it); + this.other = other; + this.set = new LinkedHashMap(); + } + + @Override + protected boolean moveNext() { + LinkedHashMap secondSet = set; + if (!once) { + once = true; + while (other.hasNext()) { + secondSet.put(other.next(), true); + } + } + + for (;;) { + if (second) { + Iterator> sIt = setIterator; + while (sIt.hasNext()) { + Entry e = sIt.next(); + + if (e.getValue()) { + value = e.getKey(); + hasValue = true; + return true; + } + } + done = true; + return false; + } else { + Iterator fIt = it; + while (fIt.hasNext()) { + T v = fIt.next(); + + Boolean b = secondSet.get(v); + if (b == null) { + value = v; + hasValue = true; + return true; + } + if (b) { + secondSet.put(v, false); + } + } + second = true; + setIterator = secondSet.entrySet().iterator(); + } + } + } + } +} diff --git a/src/main/java/ix/IxIntersect.java b/src/main/java/ix/IxIntersect.java new file mode 100644 index 0000000..33e1548 --- /dev/null +++ b/src/main/java/ix/IxIntersect.java @@ -0,0 +1,74 @@ +/* + * Copyright 2011-2016 David Karnok + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ix; + +import java.util.*; + +final class IxIntersect extends IxSource { + + final Iterable other; + + public IxIntersect(Iterable source, Iterable other) { + super(source); + this.other = other; + } + + @Override + public Iterator iterator() { + return new IntersectIterator(source.iterator(), other.iterator()); + } + + static final class IntersectIterator extends IxSourceIterator { + final Iterator other; + + final Set set; + + boolean once; + + public IntersectIterator(Iterator it, Iterator other) { + super(it); + this.other = other; + this.set = new HashSet(); + } + + @Override + protected boolean moveNext() { + Set secondSet = set; + if (!once) { + once = true; + Iterator o = other; + while (o.hasNext()) { + secondSet.add(o.next()); + } + } + + Iterator fIt = it; + while (fIt.hasNext()) { + T v = fIt.next(); + + if (secondSet.contains(v)) { + value = v; + hasValue = true; + return true; + } + } + + done = true; + return false; + } + } +} diff --git a/src/main/java/ix/IxOrderBy.java b/src/main/java/ix/IxOrderBy.java index 782a1d3..a57c6df 100644 --- a/src/main/java/ix/IxOrderBy.java +++ b/src/main/java/ix/IxOrderBy.java @@ -26,15 +26,18 @@ final class IxOrderBy extends IxSource { final Comparator comparator; - public IxOrderBy(Iterable source, Func1 keySelector, Comparator comparator) { + final int flag; + + public IxOrderBy(Iterable source, Func1 keySelector, Comparator comparator, int flag) { super(source); this.keySelector = keySelector; this.comparator = comparator; + this.flag = flag; } @Override public Iterator iterator() { - return new OrderByIterator(source.iterator(), keySelector, comparator); + return new OrderByIterator(source.iterator(), keySelector, comparator, flag); } static final class OrderByIterator extends IxSourceIterator implements Comparator { @@ -43,14 +46,17 @@ static final class OrderByIterator extends IxSourceIterator implemen final Comparator comparator; + final int flag; + List values; int index; - public OrderByIterator(Iterator it, Func1 keySelector, Comparator comparator) { + public OrderByIterator(Iterator it, Func1 keySelector, Comparator comparator, int flag) { super(it); this.keySelector = keySelector; this.comparator = comparator; + this.flag = flag; } @Override @@ -93,7 +99,7 @@ protected boolean moveNext() { public int compare(T o1, T o2) { K k1 = keySelector.call(o1); K k2 = keySelector.call(o2); - return comparator.compare(k1, k2); + return comparator.compare(k1, k2) * flag; } } diff --git a/src/main/java/ix/IxReverse.java b/src/main/java/ix/IxReverse.java new file mode 100644 index 0000000..013ffb9 --- /dev/null +++ b/src/main/java/ix/IxReverse.java @@ -0,0 +1,66 @@ +/* + * Copyright 2011-2016 David Karnok + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ix; + +import java.util.*; + +final class IxReverse extends IxSource { + + public IxReverse(Iterable source) { + super(source); + } + + @Override + public Iterator iterator() { + return new ReverseIterator(source.iterator()); + } + + static final class ReverseIterator extends IxSourceIterator { + + List list; + + int index; + + public ReverseIterator(Iterator it) { + super(it); + } + + @Override + protected boolean moveNext() { + List list = this.list; + + if (list == null) { + list = new ArrayList(); + this.list = list; + while (it.hasNext()) { + list.add(it.next()); + } + index = list.size(); + } + + int i = index; + if (i == 0) { + done = true; + return false; + } + value = list.get(i - 1); + hasValue = true; + index = i - 1; + return true; + } + } +} diff --git a/src/main/java/ix/IxSequenceEqual.java b/src/main/java/ix/IxSequenceEqual.java new file mode 100644 index 0000000..caf74cd --- /dev/null +++ b/src/main/java/ix/IxSequenceEqual.java @@ -0,0 +1,95 @@ +/* + * Copyright 2011-2016 David Karnok + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ix; + +import java.util.Iterator; + +final class IxSequenceEqual extends IxSource { + + final Iterable other; + + final Pred2 comparer; + + public IxSequenceEqual(Iterable source, Iterable other, + Pred2 comparer) { + super(source); + this.other = other; + this.comparer = comparer; + } + + @Override + public Iterator iterator() { + return new SequenceEqualIterator(source.iterator(), other.iterator(), comparer); + } + + static final class SequenceEqualIterator extends IxSourceIterator { + + final Iterator other; + + final Pred2 comparer; + + public SequenceEqualIterator(Iterator it, Iterator other, + Pred2 comparer) { + super(it); + this.other = other; + this.comparer = comparer; + } + + @Override + protected boolean moveNext() { + + Iterator it2 = it; + + while (it2.hasNext()) { + + T v = it2.next(); + + if (other.hasNext()) { + + T u = other.next(); + + if (!comparer.test(v, u)) { + + value = false; + hasValue = true; + done = true; + return true; + } + } else { + value = false; + hasValue = true; + done = true; + return true; + } + } + if (other.hasNext()) { + value = false; + hasValue = true; + done = true; + return true; + } + + value = true; + hasValue = true; + done = true; + return true; + } + + + } + +} diff --git a/src/main/java/ix/IxSwitchIfEmpty.java b/src/main/java/ix/IxSwitchIfEmpty.java new file mode 100644 index 0000000..bd43a9c --- /dev/null +++ b/src/main/java/ix/IxSwitchIfEmpty.java @@ -0,0 +1,99 @@ +/* + * Copyright 2011-2016 David Karnok + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ix; + +import java.util.Iterator; + +final class IxSwitchIfEmpty extends IxSource { + + final Iterable other; + + public IxSwitchIfEmpty(Iterable source, Iterable other) { + super(source); + this.other = other; + } + + @Override + public Iterator iterator() { + return new SwitchIfEmptyIterator(source.iterator(), other); + } + + static final class SwitchIfEmptyIterator extends IxSourceIterator { + + final Iterable other; + + Iterator otherIterator; + + boolean nonEmpty; + + public SwitchIfEmptyIterator(Iterator it, Iterable other) { + super(it); + this.other = other; + } + + @Override + protected boolean moveNext() { + Iterator ot = otherIterator; + if (ot != null) { + if (ot.hasNext()) { + value = ot.next(); + hasValue = true; + return true; + } + done = true; + return false; + } + + if (nonEmpty) { + if (it.hasNext()) { + value = it.next(); + hasValue = true; + return true; + } + done = true; + return false; + } + + if (it.hasNext()) { + nonEmpty = true; + value = it.next(); + hasValue = true; + return true; + } + + ot = other.iterator(); + otherIterator = ot; + if (ot.hasNext()) { + value = ot.next(); + hasValue = true; + return true; + } + done = true; + return false; + } + + @Override + public void remove() { + Iterator ot = otherIterator; + if (ot != null) { + ot.remove(); + } else { + it.remove(); + } + } + } +} diff --git a/src/main/java/ix/IxToSet.java b/src/main/java/ix/IxToSet.java new file mode 100644 index 0000000..7924ee3 --- /dev/null +++ b/src/main/java/ix/IxToSet.java @@ -0,0 +1,55 @@ +/* + * Copyright 2011-2016 David Karnok + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ix; + +import java.util.*; + +final class IxToSet extends IxSource> { + + public IxToSet(Iterable source) { + super(source); + } + + @Override + public Iterator> iterator() { + return new ToSetIterator(source.iterator()); + } + + static final class ToSetIterator extends IxSourceIterator> { + + public ToSetIterator(Iterator it) { + super(it); + } + + @Override + protected boolean moveNext() { + + Set set = new HashSet(); + + Iterator it = this.it; + + while (it.hasNext()) { + set.add(it.next()); + } + + value = set; + hasValue = true; + done = true; + return true; + } + } +} diff --git a/src/main/java/ix/IxUnion.java b/src/main/java/ix/IxUnion.java new file mode 100644 index 0000000..03e865b --- /dev/null +++ b/src/main/java/ix/IxUnion.java @@ -0,0 +1,82 @@ +/* + * Copyright 2011-2016 David Karnok + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ix; + +import java.util.*; + +final class IxUnion extends IxSource { + + final Iterable other; + + public IxUnion(Iterable source, Iterable other) { + super(source); + this.other = other; + } + + @Override + public Iterator iterator() { + return new UnionIterator(source.iterator(), other.iterator()); + } + + static final class UnionIterator extends IxSourceIterator { + + final Iterator other; + + final Set set; + + boolean second; + + public UnionIterator(Iterator it, Iterator other) { + super(it); + this.other = other; + this.set = new HashSet(); + } + + @Override + protected boolean moveNext() { + Set set = this.set; + for (;;) { + if (second) { + Iterator other = this.other; + while (other.hasNext()) { + T v = other.next(); + if (set.add(v)) { + value = v; + hasValue = true; + return true; + } + } + + done = true; + return false; + } + + Iterator it = this.it; + while (it.hasNext()) { + T v = it.next(); + if (set.add(v)) { + value = v; + hasValue = true; + return true; + } + } + + second = true; + } + } + } +} diff --git a/src/test/java/ix/AverageTest.java b/src/test/java/ix/AverageTest.java new file mode 100644 index 0000000..f8303f5 --- /dev/null +++ b/src/test/java/ix/AverageTest.java @@ -0,0 +1,77 @@ +/* + * Copyright 2011-2016 David Karnok + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ix; + +import org.junit.Test; + +public class AverageTest { + + @Test + public void normalFloat() { + Ix source = Ix.range(1, 5).averageFloat(); + + IxTestHelper.assertValues(source, 3f); + + IxTestHelper.assertNoRemove(source); + } + + @Test + public void justFloat() { + Ix source = Ix.just(1).averageFloat(); + + IxTestHelper.assertValues(source, 1f); + + IxTestHelper.assertNoRemove(source); + } + + @Test + public void emptyFloat() { + Ix source = Ix.empty().averageFloat(); + + IxTestHelper.assertValues(source); + + IxTestHelper.assertNoRemove(source); + } + + @Test + public void normalDouble() { + Ix source = Ix.range(1, 5).averageDouble(); + + IxTestHelper.assertValues(source, 3d); + + IxTestHelper.assertNoRemove(source); + } + + @Test + public void justDouble() { + Ix source = Ix.just(1).averageDouble(); + + IxTestHelper.assertValues(source, 1d); + + IxTestHelper.assertNoRemove(source); + } + + @Test + public void emptyDouble() { + Ix source = Ix.empty().averageDouble(); + + IxTestHelper.assertValues(source); + + IxTestHelper.assertNoRemove(source); + } + +} diff --git a/src/test/java/ix/ExceptTest.java b/src/test/java/ix/ExceptTest.java new file mode 100644 index 0000000..f9e9f20 --- /dev/null +++ b/src/test/java/ix/ExceptTest.java @@ -0,0 +1,85 @@ +/* + * Copyright 2011-2016 David Karnok + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ix; + +import org.junit.Test; + +public class ExceptTest { + + @Test + public void normal() { + Ix source = Ix.range(1, 5).except(Ix.range(3, 5)); + + IxTestHelper.assertValues(source, 1, 2, 6, 7); + + IxTestHelper.assertNoRemove(source); + } + + @Test + public void firstEmpty() { + Ix source = Ix.empty().except(Ix.range(3, 5)); + + IxTestHelper.assertValues(source, 3, 4, 5, 6, 7); + + IxTestHelper.assertNoRemove(source); + } + + @Test + public void secondEmpty() { + Ix source = Ix.range(1, 5).except(Ix.empty()); + + IxTestHelper.assertValues(source, 1, 2, 3, 4, 5); + + IxTestHelper.assertNoRemove(source); + } + + @Test + public void firstInSecond() { + Ix source = Ix.range(1, 5).except(Ix.range(1, 3)); + + IxTestHelper.assertValues(source, 4, 5); + + IxTestHelper.assertNoRemove(source); + } + + @Test + public void firstInFirst() { + Ix source = Ix.range(1, 3).except(Ix.range(1, 5)); + + IxTestHelper.assertValues(source, 4, 5); + + IxTestHelper.assertNoRemove(source); + } + + @Test + public void distinct() { + Ix source = Ix.range(1, 5).except(Ix.range(6, 5)); + + IxTestHelper.assertValues(source, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10); + + IxTestHelper.assertNoRemove(source); + } + + @Test + public void overlapWithDuplicates() { + Ix source = Ix.fromArray(1, 2, 2, 3, 4, 5).except(Ix.range(1, 3)); + + IxTestHelper.assertValues(source, 4, 5); + + IxTestHelper.assertNoRemove(source); + } +} diff --git a/src/test/java/ix/IntersectTest.java b/src/test/java/ix/IntersectTest.java new file mode 100644 index 0000000..64ade1e --- /dev/null +++ b/src/test/java/ix/IntersectTest.java @@ -0,0 +1,68 @@ +/* + * Copyright 2011-2016 David Karnok + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ix; + +import org.junit.Test; + +public class IntersectTest { + + @Test + public void normal() { + Ix source = Ix.range(1, 5).intersect(Ix.range(3, 5)); + + IxTestHelper.assertValues(source, 3, 4, 5); + + IxTestHelper.assertNoRemove(source); + } + + @Test + public void same() { + Ix source = Ix.range(1, 5).intersect(Ix.range(1, 5)); + + IxTestHelper.assertValues(source, 1, 2, 3, 4, 5); + + IxTestHelper.assertNoRemove(source); + } + + @Test + public void distinct() { + Ix source = Ix.range(1, 5).intersect(Ix.range(6, 5)); + + IxTestHelper.assertValues(source); + + IxTestHelper.assertNoRemove(source); + } + + @Test + public void distinctEmptyFirst() { + Ix source = Ix.empty().intersect(Ix.range(6, 5)); + + IxTestHelper.assertValues(source); + + IxTestHelper.assertNoRemove(source); + } + + @Test + public void distinctEmptySecond() { + Ix source = Ix.range(1, 5).intersect(Ix.empty()); + + IxTestHelper.assertValues(source); + + IxTestHelper.assertNoRemove(source); + } + +} diff --git a/src/test/java/ix/IxTestHelper.java b/src/test/java/ix/IxTestHelper.java index 02ba24d..1cd12d5 100644 --- a/src/test/java/ix/IxTestHelper.java +++ b/src/test/java/ix/IxTestHelper.java @@ -97,6 +97,6 @@ public static void assertNoRemove(Iterable source) { } public static List range(int start, int count) { - return Ix.range(1, 10).toList().first(); + return Ix.range(start, count).toList().first(); } } diff --git a/src/test/java/ix/LeavingTest.java b/src/test/java/ix/LeavingTest.java index 79c2290..7910628 100644 --- a/src/test/java/ix/LeavingTest.java +++ b/src/test/java/ix/LeavingTest.java @@ -411,4 +411,29 @@ public boolean test(Integer v) { Assert.assertEquals(Arrays.asList(2, 4, 6, 8, 10), list); } + + @Test + public void single() { + Assert.assertEquals(1, Ix.just(1).single().intValue()); + } + + @Test(expected = NoSuchElementException.class) + public void singleEmpty() { + Assert.assertEquals(1, Ix.empty().single().intValue()); + } + + @Test + public void singleEmptyDefault() { + Assert.assertEquals(2, Ix.empty().single(2).intValue()); + } + + @Test(expected = IndexOutOfBoundsException.class) + public void singleLonger() { + Ix.range(1, 5).single(); + } + + @Test(expected = IndexOutOfBoundsException.class) + public void singleLongerDefault() { + Ix.range(1, 5).single(10); + } } diff --git a/src/test/java/ix/OrderByTest.java b/src/test/java/ix/OrderByTest.java index ead8522..c3c8e67 100644 --- a/src/test/java/ix/OrderByTest.java +++ b/src/test/java/ix/OrderByTest.java @@ -79,4 +79,40 @@ public void just() { IxTestHelper.assertNoRemove(source); } + @Test + public void normalReverse() { + Ix source = Ix.range(1, 5).orderByReverse(); + + IxTestHelper.assertValues(source, 5, 4, 3, 2, 1); + + IxTestHelper.assertNoRemove(source); + } + + @Test + public void normalComparatorReverse() { + Ix source = Ix.fromArray(1, 2, 3, 4, 5).orderByReverse(new Comparator() { + @Override + public int compare(Integer a, Integer b) { + return b.compareTo(a); + } + }); + + IxTestHelper.assertValues(source, 1, 2, 3, 4, 5); + + IxTestHelper.assertNoRemove(source); + } + + @Test + public void normalKeySelectorReverse() { + Ix source = Ix.fromArray(1, 2, 3, 4, 5).orderByReverse(new Func1() { + @Override + public Integer call(Integer v) { + return 3 - v; + } + }); + + IxTestHelper.assertValues(source, 1, 2, 3, 4, 5); + + IxTestHelper.assertNoRemove(source); + } } diff --git a/src/test/java/ix/ReverseTest.java b/src/test/java/ix/ReverseTest.java new file mode 100644 index 0000000..7e0c1c0 --- /dev/null +++ b/src/test/java/ix/ReverseTest.java @@ -0,0 +1,41 @@ +/* + * Copyright 2011-2016 David Karnok + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ix; + +import org.junit.Test; + +public class ReverseTest { + + @Test + public void normal() { + Ix source = Ix.range(1, 5).reverse(); + + IxTestHelper.assertValues(source, 5, 4, 3, 2, 1); + + IxTestHelper.assertNoRemove(source); + } + + @Test + public void empty() { + Ix source = Ix.empty().reverse(); + + IxTestHelper.assertValues(source); + + IxTestHelper.assertNoRemove(source); + } + +} diff --git a/src/test/java/ix/SequenceEqualTest.java b/src/test/java/ix/SequenceEqualTest.java new file mode 100644 index 0000000..37ee340 --- /dev/null +++ b/src/test/java/ix/SequenceEqualTest.java @@ -0,0 +1,70 @@ +/* + * Copyright 2011-2016 David Karnok + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ix; + +import org.junit.Test; + +public class SequenceEqualTest { + + @Test + public void normal() { + Ix source = Ix.range(1, 5).sequenceEqual(Ix.range(1, 5)); + + IxTestHelper.assertValues(source, true); + } + + @Test + public void firstSorter() { + Ix source = Ix.range(1, 4).sequenceEqual(Ix.range(1, 5)); + + IxTestHelper.assertValues(source, false); + } + + @Test + public void secondSorter() { + Ix source = Ix.range(1, 5).sequenceEqual(Ix.range(1, 4)); + + IxTestHelper.assertValues(source, false); + } + + @Test + public void firstEmpty() { + Ix source = Ix.empty().sequenceEqual(Ix.range(1, 5)); + + IxTestHelper.assertValues(source, false); + } + + @Test + public void secondEmpty() { + Ix source = Ix.range(1, 5).sequenceEqual(Ix.empty()); + + IxTestHelper.assertValues(source, false); + } + @Test + public void empty() { + Ix source = Ix.empty().sequenceEqual(Ix.empty()); + + IxTestHelper.assertValues(source, true); + } + + @Test + public void different() { + Ix source = Ix.fromArray(1, 2, 3, 3, 5).sequenceEqual(Ix.range(1, 5)); + + IxTestHelper.assertValues(source, false); + } +} diff --git a/src/test/java/ix/SwitchIfEmptyTest.java b/src/test/java/ix/SwitchIfEmptyTest.java new file mode 100644 index 0000000..72cedac --- /dev/null +++ b/src/test/java/ix/SwitchIfEmptyTest.java @@ -0,0 +1,79 @@ +/* + * Copyright 2011-2016 David Karnok + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ix; + +import java.util.List; + +import org.junit.Test; + +public class SwitchIfEmptyTest { + + @Test + public void normal() { + Ix source = Ix.range(1, 10).switchIfEmpty(Ix.range(11, 10)); + + IxTestHelper.assertValues(source, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10); + } + + @Test + public void empty() { + Ix source = Ix.empty().switchIfEmpty(Ix.range(11, 10)); + + IxTestHelper.assertValues(source, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20); + } + + @Test + public void emptyOther() { + Ix source = Ix.empty().switchIfEmpty(Ix.empty()); + + IxTestHelper.assertValues(source); + } + + @Test + public void defaultNormal() { + Ix source = Ix.range(1, 10).defaultIfEmpty(100); + + IxTestHelper.assertValues(source, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10); + } + + @Test + public void defaultEmpty() { + Ix source = Ix.empty().defaultIfEmpty(100); + + IxTestHelper.assertValues(source, 100); + } + + @Test + public void removeNonEmpty() { + List list = IxTestHelper.range(1, 10); + List list2 = IxTestHelper.range(11, 10); + + Ix.from(list).switchIfEmpty(Ix.from(list2)).removeAll(); + + IxTestHelper.assertValues(list); + IxTestHelper.assertValues(list2, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20); + } + + @Test + public void removeEmpty() { + List list2 = IxTestHelper.range(11, 10); + + Ix.empty().switchIfEmpty(Ix.from(list2)).removeAll(); + + IxTestHelper.assertValues(list2); + } +} diff --git a/src/test/java/ix/ToSetTest.java b/src/test/java/ix/ToSetTest.java new file mode 100644 index 0000000..20ad441 --- /dev/null +++ b/src/test/java/ix/ToSetTest.java @@ -0,0 +1,55 @@ +/* + * Copyright 2011-2016 David Karnok + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ix; + +import java.util.*; + +import org.junit.Test; + +public class ToSetTest { + + @SuppressWarnings("unchecked") + @Test + public void normal() { + Ix> source = Ix.range(1, 5).toSet(); + + IxTestHelper.assertValues(source, new HashSet(Arrays.asList(1, 2, 3, 4, 5))); + + IxTestHelper.assertNoRemove(source); + } + + @SuppressWarnings("unchecked") + @Test + public void empty() { + Ix> source = Ix.empty().toSet(); + + IxTestHelper.assertValues(source, new HashSet()); + + IxTestHelper.assertNoRemove(source); + } + + @SuppressWarnings("unchecked") + @Test + public void duplicates() { + Ix> source = Ix.fromArray(1, 2, 2, 3, 2, 4, 5, 1, 5).toSet(); + + IxTestHelper.assertValues(source, new HashSet(Arrays.asList(1, 2, 3, 4, 5))); + + IxTestHelper.assertNoRemove(source); + } + +} diff --git a/src/test/java/ix/UnionTest.java b/src/test/java/ix/UnionTest.java new file mode 100644 index 0000000..cbe1be9 --- /dev/null +++ b/src/test/java/ix/UnionTest.java @@ -0,0 +1,113 @@ +/* + * Copyright 2011-2016 David Karnok + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ix; + +import org.junit.Test; + +public class UnionTest { + + @Test + public void distinct() { + Ix source = Ix.range(1, 5).union(Ix.range(6, 5)); + + IxTestHelper.assertValues(source, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10); + + IxTestHelper.assertNoRemove(source); + } + + @Test + public void overlap() { + Ix source = Ix.range(1, 5).union(Ix.range(3, 5)); + + IxTestHelper.assertValues(source, 1, 2, 3, 4, 5, 6, 7); + + IxTestHelper.assertNoRemove(source); + } + + @Test + public void overlapReverse() { + Ix source = Ix.range(3, 5).union(Ix.range(1, 5)); + + IxTestHelper.assertValues(source, 3, 4, 5, 6, 7, 1, 2); + + IxTestHelper.assertNoRemove(source); + } + + + @Test + public void same() { + Ix source = Ix.range(1, 5).union(Ix.range(1, 5)); + + IxTestHelper.assertValues(source, 1, 2, 3, 4, 5); + + IxTestHelper.assertNoRemove(source); + } + + @Test + public void firstInSecond() { + Ix source = Ix.range(1, 3).union(Ix.range(1, 5)); + + IxTestHelper.assertValues(source, 1, 2, 3, 4, 5); + + IxTestHelper.assertNoRemove(source); + } + + @Test + public void secondInFirst() { + Ix source = Ix.range(1, 5).union(Ix.range(1, 3)); + + IxTestHelper.assertValues(source, 1, 2, 3, 4, 5); + + IxTestHelper.assertNoRemove(source); + } + + @Test + public void firstEmpty() { + Ix source = Ix.empty().union(Ix.range(1, 5)); + + IxTestHelper.assertValues(source, 1, 2, 3, 4, 5); + + IxTestHelper.assertNoRemove(source); + } + + @Test + public void secondEmpty() { + Ix source = Ix.range(1, 5).union(Ix.empty()); + + IxTestHelper.assertValues(source, 1, 2, 3, 4, 5); + + IxTestHelper.assertNoRemove(source); + } + + @Test + public void bothEmpty() { + Ix source = Ix.empty().union(Ix.empty()); + + IxTestHelper.assertValues(source); + + IxTestHelper.assertNoRemove(source); + } + + @Test + public void duplicates() { + Ix source = Ix.fromArray(1, 2, 2, 1, 4, 5).union(Ix.fromArray(2, 3, 1, 5, 4)); + + IxTestHelper.assertValues(source, 1, 2, 4, 5, 3); + + IxTestHelper.assertNoRemove(source); + } +} From 2a597e2229584196cddccf2f2b32fa2e2872b953 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?D=C3=A1vid=20Karnok?= Date: Fri, 15 Jul 2016 21:49:07 +0200 Subject: [PATCH 27/66] Javadoc part 1 --- gradle.properties | 2 +- src/main/java/ix/Ix.java | 637 ++++++++++++++++++++++---- src/test/java/ix/ConcatArrayTest.java | 21 + src/test/java/ix/IxTest.java | 12 + src/test/java/ix/LeavingTest.java | 5 + src/test/java/ix/RangeTest.java | 10 + 6 files changed, 597 insertions(+), 90 deletions(-) diff --git a/gradle.properties b/gradle.properties index cb204eb..914942d 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1 +1 @@ -version=1.0.0-M2 +version=1.0.0-RC1 diff --git a/src/main/java/ix/Ix.java b/src/main/java/ix/Ix.java index aaa85f5..6bfeb09 100644 --- a/src/main/java/ix/Ix.java +++ b/src/main/java/ix/Ix.java @@ -26,41 +26,41 @@ /** * Base class and entry point for fluent Iterables. - * + *

+ * All operators tolerate {@code null} elements. + *

+ * The Iterables have to be run in a single-threaded manner and none of + * the participating operators expect or support concurrency. * @param the value type * @since 1.0 */ public abstract class Ix implements Iterable { - public static Ix just(T value) { - return new IxJust(value); - } - - public static Ix empty() { - return IxEmpty.instance(); - } - - public static Ix from(Iterable source) { - if (source instanceof Ix) { - return (Ix)source; - } - return new IxWrapper(nullCheck(source, "source")); - } - - public static Ix range(int start, int count) { - if (count == 0) { - return empty(); - } - if (count == 1) { - return just(start); - } - return new IxRange(start, count); - } - + /** + * Emits all characters from the given CharSequence as integer values. + *

+ * The result's iterator() doesn't support remove(). + * @param cs the source character sequence, not null + * @return the new Ix instance + * @throws NullPointerException if cs is null + * @since 1.0 + */ public static Ix characters(CharSequence cs) { return new IxCharacters(cs, 0, cs.length()); } + /** + * Emits a range of characters from the given CharSequence as integer values. + *

+ * The result's iterator() doesn't support remove(). + * @param cs the source character sequence, not null + * @param start the start character index, inclusive, non-negative + * @param end the end character index, exclusive, non-negative + * @return the new Ix instance + * @throws NullPointerException if cs is null + * @throws IndexOutOfBoundsException if start is out of range [0, cs.length] + * @since 1.0 + */ public static Ix characters(CharSequence cs, int start, int end) { int len = cs.length(); if (start < 0 || end < 0 || start > len || end > len) { @@ -68,25 +68,101 @@ public static Ix characters(CharSequence cs, int start, int end) { } return new IxCharacters(cs, start, end); } - - public static Ix fromArray(T... values) { - int n = values.length; - if (n == 0) { - return empty(); - } - if (n == 1) { - return just(values[0]); - } - return new IxFromArray(0, values.length, values); + + /** + * Concatenates the elements of Iterable sources, provided as an Iterable itself, sequentially. + *

+ * The result's iterator() forwards the remove() calls to the current iterator. + *

+ * Note that merge and concat operations are the same in the Iterable world. + * @param the common base type + * @param sources the Iterable sequence of source Iterables + * @return the new Ix instance + * @throws NullPointerException if sources is null + * @since 1.0 + * @see #merge(Iterable) + */ + @SuppressWarnings({ "unchecked", "rawtypes" }) + public static Ix concat(Iterable> sources) { + return new IxFlattenIterable, T>( + (Iterable)nullCheck(sources, "sources is null"), + IdentityHelper.>instance()); } - public static Ix fromArrayRange(int start, int end, T... values) { - if (start < 0 || end < 0 || start > values.length || end > values.length) { - throw new IndexOutOfBoundsException("start=" + start + ", end=" + end + ", length=" + values.length); - } - return new IxFromArray(start, end, values); + /** + * Concatenates the elements of two Iterable sources sequentially + *

+ * The result's iterator() forwards the remove() calls to the current iterator. + *

+ * Note that merge and concat operations are the same in the Iterable world. + * @param the value type + * @param source1 the first source, not null + * @param source2 the second source, not null + * @return the new Iterable source + * @throws NullPointerException if any of the sources is null + * @since 1.0 + */ + @SuppressWarnings("unchecked") + public static Ix concat(Iterable source1, Iterable source2) { + return concatArray(nullCheck(source1, "source1 is null"), nullCheck(source2, "source2 is null")); + } + + /** + * Concatenates the elements of three Iterable sources sequentially + *

+ * The result's iterator() forwards the remove() calls to the current iterator. + *

+ * Note that merge and concat operations are the same in the Iterable world. + * @param the value type + * @param source1 the first source, not null + * @param source2 the second source, not null + * @param source3 the third source, not null + * @return the new Iterable source + * @throws NullPointerException if any of the sources is null + * @since 1.0 + */ + @SuppressWarnings("unchecked") + public static Ix concat(Iterable source1, Iterable source2, + Iterable source3) { + return concatArray(nullCheck(source1, "source1 is null"), + nullCheck(source2, "source2 is null"), nullCheck(source3, "source3 is null")); } + /** + * Concatenates the elements of three Iterable sources sequentially + *

+ * The result's iterator() forwards the remove() calls to the current iterator. + *

+ * Note that merge and concat operations are the same in the Iterable world. + * @param the value type + * @param source1 the first source, not null + * @param source2 the second source, not null + * @param source3 the third source, not null + * @param source4 the fourth source, not null + * @return the new Iterable source + * @throws NullPointerException if any of the sources is null + * @since 1.0 + */ + @SuppressWarnings("unchecked") + public static Ix concat(Iterable source1, Iterable source2, + Iterable source3, Iterable source4) { + return concatArray(nullCheck(source1, "source1 is null"), nullCheck(source2, "source2 is null"), + nullCheck(source3, "source3 is null"), nullCheck(source4, "source4 is null")); + } + + /** + * Concatenates the elements of Iterable sources, provided as an array, sequentially. + *

+ * The result's iterator() forwards the remove() calls to the current iterator. + *

+ * Note that merge and concat operations are the same in the Iterable world. + * @param the common base type + * @param sources the array of source Iterables + * @return the new Ix instance + * @throws NullPointerException if sources is null + * @since 1.0 + * @see #mergeArray(Iterable...) + */ @SuppressWarnings("unchecked") public static Ix concatArray(Iterable... sources) { int n = sources.length; @@ -99,92 +175,461 @@ public static Ix concatArray(Iterable... sources) { return new IxFlattenArrayIterable((Iterable[])sources); } - public static Ix mergeArray(Iterable... sources) { - return concatArray(sources); // concat and merge are the same in the Iterable world + /** + * Defers the generation of the actual Iterable till the iterator() is called on + * the resulting Ix. + *

+ * The result's iterator() forwards the remove() calls to the generated Iterable's Iterator. + * @param the value type + * @param factory the function that returns an Iterable when the resulting Ix.iterator() is called + * @return the new Ix source + * @throws NullPointerException if factory is null + * @since 1.0 + */ + public static Ix defer(Func0> factory) { + return new IxDefer(nullCheck(factory, "factory is null")); } - - @SuppressWarnings({ "unchecked", "rawtypes" }) - public static Ix concat(Iterable> sources) { - return new IxFlattenIterable, T>( - (Iterable)sources, - IdentityHelper.>instance()); + + /** + * No elements are emitted. + *

+ * The result's iterator() doesn't support remove(). + * @param the value type + * @return the new Ix instance + * @since 1.0 + */ + public static Ix empty() { + return IxEmpty.instance(); + } + + /** + * Wraps the given Interable source into an Ix instance (if + * not already an Ix subclass). + *

+ * The result's iterator() forwards the remove() calls to the source's + * iterator(). + * @param the value type + * @param source the Iterable to wrap, not null + * @return the new Ix instance + * @throws NullPointerException if source is null + * @since 1.0 + */ + public static Ix from(Iterable source) { + if (source instanceof Ix) { + return (Ix)source; + } + return new IxWrapper(nullCheck(source, "source")); + } + + /** + * Emits all the elements of the given array. + *

+ * The result's iterator() doesn't support remove(). + * @param the value type + * @param values the array of values, not null + * @return the new Ix instance + * @throws NullPointerException if values is null + * @since 1.0 + */ + public static Ix fromArray(T... values) { + int n = values.length; + if (n == 0) { + return empty(); + } + if (n == 1) { + return just(values[0]); + } + return new IxFromArray(0, values.length, values); } - @SuppressWarnings({ "unchecked", "rawtypes" }) - public static Ix merge(Iterable> sources) { - return new IxFlattenIterable, T>( - (Iterable)sources, - IdentityHelper.>instance()); + /** + * Emits a range of elements from the given array. + *

+ * The result's iterator() doesn't support remove(). + * @param the value type + * @param start the staring index, inclusive, non-negative + * @param end the end index, exclusive, non-negative + * @param values the array of values + * @return the new Ix instance + * @throws NullPointerException if values is null + * @throws IndexOutOfBoundsException if either start or end are not in [0, values.length] + * @since 1.0 + */ + public static Ix fromArrayRange(int start, int end, T... values) { + if (start < 0 || end < 0 || start > values.length || end > values.length) { + throw new IndexOutOfBoundsException("start=" + start + ", end=" + end + ", length=" + values.length); + } + return new IxFromArray(start, end, values); } - public static Ix defer(Func0> factory) { - return new IxDefer(factory); + /** + * Generates a sequence of values via a generic indexed for-loop style construct; + * the index starts with the given seed, checked via a condition (to terminate), + * generated from the index via the selector and then a new index is generated via next. + *

+ * The result's iterator() doesn't support remove(). + * @param the index value type + * @param the result value type + * @param seed the initial value of the index + * @param condition the receives the current index (before selector is called) and if it + * returns false, the sequence terminates + * @param next the function that receives the current index and returns the next index + * @param selector the function that receives the current index and returns the value + * to be emitted. + * @return the new Ix instance + * @throws NullPointerException if condition, next or selector is null + * @since 1.0 + */ + public static Ix forloop(T seed, Pred condition, + Func1 next, + Func1 selector) { + return new IxForloop(seed, nullCheck(condition, "condition is null"), + nullCheck(selector, "selector is null"), nullCheck(next, "next is null")); } + /** + * Calls the given action to generate a value or terminate whenever the next() + * is called on the resulting Ix.iterator(). + *

+ * The result's iterator() doesn't support remove(). + *

+ * The action may call {@code onNext} at most once to signal the next value per action invocation. + * The {@code onCompleted} should be called to indicate no further values will be generated (may be + * called with an onNext in the same action invocation). Calling {@code onError} will immediately + * throw the given exception (as is if it's a RuntimeException or Error; or wrapped into a RuntimeException). + * @param the value type + * @param nextSupplier the action called with an Observer API to receive value, not null + * @return the new Ix instance + * @throws NullPointerException if nextSupplier is null + * @since 1.0 + */ public static Ix generate(Action1> nextSupplier) { - return new IxGenerateStateless(nextSupplier); + return new IxGenerateStateless(nullCheck(nextSupplier, "nextSupplier is null")); } + /** + * Calls the given function (with per-iterator state) to generate a value or terminate + * whenever the next() is called on the resulting Ix.iterator(). + *

+ * The result's iterator() doesn't support remove(). + *

+ * The action may call {@code onNext} at most once to signal the next value per action invocation. + * The {@code onCompleted} should be called to indicate no further values will be generated (may be + * called with an onNext in the same action invocation). Calling {@code onError} will immediately + * throw the given exception (as is if it's a RuntimeException or Error; or wrapped into a RuntimeException). + * @param the value type + * @param the state type supplied to and returned by the nextSupplier function + * @param stateSupplier the function that returns a state for each invocation of iterator() + * @param nextSupplier the action called with an Observer API to receive value, not null + * @return the new Ix instance + * @throws NullPointerException if stateSupplier or nextSupplier is null + * @since 1.0 + */ public static Ix generate(Func0 stateSupplier, Func2, S> nextSupplier) { return generate(stateSupplier, nextSupplier, IxEmptyAction.instance1()); } + /** + * Calls the given function (with per-iterator state) to generate a value or terminate + * whenever the next() is called on the resulting Ix.iterator(). + *

+ * The result's iterator() doesn't support remove(). + *

+ * The action may call {@code onNext} at most once to signal the next value per action invocation. + * The {@code onCompleted} should be called to indicate no further values will be generated (may be + * called with an onNext in the same action invocation). Calling {@code onError} will immediately + * throw the given exception (as is if it's a RuntimeException or Error; or wrapped into a RuntimeException). + *

+ * Note that since there is no direct way to cancel an Iterator, the stateDisposer is only invoked + * when the nextSupplier calls a terminal method. + * @param the value type + * @param the state type supplied to and returned by the nextSupplier function + * @param stateSupplier the function that returns a state for each invocation of iterator() + * @param nextSupplier the action called with an Observer API to receive value, not null + * @param stateDisposer the action called when the nextSupplier signals an {@code onError} or {@code onCompleted}. + * @return the new Ix instance + * @throws NullPointerException if stateSupplier, nextSupplier or stateDisposer is null + * @since 1.0 + */ public static Ix generate(Func0 stateSupplier, Func2, S> nextSupplier, Action1 stateDisposer) { - return new IxGenerate(stateSupplier, nextSupplier, stateDisposer); - } - - public static Ix zip(Iterable[] sources, FuncN zipper) { - return new IxZipArray(sources, zipper); + return new IxGenerate(nullCheck(stateSupplier, "stateSupplier is null"), + nullCheck(nextSupplier, "nextSupplier is null"), nullCheck(stateDisposer, "stateDisposer is null")); } - public static Ix zip(Iterable> sources, FuncN zipper) { - return new IxZipIterable(sources, zipper); + /** + * Emits a single constant value. + *

+ * The result's iterator() doesn't support remove(). + * @param the value type + * @param value the constant value to emit + * @return the new Ix instance + * @since 1.0 + */ + public static Ix just(T value) { + return new IxJust(value); } - public static Ix zip( - Iterable it1, Iterable it2, - Func2 zipper) { - return new IxZip2(it1, it2, zipper); + /** + * Concatenates the elements of Iterable sources, provided as an Iterable itself, sequentially. + *

+ * The result's iterator() forwards the remove() calls to the current iterator. + *

+ * Note that merge and concat operations are the same in the Iterable world. + * @param the common base type + * @param sources the Iterable sequence of source Iterables + * @return the new Ix instance + * @throws NullPointerException if sources is null + * @since 1.0 + * @see #concat(Iterable) + */ + public static Ix merge(Iterable> sources) { + return concat(sources); } - - public static Ix zip( - Iterable it1, Iterable it2, - Iterable it3, - Func3 zipper) { - return new IxZip3(it1, it2, it3, zipper); + + /** + * Concatenates the elements of Iterable sources, provided as an array, sequentially. + *

+ * The result's iterator() forwards the remove() calls to the current iterator. + *

+ * Note that merge and concat operations are the same in the Iterable world. + * @param the common base type + * @param sources the array of source Iterables + * @return the new Ix instance + * @throws NullPointerException if sources is null + * @since 1.0 + * @see #concatArray(Iterable...) + */ + public static Ix mergeArray(Iterable... sources) { + return concatArray(sources); // concat and merge are the same in the Iterable world } - - public static Ix zip( - Iterable it1, Iterable it2, - Iterable it3, Iterable it4, - Func4 zipper) { - return new IxZip4(it1, it2, it3, it4, zipper); + + /** + * Emits a range of incrementing integer values, starting from {@code start} and + * up to {@code count} times. + * @param start the starting value + * @param count the number of integers to emit, non-negative + * @return the new Ix instance + * @throws IllegalArgumentException if count is negative + * @since 1.0 + */ + public static Ix range(int start, int count) { + if (count == 0) { + return empty(); + } + if (count == 1) { + return just(start); + } + if (count < 0) { + throw new IllegalArgumentException("count >= 0 required but it was " + count); + } + return new IxRange(start, count); } + /** + * Repeats the given value indefinitely. + *

+ * The result's iterator() doesn't support remove(). + * @param the value type + * @param value the value to emit whenever next() is called + * @return the new Ix instance + * @since 1.0 + */ public static Ix repeatValue(T value) { return new IxRepeat(value); } + /** + * Repeats the given value at most count times. + *

A count of zero will yield an empty sequence, a count of one + * will yield a sequence with only one element and so forth. + *

+ * The result's iterator() doesn't support remove(). + * @param the value type + * @param value the value to emit + * @param count the number of times to emit the value, non-negative + * @return the new Ix instance + * @throws IllegalArgumentException if count is negative + * @since 1.0 + */ public static Ix repeatValue(T value, long count) { - return new IxRepeatCount(value, count); + return new IxRepeatCount(value, nonNegative(count, "count")); } + /** + * Repeats the given value until the given predicate returns true. + *

A count of zero will yield an empty sequence, a count of one + * will yield a sequence with only one element and so forth. + *

+ * The result's iterator() doesn't support remove(). + * @param the value type + * @param value the value to emit + * @param stopPredicate the predicate called before any emission; returning + * false keeps repeating the value, returning true terminates the sequence + * @return the new Ix instance + * @throws NullPointerException if stopPredicate is null + * @since 1.0 + */ public static Ix repeatValue(T value, Pred0 stopPredicate) { return repeatValue(value, Long.MAX_VALUE, stopPredicate); } + /** + * Repeats the given value at most count times or until the given predicate returns true. + *

A count of zero will yield an empty sequence, a count of one + * will yield a sequence with only one element and so forth. + *

+ * The result's iterator() doesn't support remove(). + * @param the value type + * @param value the value to emit + * @param count the number of times to emit the value, non-negative + * @param stopPredicate the predicate called before any emission; returning + * false keeps repeating the value, returning true terminates the sequence + * @return the new Ix instance + * @throws IllegalArgumentException if count is negative + * @throws NullPointerException if stopPredicate is null + * @since 1.0 + */ public static Ix repeatValue(T value, long count, Pred0 stopPredicate) { - return new IxRepeatPredicate(value, count, stopPredicate); - } - - public static Ix forloop(T seed, Pred condition, - Func1 next, - Func1 selector) { - return new IxForloop(seed, condition, selector, next); + return new IxRepeatPredicate(value, nonNegative(count, "count"), nullCheck(stopPredicate, "stopPredicate is null")); } + /** + * Emits a sequence of substring of a string split by the given separator. + *

+ * The result's iterator() doesn't support remove(). + * @param string the string to split, not null + * @param by the separator to split along, not null + * @return the new Ix instance + * @throws NullPointerException if string or by is null + * @since 1.0 + */ public static Ix split(String string, String by) { - return new IxSplit(string, by); + return new IxSplit(nullCheck(string, "string is null"), nullCheck(by, "by is null")); + } + + /** + * Combines the next element from each source Iterable via a zipper function. + *

+ * If one of the source Iterables is sorter the sequence terminates eagerly. + *

+ * The result's iterator() doesn't support remove(). + * + * @param the common element type of the sources + * @param the result value type + * @param sources the array of Iterable sources, not null + * @param zipper the function that takes an array of values and returns a value + * to be emitted, one from each source, not null + * @return the new Ix instance + * @throws NullPointerException if sources or zipper is null + * @since 1.0 + */ + public static Ix zip(Iterable[] sources, FuncN zipper) { + return new IxZipArray(nullCheck(sources, "sources is null"), nullCheck(zipper, "zipper is null")); + } + + /** + * Combines the next element from each source Iterable, provided as an Iterable itself, + * via a zipper function. + *

+ * If one of the source Iterables is sorter the sequence terminates eagerly. + *

+ * The result's iterator() doesn't support remove(). + * + * @param the common element type of the sources + * @param the result value type + * @param sources the Iterable of Iterable sources, not null + * @param zipper the function that takes an array of values and returns a value + * to be emitted, one from each source, not null + * @return the new Ix instance + * @throws NullPointerException if sources or zipper is null + * @since 1.0 + */ + public static Ix zip(Iterable> sources, FuncN zipper) { + return new IxZipIterable(nullCheck(sources, "sources is null"), nullCheck(zipper, "zipper is null")); + } + + /** + * Combines the next element from each source Iterable, provided as an Iterable itself, + * via a zipper function. + *

+ * If one of the source Iterables is sorter the sequence terminates eagerly. + *

+ * The result's iterator() doesn't support remove(). + * + * @param the first source's element type + * @param the second source's element type + * @param the result value type + * @param source1 the first source Iterable + * @param source2 the second source Iterable + * @param zipper the function that takesone from each source, not null + * @return the new Ix instance + * @throws NullPointerException if any of the sources or zipper is null + * @since 1.0 + */ + public static Ix zip( + Iterable source1, Iterable source2, + Func2 zipper) { + return new IxZip2(nullCheck(source1, "source1 is null"), + nullCheck(source2, "source2 is null"), nullCheck(zipper, "zipper is null")); + } + + /** + * Combines the next element from each source Iterable, provided as an Iterable itself, + * via a zipper function. + *

+ * If one of the source Iterables is sorter the sequence terminates eagerly. + *

+ * The result's iterator() doesn't support remove(). + * + * @param the first source's element type + * @param the second source's element type + * @param the third source's element type + * @param the result value type + * @param source1 the first source Iterable + * @param source2 the second source Iterable + * @param source3 the third source Iterable + * @param zipper the function that takesone from each source, not null + * @return the new Ix instance + * @throws NullPointerException if any of the sources or zipper is null + * @since 1.0 + */ + public static Ix zip( + Iterable source1, Iterable source2, + Iterable source3, + Func3 zipper) { + return new IxZip3(nullCheck(source1, "source1 is null"), nullCheck(source2, "source2 is null"), + nullCheck(source3, "source3 is null"), nullCheck(zipper, "zipper is null")); + } + + /** + * Combines the next element from each source Iterable, provided as an Iterable itself, + * via a zipper function. + *

+ * If one of the source Iterables is sorter the sequence terminates eagerly. + *

+ * The result's iterator() doesn't support remove(). + * + * @param the first source's element type + * @param the second source's element type + * @param the third source's element type + * @param the fourth source's element type + * @param the result value type + * @param source1 the first source Iterable + * @param source2 the second source Iterable + * @param source3 the third source Iterable + * @param source4 the fourth source Iterable + * @param zipper the function that takesone from each source, not null + * @return the new Ix instance + * @throws NullPointerException if any of the sources or zipper is null + * @since 1.0 + */ + public static Ix zip( + Iterable source1, Iterable source2, + Iterable source3, Iterable source4, + Func4 zipper) { + return new IxZip4(nullCheck(source1, "source1 is null"), + nullCheck(source2, "source2 is null"), nullCheck(source3, "source3 is null"), + nullCheck(source4, "source4 is null"), nullCheck(zipper, "zipper is null")); } //--------------------------------------------------------------------------------------- @@ -930,4 +1375,18 @@ protected static U checkedCall(Callable callable) { throw new RuntimeException(ex); } } + + /** + * Checks if the given value is non-negative and returns it; throws + * an IllegalArgumentException otherwise + * @param n the number to check + * @param name the name of the parameter + * @return n + */ + protected static long nonNegative(long n, String name) { + if (n < 0L) { + throw new IllegalArgumentException(name + " >= 0 required but it was " + n); + } + return n; + } } diff --git a/src/test/java/ix/ConcatArrayTest.java b/src/test/java/ix/ConcatArrayTest.java index 22cfc7d..b775fd9 100644 --- a/src/test/java/ix/ConcatArrayTest.java +++ b/src/test/java/ix/ConcatArrayTest.java @@ -168,4 +168,25 @@ public void mergeWithEmpty() { IxTestHelper.assertValues(source, 1, 2, 3, 4, 5); } + + @Test + public void concat2() { + Ix source = Ix.concat(Ix.just(1), Ix.just(2)); + + IxTestHelper.assertValues(source, 1, 2); + } + + @Test + public void concat3() { + Ix source = Ix.concat(Ix.just(1), Ix.just(2), Ix.just(3)); + + IxTestHelper.assertValues(source, 1, 2, 3); + } + + @Test + public void concat4() { + Ix source = Ix.concat(Ix.just(1), Ix.just(2), Ix.just(3), Ix.just(4)); + + IxTestHelper.assertValues(source, 1, 2, 3, 4); + } } diff --git a/src/test/java/ix/IxTest.java b/src/test/java/ix/IxTest.java index 0f9321a..e7e78e9 100644 --- a/src/test/java/ix/IxTest.java +++ b/src/test/java/ix/IxTest.java @@ -66,5 +66,17 @@ public void nullCheck() { Assert.assertEquals("Failure", ex.getMessage()); } } + + @Test + public void nonNegativeLong() { + Ix.nonNegative(0L, "n"); + Ix.nonNegative(1L, "n"); + + try { + Ix.nonNegative(-99, "n"); + } catch (IllegalArgumentException ex) { + Assert.assertEquals("n >= 0 required but it was -99", ex.getMessage()); + } + } } diff --git a/src/test/java/ix/LeavingTest.java b/src/test/java/ix/LeavingTest.java index 7910628..6d5ec3f 100644 --- a/src/test/java/ix/LeavingTest.java +++ b/src/test/java/ix/LeavingTest.java @@ -417,6 +417,11 @@ public void single() { Assert.assertEquals(1, Ix.just(1).single().intValue()); } + @Test + public void singleDefault() { + Assert.assertEquals(1, Ix.just(1).single(2).intValue()); + } + @Test(expected = NoSuchElementException.class) public void singleEmpty() { Assert.assertEquals(1, Ix.empty().single().intValue()); diff --git a/src/test/java/ix/RangeTest.java b/src/test/java/ix/RangeTest.java index b2688d5..5070456 100644 --- a/src/test/java/ix/RangeTest.java +++ b/src/test/java/ix/RangeTest.java @@ -51,4 +51,14 @@ public void just() { Assert.assertTrue(source.getClass().toString(), source instanceof IxScalarCallable); } + + @Test + public void negativeRange() { + try { + Ix.range(1, -99); + Assert.fail("Should have thrown IllegalArgumentException"); + } catch (IllegalArgumentException ex) { + Assert.assertEquals("count >= 0 required but it was -99", ex.getMessage()); + } + } } From 3639b87bd62f39b936c580c2a0e9db083fab8d31 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?D=C3=A1vid=20Karnok?= Date: Fri, 15 Jul 2016 22:25:19 +0200 Subject: [PATCH 28/66] Javadoc part 2 --- src/main/java/ix/Ix.java | 779 +++++++++++++++++++++++---------------- 1 file changed, 461 insertions(+), 318 deletions(-) diff --git a/src/main/java/ix/Ix.java b/src/main/java/ix/Ix.java index 6bfeb09..508093a 100644 --- a/src/main/java/ix/Ix.java +++ b/src/main/java/ix/Ix.java @@ -635,48 +635,57 @@ public static Ix zip( //--------------------------------------------------------------------------------------- // Instance operators //--------------------------------------------------------------------------------------- - - public final R as(Func1, R> transformer) { - return transformer.call(this); - } - - public final Ix compose(Func1, ? extends Iterable> transformer) { - return new IxCompose(this, transformer); + + public final Ix all(Pred predicate) { + return new IxAll(this, predicate); } - public final Ix any(Pred predicate) { return new IxAny(this, predicate); } + public final R as(Func1, R> transformer) { + return transformer.call(this); + } - public final Ix all(Pred predicate) { - return new IxAll(this, predicate); + @SuppressWarnings("unchecked") + public final Ix averageFloat() { + return new IxAverageFloat((Iterable)this); + } + + @SuppressWarnings("unchecked") + public final Ix averageDouble() { + return new IxAverageDouble((Iterable)this); } - public final Ix hasElements() { - return new IxHasElements(this); + public final Ix> buffer(int size) { + return new IxBuffer(this, size); } - public final Ix ignoreElements() { - return new IxIgnoreElements(this); + public final Ix> buffer(int size, int skip) { + if (size == skip) { + return buffer(size); + } + if (size < skip) { + return new IxBufferSkip(this, size, skip); + } + return new IxBufferOverlap(this, size, skip); } - public final Ix max(Comparator comparator) { - return new IxMinMax(this, comparator, -1); + public final Ix collect(Func0 initialFactory, Action2 collector) { + return new IxCollect(this, initialFactory, collector); } - @SuppressWarnings({ "rawtypes", "unchecked" }) - public final Ix max() { - return max((Comparator)SelfComparator.INSTANCE); + public final Ix compose(Func1, ? extends Iterable> transformer) { + return new IxCompose(this, transformer); } - - public final Ix min(Comparator comparator) { - return new IxMinMax(this, comparator, 1); + + public final Ix concatMap(Func1> mapper) { + return new IxFlattenIterable(this, mapper); } - - @SuppressWarnings({ "rawtypes", "unchecked" }) - public final Ix min() { - return min((Comparator)SelfComparator.INSTANCE); + + @SuppressWarnings("unchecked") + public final Ix concatWith(Iterable other) { + return concatArray(this, other); } public final Ix contains(Object o) { @@ -690,6 +699,10 @@ public final Ix count() { public final Ix countLong() { return new IxCountLong(this); } + + public final Ix defaultIfEmpty(T value) { + return switchIfEmpty(Ix.just(value)); + } public final Ix distinct() { return distinct(IdentityHelper.instance()); @@ -718,71 +731,77 @@ public final Ix doOnNext(Action1 action) { public final Ix doOnCompleted(Action0 action) { return new IxDoOn(this, IxEmptyAction.instance1(), action); } - - @SuppressWarnings("unchecked") - public final Ix startWith(T... values) { - return concatArray(fromArray(values), this); - } @SuppressWarnings("unchecked") public final Ix endWith(T... values) { return concatArray(this, fromArray(values)); } - public final Ix join() { - return join(", "); + public final Ix except(Iterable other) { + return new IxExcept(this, other); } - public final Ix join(CharSequence separator) { - return new IxJoin(this, separator); + public final Ix filter(Pred predicate) { + return new IxFilter(this, predicate); } - public final Ix map(Func1 mapper) { - return new IxMap(this, mapper); + public final Ix flatMap(Func1> mapper) { + return new IxFlattenIterable(this, mapper); } - public final Ix filter(Pred predicate) { - return new IxFilter(this, predicate); + public final Ix> groupBy(Func1 keySelector) { + return groupBy(keySelector, IdentityHelper.instance()); } - - public final Ix collect(Func0 initialFactory, Action2 collector) { - return new IxCollect(this, initialFactory, collector); + + public final Ix> groupBy(Func1 keySelector, + Func1 valueSelector) { + return new IxGroupBy(this, keySelector, valueSelector); } - public final Ix reduce(Func0 initialFactory, Func2 reducer) { - return new IxReduce(this, initialFactory, reducer); + public final Ix hasElements() { + return new IxHasElements(this); } public final Ix hide() { return new IxWrapper(this); } - public final Ix> toList() { - return collect(ToListHelper.initialFactory(), ToListHelper.collector()); + public final Ix intersect(Iterable other) { + return new IxIntersect(this, other); } - public final Ix toArray() { - return collect(ToListHelper.initialFactory(), ToListHelper.collector()) - .map(ToListHelper.toArray()); + public final Ix ignoreElements() { + return new IxIgnoreElements(this); } - public final Ix reduce(Func2 reducer) { - return new IxAggregate(this, reducer); + public final Ix join() { + return join(", "); } - @SuppressWarnings("unchecked") - public final Ix maxInt() { - return new IxMaxInt((Ix)this); + public final Ix join(CharSequence separator) { + return new IxJoin(this, separator); } - - @SuppressWarnings("unchecked") - public final Ix minInt() { - return new IxMinInt((Ix)this); + + public final Ix lift(Func1, ? extends Iterator> lifter) { + return new IxLift(this, lifter); + } + + public final Ix map(Func1 mapper) { + return new IxMap(this, mapper); + } + + public final Ix max(Comparator comparator) { + return new IxMinMax(this, comparator, -1); } + @SuppressWarnings({ "rawtypes", "unchecked" }) + public final Ix max() { + return max((Comparator)SelfComparator.INSTANCE); + } + @SuppressWarnings("unchecked") - public final Ix sumInt() { - return new IxSumInt((Ix)this); + public final Ix maxInt() { + return new IxMaxInt((Ix)this); } @SuppressWarnings("unchecked") @@ -790,84 +809,73 @@ public final Ix maxLong() { return new IxMaxLong((Ix)this); } - @SuppressWarnings("unchecked") - public final Ix minLong() { - return new IxMinLong((Ix)this); + public final Ix mergeWith(Iterable other) { + return concatWith(other); } - @SuppressWarnings("unchecked") - public final Ix sumLong() { - return new IxSumLong((Ix)this); - } - - @SuppressWarnings("unchecked") - public final Ix toLong() { - return ((Ix)this).map(NumberToLongHelper.INSTANCE); + public final Ix min(Comparator comparator) { + return new IxMinMax(this, comparator, 1); } - public final Ix skip(int n) { - if (n == 0) { - return this; - } - return new IxSkip(this, n); + @SuppressWarnings({ "rawtypes", "unchecked" }) + public final Ix min() { + return min((Comparator)SelfComparator.INSTANCE); } - public final Ix take(int n) { - return new IxTake(this, n); + @SuppressWarnings("unchecked") + public final Ix minInt() { + return new IxMinInt((Ix)this); } - public final Ix skipLast(int n) { - if (n == 0) { - return this; - } - return new IxSkipLast(this, n); + @SuppressWarnings("unchecked") + public final Ix minLong() { + return new IxMinLong((Ix)this); } - public final Ix takeLast(int n) { - return new IxTakeLast(this, n); + @SuppressWarnings({ "unchecked", "rawtypes" }) + public final Ix orderBy() { + return orderBy((Comparator)SelfComparator.INSTANCE); } - public final Ix flatMap(Func1> mapper) { - return new IxFlattenIterable(this, mapper); + public final Ix orderBy(Comparator comparator) { + return new IxOrderBy(this, IdentityHelper.instance(), comparator, 1); } - public final Ix concatMap(Func1> mapper) { - return new IxFlattenIterable(this, mapper); + public final > Ix orderBy(Func1 keySelector) { + return new IxOrderBy(this, keySelector, SelfComparator.INSTANCE, 1); } - public final Ix skipWhile(Pred predicate) { - return new IxSkipWhile(this, predicate); + @SuppressWarnings({ "unchecked", "rawtypes" }) + public final Ix orderByReverse() { + return orderByReverse((Comparator)SelfComparator.INSTANCE); } - public final Ix takeWhile(Pred predicate) { - return new IxTakeWhile(this, predicate); + public final Ix orderByReverse(Comparator comparator) { + return new IxOrderBy(this, IdentityHelper.instance(), comparator, -1); } - public final Ix takeUntil(Pred stopPredicate) { - return new IxTakeUntil(this, stopPredicate); + public final > Ix orderByReverse(Func1 keySelector) { + return new IxOrderBy(this, keySelector, SelfComparator.INSTANCE, -1); } - - public final Ix> buffer(int size) { - return new IxBuffer(this, size); + + public final Ix publish() { + return new IxPublish(this); + } + + public final Ix publish(Func1, ? extends Iterable> transform) { + return new IxPublishSelector(this, transform); } - public final Ix> buffer(int size, int skip) { - if (size == skip) { - return buffer(size); - } - if (size < skip) { - return new IxBufferSkip(this, size, skip); - } - return new IxBufferOverlap(this, size, skip); + public final Ix reduce(Func2 reducer) { + return new IxAggregate(this, reducer); } - public final Ix> groupBy(Func1 keySelector) { - return groupBy(keySelector, IdentityHelper.instance()); + public final Ix reduce(Func0 initialFactory, Func2 reducer) { + return new IxReduce(this, initialFactory, reducer); } - - public final Ix> groupBy(Func1 keySelector, - Func1 valueSelector) { - return new IxGroupBy(this, keySelector, valueSelector); + + public final Ix remove(Pred predicate) { + return new IxRemove(this, predicate); } public final Ix repeat() { @@ -886,14 +894,6 @@ public final Ix repeat(long times, Pred0 predicate) { return concat(repeatValue(this, times, predicate)); } - public final Ix publish() { - return new IxPublish(this); - } - - public final Ix publish(Func1, ? extends Iterable> transform) { - return new IxPublishSelector(this, transform); - } - public final Ix replay() { return new IxReplay(this); } @@ -909,152 +909,158 @@ public final Ix replay(Func1, ? extends Iterable Ix replay(int size, Func1, ? extends Iterable> transform) { return new IxReplaySizeSelector(this, size, transform); } + + public final Ix retain(Pred predicate) { + return new IxRetain(this, predicate); + } - public final Ix> toMap(Func1 keySelector) { - Func1 f = IdentityHelper.instance(); - return this.toMap(keySelector, f); + public final Ix reverse() { + return new IxReverse(this); } - public final Ix> toMap(Func1 keySelector, Func1 valueSelector) { - return new IxToMap(this, keySelector, valueSelector); + public final Ix scan(Func2 scanner) { + return new IxScan(this, scanner); } - public final Ix>> toMultimap(Func1 keySelector) { - Func1 f = IdentityHelper.instance(); - return this.toMultimap(keySelector, f); + public final Ix scan(Func0 initialFactory, Func2 scanner) { + return new IxScanSeed(this, initialFactory, scanner); } - - public final Ix>> toMultimap(Func1 keySelector, Func1 valueSelector) { - return new IxToMultimap(this, keySelector, valueSelector); + + public final Ix sequenceEqual(Iterable other) { + return sequenceEqual(other, EqualityHelper.INSTANCE); } - public final Ix> window(int size) { - return new IxWindow(this, size); + public final Ix sequenceEqual(Iterable other, Pred2 comparer) { + return new IxSequenceEqual(this, other, comparer); } - public final Ix> window(int size, int skip) { - if (size == skip) { - return window(size); - } - if (size < skip) { - return new IxWindowSkip(this, size, skip); + public final Ix skip(int n) { + if (n == 0) { + return this; } - return new IxWindowOverlap(this, size, skip); + return new IxSkip(this, n); } - - @SuppressWarnings("unchecked") - public final Ix concatWith(Iterable other) { - return concatArray(this, other); + + public final Ix skipLast(int n) { + if (n == 0) { + return this; + } + return new IxSkipLast(this, n); } - public final Ix mergeWith(Iterable other) { - return concatWith(other); + public final Ix skipWhile(Pred predicate) { + return new IxSkipWhile(this, predicate); } - public final Ix zipWith(Iterable other, Func2 zipper) { - return zip(this, other, zipper); + @SuppressWarnings("unchecked") + public final Ix startWith(T... values) { + return concatArray(fromArray(values), this); } - - @SuppressWarnings({ "unchecked", "rawtypes" }) - public final Ix orderBy() { - return orderBy((Comparator)SelfComparator.INSTANCE); + + @SuppressWarnings("unchecked") + public final Ix sumInt() { + return new IxSumInt((Ix)this); } - - public final Ix orderBy(Comparator comparator) { - return new IxOrderBy(this, IdentityHelper.instance(), comparator, 1); + + @SuppressWarnings("unchecked") + public final Ix sumLong() { + return new IxSumLong((Ix)this); } - public final > Ix orderBy(Func1 keySelector) { - return new IxOrderBy(this, keySelector, SelfComparator.INSTANCE, 1); + public final Ix switchIfEmpty(Iterable other) { + return new IxSwitchIfEmpty(this, other); } - @SuppressWarnings({ "unchecked", "rawtypes" }) - public final Ix orderByReverse() { - return orderByReverse((Comparator)SelfComparator.INSTANCE); + public final Ix take(int n) { + return new IxTake(this, n); } - public final Ix orderByReverse(Comparator comparator) { - return new IxOrderBy(this, IdentityHelper.instance(), comparator, -1); + public final Ix takeLast(int n) { + return new IxTakeLast(this, n); } - public final > Ix orderByReverse(Func1 keySelector) { - return new IxOrderBy(this, keySelector, SelfComparator.INSTANCE, -1); - } - - public final Ix scan(Func2 scanner) { - return new IxScan(this, scanner); - } - - public final Ix scan(Func0 initialFactory, Func2 scanner) { - return new IxScanSeed(this, initialFactory, scanner); + public final Ix takeUntil(Pred stopPredicate) { + return new IxTakeUntil(this, stopPredicate); } - public final Ix remove(Pred predicate) { - return new IxRemove(this, predicate); - } - - public final Ix retain(Pred predicate) { - return new IxRetain(this, predicate); + public final Ix takeWhile(Pred predicate) { + return new IxTakeWhile(this, predicate); } - - public final Ix transform(IxTransform transformer) { - return new IxTransformer(this, transformer); + + public final Ix toArray() { + return collect(ToListHelper.initialFactory(), ToListHelper.collector()) + .map(ToListHelper.toArray()); } - public final Ix lift(Func1, ? extends Iterator> lifter) { - return new IxLift(this, lifter); + public final Ix> toList() { + return collect(ToListHelper.initialFactory(), ToListHelper.collector()); } @SuppressWarnings("unchecked") - public final Ix averageFloat() { - return new IxAverageFloat((Iterable)this); + public final Ix toLong() { + return ((Ix)this).map(NumberToLongHelper.INSTANCE); } - - @SuppressWarnings("unchecked") - public final Ix averageDouble() { - return new IxAverageDouble((Iterable)this); + + public final Ix> toMap(Func1 keySelector) { + Func1 f = IdentityHelper.instance(); + return this.toMap(keySelector, f); } - public final Ix defaultIfEmpty(T value) { - return switchIfEmpty(Ix.just(value)); + public final Ix> toMap(Func1 keySelector, Func1 valueSelector) { + return new IxToMap(this, keySelector, valueSelector); } - - public final Ix switchIfEmpty(Iterable other) { - return new IxSwitchIfEmpty(this, other); + + public final Ix>> toMultimap(Func1 keySelector) { + Func1 f = IdentityHelper.instance(); + return this.toMultimap(keySelector, f); } - - public final Ix except(Iterable other) { - return new IxExcept(this, other); + + public final Ix>> toMultimap(Func1 keySelector, Func1 valueSelector) { + return new IxToMultimap(this, keySelector, valueSelector); } - public final Ix intersect(Iterable other) { - return new IxIntersect(this, other); + public final Ix> toSet() { + return new IxToSet(this); } - - public final Ix reverse() { - return new IxReverse(this); + + public final Ix transform(IxTransform transformer) { + return new IxTransformer(this, transformer); } - public final Ix sequenceEqual(Iterable other) { - return sequenceEqual(other, EqualityHelper.INSTANCE); + public final Ix union(Iterable other) { + return new IxUnion(this, other); } - public final Ix sequenceEqual(Iterable other, Pred2 comparer) { - return new IxSequenceEqual(this, other, comparer); + public final Ix> window(int size) { + return new IxWindow(this, size); } - - public final Ix> toSet() { - return new IxToSet(this); + + public final Ix> window(int size, int skip) { + if (size == skip) { + return window(size); + } + if (size < skip) { + return new IxWindowSkip(this, size, skip); + } + return new IxWindowOverlap(this, size, skip); } - public final Ix union(Iterable other) { - return new IxUnion(this, other); + public final Ix zipWith(Iterable other, Func2 zipper) { + return zip(this, other, zipper); } //--------------------------------------------------------------------------------------- // Leaving the Iterable world //--------------------------------------------------------------------------------------- + /** + * Returns the first element of this sequence. + * @return the first element + * @throws NoSuchElementException if this sequence is empty + * @since 1.0 + * @see #first(Object) + * @see #last(Object) + */ @SuppressWarnings("unchecked") public final T first() { if (this instanceof Callable) { @@ -1063,6 +1069,15 @@ public final T first() { return iterator().next(); } + /** + * Returns the first element of this sequence or the defaultValue + * if this sequence is empty. + * @param defaultValue the value to return if this sequence is empty + * @return the first element or the default value + * @since 1.0 + * @see #first() + * @see #last() + */ @SuppressWarnings("unchecked") public final T first(T defaultValue) { if (this instanceof Callable) { @@ -1074,7 +1089,60 @@ public final T first(T defaultValue) { } return defaultValue; } + + /** + * Consumes the entire sequence and calls the given action with each value. + * @param action the action to call + * @throws NullPointerException if action is null + * @since 1.0 + * @see #foreachWhile(Pred) + */ + public final void foreach(Action1 action) { + for (T t : this) { + action.call(t); + } + } + + /** + * Consumes the entire sequence and calls the given predicate with each value; + * which can stop the iteration by returning false. + * @param predicate the predicate to call with the current element and should + * return true to continue the loop or false to quit the loop. + * @throws NullPointerException if action is null + * @since 1.0 + * @see #foreach(Pred) + */ + public final void foreachWhile(Pred predicate) { + for (T t : this) { + if (!predicate.test(t)) { + break; + } + } + } + + /** + * Consumes the entire sequence and adds each element into the given collection + * that is also returned. + * @param the collection of type accepting a (super)type of this element type + * @param collection the collection to collect into + * @return the collection itself + * @throws NullPointerException if collection is null + * @since 1.0 + */ + public final > U into(U collection) { + for (T v : this) { + collection.add(v); + } + return collection; + } + /** + * Returns the last element of this sequence. + * @return the last element of this sequence + * @throws NoSuchElementException if the sequence is empty + * @since 1.0 + * @see #last(Object) + */ @SuppressWarnings("unchecked") public final T last() { if (this instanceof Callable) { @@ -1093,6 +1161,15 @@ public final T last() { } } + /** + * Returns the last element of this sequence or the defaultValue if + * this sequence is empty. + * @param defaultValue the value to return if this sequence is empty + * @return the last element or the default value + * @since 1.0 + * @see #last() + * @see #first() + */ @SuppressWarnings("unchecked") public final T last(T defaultValue) { if (this instanceof Callable) { @@ -1110,40 +1187,23 @@ public final T last(T defaultValue) { } } } - - public final void removeAll() { - Iterator it = iterator(); - while (it.hasNext()) { - it.next(); - it.remove(); - } - } - - public final void foreach(Action1 action) { - for (T t : this) { - action.call(t); - } - } - - public final void foreachWhile(Pred action) { - for (T t : this) { - if (!action.test(t)) { - break; - } - } - } - - public final > U into(U collection) { - for (T v : this) { - collection.add(v); - } - return collection; - } + /** + * Prints the elements of this sequence to the console, separated + * by a comma+space and with a line break after roughly 80 characters. + * @since 1.0 + */ public final void print() { print(", ", 80); } + /** + * Prints the elements of this sequence to the console, separated + * by the given separator and with a line break after roughly the + * given charsPerLine amount. + * @param separator the characters to separate the elements + * @param charsPerLine indicates how long a line should be + */ public final void print(CharSequence separator, int charsPerLine) { boolean first = true; int len = 0; @@ -1172,21 +1232,87 @@ public final void print(CharSequence separator, int charsPerLine) { } } + /** + * Prints each element of this sequence into a new line on the console. + * @since 1.0 + */ public final void println() { for (T v : this) { System.out.println(v); } } + /** + * Prints each element of this sequence into a new line on the console, prefixed + * by the given character sequence. + * @param prefix the prefix before each line + */ public final void println(CharSequence prefix) { for (T v : this) { System.out.print(prefix); System.out.println(v); } + } + /** + * Removes all elements by repeatedly calling this sequence's Iterator.remove(). + */ + public final void removeAll() { + Iterator it = iterator(); + while (it.hasNext()) { + it.next(); + it.remove(); + } + } + + /** + * Consumes this Iterable and removes all elements for + * which the predicate returns true; in other words, + * remove those elements of a mutable source that match + * the predicate. + * @param predicate the predicate called with the current + * element and should return true for elements to remove, false + * for elements to keep. + * @throws UnsupportedOperationException if the this Iterable + * doesn't allow removing elements. + * @see #retainAll(Pred) + * @see #removeAll() + * @since 1.0 + */ + public final void removeAll(Pred predicate) { + Iterator it = iterator(); + while (it.hasNext()) { + T v = it.next(); + if (predicate.test(v)) { + it.remove(); + } + } + } + /** + * Consumes this Iterable and removes all elements for + * which the predicate returns false; in other words, + * retain those elements of a mutable source that match + * the predicate. + * @param predicate the predicate called with the current + * element and should return true for elements to keep, false + * for elements to remove. + * @throws UnsupportedOperationException if the this Iterable + * doesn't allow removing elements. + * @see #removeAll(Pred) + * @since 1.0 + */ + public final void retainAll(Pred predicate) { + Iterator it = iterator(); + while (it.hasNext()) { + T v = it.next(); + if (!predicate.test(v)) { + it.remove(); + } + } } /** * Iterates over this instance, dropping all values it produces. + * @see #subscribe() */ public final void run() { Iterator it = iterator(); @@ -1195,20 +1321,85 @@ public final void run() { } } + /** + * Returns the single element of this sequence or throws a NoSuchElementException + * if this sequence is empty or IndexOutOfBoundsException if this sequence has more + * than on element + * @return the single element of the sequence + * @throws IndexOutOfBoundsException if the sequence has more than one element + * @throws NoSuchElementException if the sequence is empty + * @since 1.0 + * @see #single(Object) + */ + public final T single() { + Iterator it = iterator(); + if (it.hasNext()) { + T v = it.next(); + if (it.hasNext()) { + throw new IndexOutOfBoundsException("The source has more than one element."); + } + return v; + } + throw new NoSuchElementException("The source is empty."); + } + + + /** + * Returns the single element of this sequence, the defaltValue + * if this sequence is empty or IndexOutOfBoundsException if this sequence has more + * than on element + * @param defaultValue the value to return if this sequence is empty + * @return the single element of the sequence + * @throws IndexOutOfBoundsException if the sequence has more than one element + * @since 1.0 + * @see #single(Object) + */ + public final T single(T defaultValue) { + Iterator it = iterator(); + if (it.hasNext()) { + T v = it.next(); + if (it.hasNext()) { + throw new IndexOutOfBoundsException("The source has more than one element."); + } + return v; + } + return defaultValue; + } + + /** + * Iterates over this instance, dropping all values it produces. + * @see #run() + */ public final void subscribe() { run(); } - public final void subscribe(Action1 consumer) { + /** + * Iterates over this sequence and calls the given onNext action with + * each element. + * @param onNext the consumer to call with each element + * @throws NullPointerException if consumer is null + * @since 1.0 + */ + public final void subscribe(Action1 onNext) { for (T v : this) { - consumer.call(v); + onNext.call(v); } } - public final void subscribe(Action1 consumer, Action1 onError) { + /** + * Iterates over this sequence and calls the given onNext action with + * each element and calls the onError with any exception thrown by the iteration + * or the onNext action. + * @param onNext the consumer to call with each element + * @param onError the consumer to call with the exception thrown + * @throws NullPointerException if onError is null + * @since 1.0 + */ + public final void subscribe(Action1 onNext, Action1 onError) { try { for (T v : this) { - consumer.call(v); + onNext.call(v); } } catch (Throwable ex) { Exceptions.throwIfFatal(ex); @@ -1216,10 +1407,21 @@ public final void subscribe(Action1 consumer, Action1 onEr } } - public final void subscribe(Action1 consumer, Action1 onError, Action0 onCompleted) { + /** + * Iterates over this sequence and calls the given onNext action with + * each element and calls the onError with any exception thrown by the iteration + * or the onNext action; otherwise calls the onCompleted action when the sequence completes + * without exception. + * @param onNext the consumer to call with each element + * @param onError the consumer to call with the exception thrown + * @param onCompleted the action called after the sequence has been consumed + * @throws NullPointerException if onError or onCompleted is null + * @since 1.0 + */ + public final void subscribe(Action1 onNext, Action1 onError, Action0 onCompleted) { try { for (T v : this) { - consumer.call(v); + onNext.call(v); } } catch (Throwable ex) { Exceptions.throwIfFatal(ex); @@ -1229,6 +1431,12 @@ public final void subscribe(Action1 consumer, Action1 onEr onCompleted.call(); } + /** + * Consumes this sequence and calls the appropriate onXXX method on the given Observer instance. + * @param observer the observer to forward values, error or completion to. + * @throws NullPointerException if observer is null + * @since 1.0 + */ public final void subscribe(Observer observer) { try { for (T v : this) { @@ -1242,6 +1450,13 @@ public final void subscribe(Observer observer) { observer.onCompleted(); } + /** + * Consumes this sequence and calls the appropriate onXXX method on the given Subscriber instance + * as long as it has not unsubscribed. + * @param subscriber the subscriber to forward values, error or completion to. + * @throws NullPointerException if subscriber is null + * @since 1.0 + */ public final void subscribe(Subscriber subscriber) { try { for (T v : this) { @@ -1263,78 +1478,6 @@ public final void subscribe(Subscriber subscriber) { } subscriber.onCompleted(); } - - /** - * Consumes this Iterable and removes all elements for - * which the predicate returns false; in other words, - * retain those elements of a mutable source that match - * the predicate. - * @param predicate the predicate called with the current - * element and should return true for elements to keep, false - * for elements to remove. - * @throws UnsupportedOperationException if the this Iterable - * doesn't allow removing elements. - * @see #removeAll(Pred) - * @since 1.0 - */ - public final void retainAll(Pred predicate) { - Iterator it = iterator(); - while (it.hasNext()) { - T v = it.next(); - if (!predicate.test(v)) { - it.remove(); - } - } - } - - /** - * Consumes this Iterable and removes all elements for - * which the predicate returns true; in other words, - * remove those elements of a mutable source that match - * the predicate. - * @param predicate the predicate called with the current - * element and should return true for elements to remove, false - * for elements to keep. - * @throws UnsupportedOperationException if the this Iterable - * doesn't allow removing elements. - * @see #retainAll(Pred) - * @see #removeAll() - * @since 1.0 - */ - public final void removeAll(Pred predicate) { - Iterator it = iterator(); - while (it.hasNext()) { - T v = it.next(); - if (predicate.test(v)) { - it.remove(); - } - } - } - - - public final T single() { - Iterator it = iterator(); - if (it.hasNext()) { - T v = it.next(); - if (it.hasNext()) { - throw new IndexOutOfBoundsException("The source has more than one element."); - } - return v; - } - throw new NoSuchElementException("The source is empty."); - } - - public final T single(T defaultValue) { - Iterator it = iterator(); - if (it.hasNext()) { - T v = it.next(); - if (it.hasNext()) { - throw new IndexOutOfBoundsException("The source has more than one element."); - } - return v; - } - return defaultValue; - } // -------------------------------------------------------------------------------------------- // Helper methods From b6185bdc84a8c8b90a316076d339a22938397a1d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?D=C3=A1vid=20Karnok?= Date: Fri, 15 Jul 2016 23:54:59 +0200 Subject: [PATCH 29/66] Javadoc part 3 --- src/main/java/ix/Ix.java | 448 +++++++++++++++++++++++++++++++-- src/main/java/ix/IxRemove.java | 2 +- src/main/java/ix/IxRetain.java | 2 +- src/test/java/ix/IxTest.java | 29 +++ 4 files changed, 457 insertions(+), 24 deletions(-) diff --git a/src/main/java/ix/Ix.java b/src/main/java/ix/Ix.java index 508093a..91b5897 100644 --- a/src/main/java/ix/Ix.java +++ b/src/main/java/ix/Ix.java @@ -636,156 +636,531 @@ public static Ix zip( // Instance operators //--------------------------------------------------------------------------------------- + /** + * Emits true if all elements of this sequence match a given predicate (including empty). + *

+ * The result's iterator() doesn't support remove(). + * @param predicate the predicate receiving each element + * @return the new Ix instance + * @throws NullPointerException if predicate is null + * @since 1.0 + */ public final Ix all(Pred predicate) { - return new IxAll(this, predicate); + return new IxAll(this, nullCheck(predicate, "predicate is null")); } + + /** + * Emits true if any element of this sequence matches the given predicate, + * false otherwise (or for empty sequences). + *

+ * The result's iterator() doesn't support remove(). + * @param predicate the predicate receiving each element + * @return the new Ix instance + * @throws NullPointerException if predicate is null + * @since 1.0 + */ public final Ix any(Pred predicate) { - return new IxAny(this, predicate); + return new IxAny(this, nullCheck(predicate, "predicate is null")); } + /** + * Calls the given transformers with this and returns its value allowing + * fluent conversions to non-Ix types. + * @param the result type + * @param transformer the function receiving this Ix instance and returns a value + * @return the value returned by the transformer function + * @throws NullPointerException if transformer is null + * @since 1.0 + */ public final R as(Func1, R> transformer) { return transformer.call(this); } + /** + * Calculates the float-based average of this sequence of numbers. + *

The returned sequence is empty if this sequence is empty. + *

This operator force-casts this sequence which may lead + * to ClassCastException if any of this sequence's elements is not + * a subclass of Number. + *

+ * The result's iterator() doesn't support remove(). + * @return the new Ix instance + * @since 1.0 + */ @SuppressWarnings("unchecked") public final Ix averageFloat() { return new IxAverageFloat((Iterable)this); } + /** + * Calculates the double-based average of this sequence of numbers. + *

The returned sequence is empty if this sequence is empty. + *

This operator force-casts this sequence which may lead + * to ClassCastException if any of this sequence's elements is not + * a subclass of Number. + *

+ * The result's iterator() doesn't support remove(). + * @return the new Ix instance + * @since 1.0 + */ @SuppressWarnings("unchecked") public final Ix averageDouble() { return new IxAverageDouble((Iterable)this); } + /** + * Buffers the subsequent {@code size} elements into a sequence of + * non-overlapping Lists. + *

+ * The result's iterator() doesn't support remove(). + * @param size the number of elements to group together, positive + * @return the new Ix instance + * @throws IllegalArgumentException if size is non-positive + * @since 1.0 + */ public final Ix> buffer(int size) { - return new IxBuffer(this, size); + return new IxBuffer(this, positive(size, "size")); } + /** + * Buffers the subsequent {@code size} elemeints into a sequence of + * potentially overlapping Lists. + *

+ * The result's iterator() doesn't support remove(). + * @param size the number of elements to group together, positive + * @param skip specifies how often to start a new list + * @return the new Ix instance + * @throws IllegalArgumentException if size or skip is non-positive + * @since 1.0 + */ public final Ix> buffer(int size, int skip) { if (size == skip) { return buffer(size); } if (size < skip) { - return new IxBufferSkip(this, size, skip); + return new IxBufferSkip(this, positive(size, "size"), positive(skip, "skip")); } - return new IxBufferOverlap(this, size, skip); + return new IxBufferOverlap(this, positive(size, "size"), positive(skip, "skip")); } + /** + * Collect the elements into a collection via collector action and emit that collection + * as a single item. + *

+ * The result's iterator() doesn't support remove(). + * @param the collection type + * @param initialFactory the function returning a collection for each iterator() call + * @param collector the action called with the collection and the current item + * @return the new Ix instance + * @throws NullPointerException if initialFactory or collector is null + * @since 1.0 + */ public final Ix collect(Func0 initialFactory, Action2 collector) { - return new IxCollect(this, initialFactory, collector); + return new IxCollect(this, nullCheck(initialFactory, "initalFactory is null"), nullCheck(collector, "collector")); } + /** + * When the iterator() of the returned Ix is called, it calls the transformer function + * with this Ix instance and emits the elements of the returned Iterable. + *

+ * The result's iterator() forwards the call remove() to the returned Iterable's Iterator. + * + * @param the result value type + * @param transformer the transformer called with this Ix when Ix.iterator() is invoked + * @return the new Ix instance + * @throws NullPointerException if transformer is null + * @since 1.0 + */ public final Ix compose(Func1, ? extends Iterable> transformer) { - return new IxCompose(this, transformer); + return new IxCompose(this, nullCheck(transformer, "transformer is null")); } + /** + * Maps each element from this sequence into subsequent Iterable sequences whose elmenents are + * concatenated in order. + *

+ * Note that flatMap and concatMap operations are the same in the Iterable world. + *

+ * The result's iterator() forwards the call remove() to the current inner Iterator. + * + * @param the result value type + * @param mapper the function + * @return the new Ix instance + * @throws NullPointerException if mapper is null + * @since 1.0 + * @see #flatMap(Func1) + */ public final Ix concatMap(Func1> mapper) { - return new IxFlattenIterable(this, mapper); + return new IxFlattenIterable(this, nullCheck(mapper, "mapper is null")); } - @SuppressWarnings("unchecked") + /** + * Emits elements of this sequence followed by the elements of the other sequence. + *

+ * The result's iterator() forwards the call remove() to the current Iterator. + * @param other the other sequence to emits elements of + * @return the new Ix instance + * @throws NullPointerException if other is null + * @since 1.0 + */ public final Ix concatWith(Iterable other) { - return concatArray(this, other); + return concat(this, other); } + /** + * Emits true if the sequence contains the given Object, compared via null-safe + * equals. + *

+ * The result's iterator() doesn't support remove(). + * @param o the value to find + * @return the new Ix instance + * @since 1.0 + */ public final Ix contains(Object o) { return new IxContains(this, o); } + /** + * Emits the number of elements in this sequence. + *

+ * The result's iterator() doesn't support remove(). + * @return the number of elements in this sequence + * @since 1.0 + */ public final Ix count() { return new IxCount(this); } + /** + * Emits the number of elements, as a long, in this sequence. + *

+ * The result's iterator() doesn't support remove(). + * @return the number of elements in this sequence + * @since 1.0 + */ public final Ix countLong() { return new IxCountLong(this); } + /** + * Emits the given value if this sequence is empty, streams this sequence otherwise. + *

+ * The result's iterator() doesn't support remove(). + * @param value the value to emit if this sequence is empty + * @return the new Ix instance + * @since 1.0 + */ public final Ix defaultIfEmpty(T value) { return switchIfEmpty(Ix.just(value)); } + /** + * Emits only distinct, never before seen elements (according to null-safe equals()) + * of this sequence. + *

+ * Note that this operator uses a memory of seen elements which may grow unbounded + * with long sequences. + *

+ * The result's iterator() doesn't support remove(). + * @return the new Ix instance + * @since 1.0 + */ public final Ix distinct() { return distinct(IdentityHelper.instance()); } + /** + * Emits only distinct, never before seen keys extracted from elements + * (according to null-safe equals()) of this sequence. + *

+ * Note that this operator uses a memory of seen elements which may grow unbounded + * with long sequences. + *

+ * The result's iterator() doesn't support remove(). + * @param the key type + * @param keySelector the function taking the current element and returning a key object + * that will be compared with null-safe equals(). + * @return the new Ix instance + * @throws NullPointerException if keySelector is null + * @since 1.0 + */ public final Ix distinct(Func1 keySelector) { - return new IxDistinct(this, keySelector); + return new IxDistinct(this, nullCheck(keySelector, "keySelector is null")); } + /** + * Emits elements from this sequence if each element is different from the previous element + * (according to a null-safe equals()), dropping elements that evaluate to the same as the previous. + *

+ * The result's iterator() doesn't support remove(). + * @return the new Ix instance + * @since 1.0 + */ public final Ix distinctUntilChanged() { return distinctUntilChanged(IdentityHelper.instance()); } + /** + * Emits elements from this sequence if each element is different from the previous element + * (according to a comparer), dropping elements that evaluate to the same as the previous. + *

+ * The result's iterator() doesn't support remove(). + * @param comparer the predicate receiving the previous element and the current element and + * returns true if they are the same (thus ignoring the latter). + * @return the new Ix instance + * @throws NullPointerException if comparer is null + * @since 1.0 + */ public final Ix distinctUntilChanged(Pred2 comparer) { - return new IxDistinctUntilChanged(this, IdentityHelper.instance(), comparer); + return new IxDistinctUntilChanged(this, IdentityHelper.instance(), nullCheck(comparer, "comparer is null")); } + /** + * Emits elements from this sequence if each element is different from the previous element + * (according to a null-safe equals() of the extracted key), dropping elements that evaluate + * to the same as the previous. + *

+ * The result's iterator() doesn't support remove(). + * @param the key type + * @param keySelector the function that receives the current element and returns a key that will be compared + * via null-safe equals with the previous element's key + * @return the new Ix instance + * @throws NullPointerException if comparer is null + * @since 1.0 + */ public final Ix distinctUntilChanged(Func1 keySelector) { return new IxDistinctUntilChanged(this, keySelector, EqualityHelper.INSTANCE); } + /** + * Calls the given action just before when the consumer calls next() of this Ix.iterator(). + *

+ * The result's iterator() forwards calls to remove() to this Iterator. + * @param action the action to call for each item + * @return the new Ix instance + * @throws NullPointerException if action is null + * @since 1.0 + */ public final Ix doOnNext(Action1 action) { - return new IxDoOn(this, action, IxEmptyAction.instance0()); + return new IxDoOn(this, nullCheck(action, "action is null"), IxEmptyAction.instance0()); } + /** + * Calls the given action after consumption of this sequence has completed, i.e., when + * hasNext() of this Ix.iterator() returns false. + *

+ * The result's iterator() forwards calls to remove() to this' Iterator. + * @param action the action to call after the source sequence completes + * @return the new Ix instance + * @throws NullPointerException if action is null + * @since 1.0 + */ public final Ix doOnCompleted(Action0 action) { - return new IxDoOn(this, IxEmptyAction.instance1(), action); + return new IxDoOn(this, IxEmptyAction.instance1(), nullCheck(action, "action is null")); } - @SuppressWarnings("unchecked") + /** + * Emits the elements of this sequence followed by the elements of the given array of values. + *

+ * The result's iterator() doesn't support remove(). + * @param values the elements to emit after this sequence + * @return the new Ix instance + * @throws NullPointerException if values is null + * @since 1.0 + */ public final Ix endWith(T... values) { - return concatArray(this, fromArray(values)); + return concat(this, fromArray(values)); } + /** + * Emits distinct elements from this and the other Iterable which are not + * in the other sequence (i.e., (A union B) minus (A intersection B)). + *

+ * The result's iterator() doesn't support remove(). + * @param other the other Iterable sequence, not null + * @return the new Ix instance + * @throws NullPointerException if other is null + * @since 1.0 + */ public final Ix except(Iterable other) { - return new IxExcept(this, other); + return new IxExcept(this, nullCheck(other, "other is null")); } + /** + * Emits elements of this sequence which match the given predicate only. + *

+ * The result's iterator() forwards the call to remove() to this' Iterator. + * @param predicate the predicate receiving the current element and if it + * returns true, the value is emitted, ingored otherwise. + * @return the new Ix instance + * @throws NullPointerException if predicate is null + * @since 1.0 + */ public final Ix filter(Pred predicate) { - return new IxFilter(this, predicate); + return new IxFilter(this, nullCheck(predicate, "predicate is null")); } + /** + * Maps each element from this sequence into subsequent Iterable sequences whose elmenents are + * concatenated in order. + *

+ * Note that flatMap and concatMap operations are the same in the Iterable world. + *

+ * The result's iterator() forwards the call remove() to the current inner Iterator. + * + * @param the result value type + * @param mapper the function + * @return the new Ix instance + * @throws NullPointerException if mapper is null + * @since 1.0 + * @see #concatMap(Func1) + */ public final Ix flatMap(Func1> mapper) { return new IxFlattenIterable(this, mapper); } + /** + * Groups elements of this sequence into distinct groups keyed by the keys returned by the keySelector. + *

+ * The operator doesn't lose data and calling hasNext/next on either the returned Ix or on the inner + * GroupedIx can move the source sequence forward. + *

+ * The result's iterator() and the inner groups' Iterators don't support remove(). + * @param the key type + * @param keySelector the function receiving the current element and returns the key to be used for + * grouping the values into the same inner GroupedIx. + * @return the new Ix instance + * @throws NullPointerException if keySelector is null + * @since 1.0 + * @see #groupBy(Func1, Func1) + */ public final Ix> groupBy(Func1 keySelector) { return groupBy(keySelector, IdentityHelper.instance()); } + /** + * Groups mapped elements (by the valueSelector) of this sequence into distinct groups + * keyed by the keys returned by the keySelector. + *

+ * The operator doesn't lose data and calling hasNext/next on either the returned Ix or on the inner + * GroupedIx can move the source sequence forward. + *

+ * The result's iterator() and the inner groups' Iterators don't support remove(). + * @param the key type + * @param the value type + * @param keySelector the function receiving the current element and returns the key to be used for + * grouping the values into the same inner GroupedIx. + * @param valueSelector the function receiving the current element and returns the value to be emitted + * by the appropriate group + * @return the new Ix instance + * @throws NullPointerException if keySelector or valueSelector is null + * @since 1.0 + * @see #groupBy(Func1, Func1) + */ public final Ix> groupBy(Func1 keySelector, Func1 valueSelector) { - return new IxGroupBy(this, keySelector, valueSelector); + return new IxGroupBy(this, nullCheck(keySelector, "keySelector is null"), nullCheck(valueSelector, "valueSelector is null")); } - + + /** + * Emits true if this sequence has elements, emits false otherwise. + *

+ * The result's iterator() doesn't support remove(). + * @return the new Ix instance + * @since 1.0 + */ public final Ix hasElements() { return new IxHasElements(this); } + /** + * Hides the identity of this Ix instance and prevents certain identity-based optimiziations. + *

+ * The result's iterator() forwards the remove() calls to this' Iterator. + * @return the new Ix instance + * @since 1.0 + */ public final Ix hide() { return new IxWrapper(this); } + /** + * Emits distinct values of this and the other Iterables that are present in + * both sequences. + *

+ * The result's iterator() doesn't support remove(). + * @param other the other Iterable sequence + * @return the new Ix instance + * @throws NullPointerException if other is null + * @since 1.0 + */ public final Ix intersect(Iterable other) { - return new IxIntersect(this, other); + return new IxIntersect(this, nullCheck(other, "other is null")); } + /** + * Runs through this sequence, ignoring all values until this sequence completes. + *

+ * The result's iterator() doesn't support remove(). + * @return the new Ix instance + * @since 1.0 + */ public final Ix ignoreElements() { return new IxIgnoreElements(this); } + /** + * Converts elements of this sequence to String and concatenates them into + * a single, comma separated String. + *

+ * The result's iterator() doesn't support remove(). + * @return the new Ix instance + * @since 1.0 + */ public final Ix join() { return join(", "); } + /** + * Converts elements of this sequence to String and concatenates them into + * a single String separated by the given character sequence. + *

+ * The result's iterator() doesn't support remove(). + * @param separator the character sequence separating elements + * @return the new Ix instance + * @since 1.0 + */ public final Ix join(CharSequence separator) { return new IxJoin(this, separator); } + /** + * Calls the given lifter function with the iterator of this sequence and emits + * elements of the returned Iterator. + *

+ * The result's iterator() forwards the remove() calls to the returned Iterator. + * @param the result value type + * @param lifter the function that receives the Iterator of this and returns an Iterator + * that will be consumed further on + * @return the new Ix instance + * @throws NullPointerException if lifter is null + * @since 1.0 + */ public final Ix lift(Func1, ? extends Iterator> lifter) { - return new IxLift(this, lifter); + return new IxLift(this, nullCheck(lifter, "lifter is null")); } + /** + * Maps each element of this sequence to some other value. + *

+ * The result's iterator() forwards the remove() calls to this' Iterator. + * @param the result value type + * @param mapper the function that receives an element from this sequence + * and returns another value for it to be emitted. + * @return the new Ix instance + * @throws NullPointerException if mapper is null + * @since 1.0 + */ public final Ix map(Func1 mapper) { return new IxMap(this, mapper); } @@ -1532,4 +1907,33 @@ protected static long nonNegative(long n, String name) { } return n; } + + /** + * Checks if the given value is non-negative and returns it; throws + * an IllegalArgumentException otherwise + * @param n the number to check + * @param name the name of the parameter + * @return n + */ + protected static int nonNegative(int n, String name) { + if (n < 0L) { + throw new IllegalArgumentException(name + " >= 0 required but it was " + n); + } + return n; + } + + /** + * Checks if the given value is positive and returns it; throws + * an IllegalArgumentException otherwise + * @param n the number to check + * @param name the name of the parameter + * @return n + */ + protected static int positive(int n, String name) { + if (n <= 0L) { + throw new IllegalArgumentException(name + " > 0 required but it was " + n); + } + return n; + } + } diff --git a/src/main/java/ix/IxRemove.java b/src/main/java/ix/IxRemove.java index fa3285e..ef2ba4c 100644 --- a/src/main/java/ix/IxRemove.java +++ b/src/main/java/ix/IxRemove.java @@ -18,7 +18,7 @@ import java.util.Iterator; -public class IxRemove extends IxSource { +final class IxRemove extends IxSource { final Pred predicate; diff --git a/src/main/java/ix/IxRetain.java b/src/main/java/ix/IxRetain.java index 274be72..6be2f4a 100644 --- a/src/main/java/ix/IxRetain.java +++ b/src/main/java/ix/IxRetain.java @@ -18,7 +18,7 @@ import java.util.Iterator; -public class IxRetain extends IxSource { +final class IxRetain extends IxSource { final Pred predicate; diff --git a/src/test/java/ix/IxTest.java b/src/test/java/ix/IxTest.java index e7e78e9..3102a19 100644 --- a/src/test/java/ix/IxTest.java +++ b/src/test/java/ix/IxTest.java @@ -72,6 +72,18 @@ public void nonNegativeLong() { Ix.nonNegative(0L, "n"); Ix.nonNegative(1L, "n"); + try { + Ix.nonNegative(-99L, "n"); + } catch (IllegalArgumentException ex) { + Assert.assertEquals("n >= 0 required but it was -99", ex.getMessage()); + } + } + + @Test + public void nonNegativeInt() { + Ix.nonNegative(0, "n"); + Ix.nonNegative(1, "n"); + try { Ix.nonNegative(-99, "n"); } catch (IllegalArgumentException ex) { @@ -79,4 +91,21 @@ public void nonNegativeLong() { } } + @Test + public void positiveInt() { + Ix.nonNegative(1, "n"); + + try { + Ix.positive(0, "n"); + } catch (IllegalArgumentException ex) { + Assert.assertEquals("n > 0 required but it was 0", ex.getMessage()); + } + + try { + Ix.positive(-99, "n"); + } catch (IllegalArgumentException ex) { + Assert.assertEquals("n > 0 required but it was -99", ex.getMessage()); + } + } + } From 80248455935747fc26a566a51341dbf6dd4abf20 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?D=C3=A1vid=20Karnok?= Date: Sat, 16 Jul 2016 00:50:14 +0200 Subject: [PATCH 30/66] Javadoc part 4 --- src/main/java/ix/Ix.java | 487 ++++++++++++++++++++++++++++++++++++--- 1 file changed, 460 insertions(+), 27 deletions(-) diff --git a/src/main/java/ix/Ix.java b/src/main/java/ix/Ix.java index 91b5897..82c9b64 100644 --- a/src/main/java/ix/Ix.java +++ b/src/main/java/ix/Ix.java @@ -440,7 +440,8 @@ public static Ix repeatValue(T value) { /** * Repeats the given value at most count times. - *

A count of zero will yield an empty sequence, a count of one + *

+ * A count of zero will yield an empty sequence, a count of one * will yield a sequence with only one element and so forth. *

* The result's iterator() doesn't support remove(). @@ -457,7 +458,8 @@ public static Ix repeatValue(T value, long count) { /** * Repeats the given value until the given predicate returns true. - *

A count of zero will yield an empty sequence, a count of one + *

+ * A count of zero will yield an empty sequence, a count of one * will yield a sequence with only one element and so forth. *

* The result's iterator() doesn't support remove(). @@ -475,7 +477,8 @@ public static Ix repeatValue(T value, Pred0 stopPredicate) { /** * Repeats the given value at most count times or until the given predicate returns true. - *

A count of zero will yield an empty sequence, a count of one + *

+ * A count of zero will yield an empty sequence, a count of one * will yield a sequence with only one element and so forth. *

* The result's iterator() doesn't support remove(). @@ -797,11 +800,14 @@ public final Ix concatMap(Func1 + * Note that mergeWith and concatWith operations are the same in the Iterable world. + *

* The result's iterator() forwards the call remove() to the current Iterator. * @param other the other sequence to emits elements of * @return the new Ix instance * @throws NullPointerException if other is null * @since 1.0 + * @see #mergeWith(Iterable) */ public final Ix concatWith(Iterable other) { return concat(this, other); @@ -1165,171 +1171,598 @@ public final Ix map(Func1 mapper) { return new IxMap(this, mapper); } + /** + * Emits the first maximum element according to the given comparator. + *

+ * The result's iterator() doesn't support remove(). + * @param comparator the comparator called with the latest maximum element and + * the current element; if it returns a positive value, the current element + * becomes the maximum element. + * @return the new Ix instance + * @throws NullPointerException if comparator is null + * @since 1.0 + * @see #min(Comparator) + */ public final Ix max(Comparator comparator) { return new IxMinMax(this, comparator, -1); } + /** + * Emits the first maximum element according to their natural order. + *

+ * The sequence may throw a ClassCastException if any of the elements is + * not self-comparable (i.e., doesn't implement the Comparable interface). + *

+ * The result's iterator() doesn't support remove(). + * @return the new Ix instance + * @since 1.0 + * @see #min() + */ @SuppressWarnings({ "rawtypes", "unchecked" }) public final Ix max() { return max((Comparator)SelfComparator.INSTANCE); } + /** + * Returns the first maximum integer value. + *

+ * The sequence may throw a ClassCastException if any of the elements is not + * an Integer object. + *

+ * The result's iterator() doesn't support remove(). + * @return the new Ix instance + * @since 1.0 + */ @SuppressWarnings("unchecked") public final Ix maxInt() { return new IxMaxInt((Ix)this); } + /** + * Returns the first maximum long value. + *

+ * The sequence may throw a ClassCastException if any of the elements is not + * a Long object. + *

+ * The result's iterator() doesn't support remove(). + * @return the new Ix instance + * @since 1.0 + */ @SuppressWarnings("unchecked") public final Ix maxLong() { return new IxMaxLong((Ix)this); } + /** + * Emits elements of this sequence followed by the elements of the other sequence. + *

+ * Note that mergeWith and concatWith operations are the same in the Iterable world. + *

+ * The result's iterator() forwards the call remove() to the current Iterator. + * @param other the other sequence to emits elements of + * @return the new Ix instance + * @throws NullPointerException if other is null + * @since 1.0 + * @see #concatWith(Iterable) + */ public final Ix mergeWith(Iterable other) { return concatWith(other); } + /** + * Emits the first minimum element according to the given comparator. + *

+ * The result's iterator() doesn't support remove(). + * @param comparator the comparator called with the latest minimum element and + * the current element; if it returns a negative value, the current element + * becomes the minimum element. + * @return the new Ix instance + * @throws NullPointerException if comparator is null + * @since 1.0 + * @see #max(Comparator) + */ public final Ix min(Comparator comparator) { return new IxMinMax(this, comparator, 1); } + /** + * Emits the first minimum element according to their natural order. + *

+ * The sequence may throw a ClassCastException if any of the element is + * not self-comparable (i.e., doesn't implement the Comparable interface). + *

+ * The result's iterator() doesn't support remove(). + * @return the new Ix instance + * @since 1.0 + * @see #min() + */ @SuppressWarnings({ "rawtypes", "unchecked" }) public final Ix min() { return min((Comparator)SelfComparator.INSTANCE); } + /** + * Returns the first minimum integer value. + *

+ * The sequence may throw a ClassCastException if any of the elements is not + * an Integer object. + *

+ * The result's iterator() doesn't support remove(). + * @return the new Ix instance + * @since 1.0 + */ @SuppressWarnings("unchecked") public final Ix minInt() { return new IxMinInt((Ix)this); } + /** + * Returns the first minimum long value. + *

+ * The sequence may throw a ClassCastException if any of the elements is not + * a Long object. + *

+ * The result's iterator() doesn't support remove(). + * @return the new Ix instance + * @since 1.0 + */ @SuppressWarnings("unchecked") public final Ix minLong() { return new IxMinLong((Ix)this); } + /** + * Orders elements according to their natural order. + *

+ * The sequence may throw a ClassCastException if any of the elements is not + * a self-comparable object (i.e., doesn't implement the Comparable interface). + *

+ * The result's iterator() doesn't support remove(). + * @return the new Ix instance + * @since 1.0 + * @see #orderByReverse() + * @see #orderBy(Comparator) + */ @SuppressWarnings({ "unchecked", "rawtypes" }) public final Ix orderBy() { return orderBy((Comparator)SelfComparator.INSTANCE); } + /** + * Orders elements according to the comparator. + *

+ * The result's iterator() doesn't support remove(). + * @param comparator the comparator comparing two elements; if it returns a negative value, + * the first element will be before the second; if it returns a positive value, + * the first element will be after the second. + * @return the new Ix instance + * @throws NullPointerException if comparator is null + * @since 1.0 + * @see #orderBy() + * @see #orderByReverse(Comparator) + */ public final Ix orderBy(Comparator comparator) { - return new IxOrderBy(this, IdentityHelper.instance(), comparator, 1); + return new IxOrderBy(this, IdentityHelper.instance(), nullCheck(comparator, "comparator is null"), 1); } + /** + * Orders elements according to the natural order of the extracted keys from these elements. + *

+ * The result's iterator() doesn't support remove(). + * @param the key type + * @param keySelector the function receiving each element and returns a self-comparable key for them. + * @return the new Ix instance + * @throws NullPointerException if keySelector is null + * @since 1.0 + * @see #orderByReverse(Func1) + */ public final > Ix orderBy(Func1 keySelector) { - return new IxOrderBy(this, keySelector, SelfComparator.INSTANCE, 1); + return new IxOrderBy(this, nullCheck(keySelector, "keySelector is null"), SelfComparator.INSTANCE, 1); } + /** + * Orders elements according to their reverse natural order. + *

+ * The sequence may throw a ClassCastException if any of the elements is not + * a self-comparable object (i.e., doesn't implement the Comparable interface). + *

+ * The result's iterator() doesn't support remove(). + * @return the new Ix instance + * @since 1.0 + * @see #orderBy() + * @see #orderByReverse(Comparator) + */ @SuppressWarnings({ "unchecked", "rawtypes" }) public final Ix orderByReverse() { return orderByReverse((Comparator)SelfComparator.INSTANCE); } + /** + * Orders elements according to the reversed comparator. + *

+ * The result's iterator() doesn't support remove(). + * @param comparator the comparator comparing two elements; if it returns a negative value, + * the first element will be after the second; if it returns a positive value, + * the first element will be before the second. + * @return the new Ix instance + * @throws NullPointerException if comparator is null + * @since 1.0 + * @see #orderByReverse() + * @see #orderBy(Comparator) + */ public final Ix orderByReverse(Comparator comparator) { - return new IxOrderBy(this, IdentityHelper.instance(), comparator, -1); + return new IxOrderBy(this, IdentityHelper.instance(), nullCheck(comparator, "comparator is null"), -1); } + /** + * Orders elements according to the reverse natural order of the extracted keys from these elements. + *

+ * The result's iterator() doesn't support remove(). + * @param the key type + * @param keySelector the function receiving each element and returns a self-comparable key for them. + * @return the new Ix instance + * @throws NullPointerException if keySelector is null + * @since 1.0 + * @see #orderByReverse(Func1) + */ public final > Ix orderByReverse(Func1 keySelector) { - return new IxOrderBy(this, keySelector, SelfComparator.INSTANCE, -1); + return new IxOrderBy(this, nullCheck(keySelector, "keySelector is null"), SelfComparator.INSTANCE, -1); } + /** + * Shares an underlying Iterator that is consumed only once and each created iterator() that calls + * next() will receive the elements; other iterator() instances may receive different or no elements + * at all. + *

+ * The result's iterator() doesn't support remove(). + * @return the new iterator sequence + * @since 1.0 + */ public final Ix publish() { return new IxPublish(this); } + /** + * Shares an Iterator, exposed as an Ix sequence, for the duration of the transform function called + * for each iterator() invocation and emits elements of the resulting iterable sequence of the function. + *

+ * The result's iterator() doesn't support remove(). + * @param the result value type + * @param transform the function that receives an Ix instance sharing a single underlying Iterator to this + * sequence and returns another Iterable to be the result sequence + * @return the new Iterable sequence + * @throws NullPointerException if transform is null + * @since 1.0 + */ public final Ix publish(Func1, ? extends Iterable> transform) { - return new IxPublishSelector(this, transform); + return new IxPublishSelector(this, nullCheck(transform, "transfrom is null")); } + /** + * Reduces the elements of this sequence into a single value via a reducer function. + *

+ * The result's iterator() doesn't support remove(). + * @param reducer the function that receives the previous reduced element (or the first) and the current element + * and returns a new reduced element + * @return the new Ix instance + * @throws NullPointerException if reducer is null + * @since 1.0 + * @see #reduce(Func0, Func2) + */ public final Ix reduce(Func2 reducer) { - return new IxAggregate(this, reducer); + return new IxAggregate(this, nullCheck(reducer, "reducer is null")); } + /** + * Given a per-iterator() initial value, reduces the elements of this sequence into a single + * value via a reducer function. + *

+ * The result's iterator() doesn't support remove(). + * @param the reduced value type + * @param initialFactory a function called for each iterator() invocation and returns the first + * reduced value + * @param reducer the function called with the previous (or initial) reduced value and the current element + * and returns a new reduced value + * @return the new Ix instance + * @throws NullPointerException if initialFactory or reducer is null + * @since 1.0 + * @see #reduce(Func2) + */ public final Ix reduce(Func0 initialFactory, Func2 reducer) { return new IxReduce(this, initialFactory, reducer); } + /** + * Removes those elements via Iterator.remove() from this sequence that match the + * given predicate. + *

+ * The result's iterator() forwards the calls to remove() to this' Iterator. + * @param predicate the function called with the current element and returns true + * if that particular element should be removed. + * @return the new Ix instance + * @throws NullPointerException if predicate is null + * @since 1.0 + * @see #retain(Pred) + */ public final Ix remove(Pred predicate) { - return new IxRemove(this, predicate); + return new IxRemove(this, nullCheck(predicate, "predicate is null")); } + /** + * Repeats this sequence indefinitely. + *

+ * The result's iterator() doesn't support remove(). + * @return the new Ix instance + * @since 1.0 + */ public final Ix repeat() { return concat(repeatValue(this)); } + /** + * Repeats this sequence at most the given number of times. + *

A count of zero will yield an empty sequence, a count of one + * will yield a sequence with only one element and so forth. + *

+ * The result's iterator() doesn't support remove(). + * @param times the number of times to emit the value, non-negative + * @return the new Ix instance + * @throws IllegalArgumentException if count is negative + * @since 1.0 + */ public final Ix repeat(long times) { return concat(repeatValue(this, times)); } - public final Ix repeat(Pred0 predicate) { - return concat(repeatValue(this, predicate)); + /** + * Repeats this sequence if the given predicate returns true after the sequence + * completes in a round. + *

+ * The result's iterator() doesn't support remove(). + * @param stopPredicate the predicate called before any emission; returning + * false keeps repeating the value, returning true terminates the sequence + * @return the new Ix instance + * @throws NullPointerException if stopPredicate is null + * @since 1.0 + */ + public final Ix repeat(Pred0 stopPredicate) { + return concat(repeatValue(this, stopPredicate)); } - public final Ix repeat(long times, Pred0 predicate) { - return concat(repeatValue(this, times, predicate)); + /** + * Repeats this sequence if the given predicate returns true after the sequence + * completes in a round or at most the given number of times. + *

+ * A count of zero will yield an empty sequence, a count of one + * will yield a sequence with only one element and so forth. + *

+ * The result's iterator() doesn't support remove(). + * @param times the number of times to emit the value, non-negative + * @param stopPredicate the predicate called before any emission; returning + * false keeps repeating the value, returning true terminates the sequence + * @return the new Ix instance + * @throws IllegalArgumentException if count is negative + * @throws NullPointerException if stopPredicate is null + * @since 1.0 + */ + public final Ix repeat(long times, Pred0 stopPredicate) { + return concat(repeatValue(this, times, stopPredicate)); } + /** + * Caches and replays all elements of this sequence to consumers of this' iterator(). + *

+ * The result's iterator() doesn't support remove(). + * @return the new Ix instance + * @since 1.0 + */ public final Ix replay() { return new IxReplay(this); } + /** + * Caches and replays the last {@code size} elements of this sequence to consumers of this' iterator(). + *

+ * Consumption by any of the iterator() may move the source sequence forward and subsequent iterator() + * consumers may get a different set of values + *

+ * The result's iterator() doesn't support remove(). + * @param size the maximum number of elements to keep replaying to new iterator() consumers, positive + * @return the new Ix instance + * @throws IllegalArgumentException if size is non-positive + * @since 1.0 + */ public final Ix replay(int size) { - return new IxReplaySize(this, size); + return new IxReplaySize(this, positive(size, "size")); } + /** + * Caches and replays the elements of this sequence for the duration of the given transform function + * without consuming this sequence multiple times. + *

+ * The result's iterator() doesn't support remove(). + * @param the result value type + * @param transform the function receiving a view into the cache and returns an Iterable sequence whose + * elements will be emitted by this Ix. + * @return the new Ix instance + * @throws NullPointerException + * @since 1.0 + */ public final Ix replay(Func1, ? extends Iterable> transform) { - return new IxReplaySelector(this, transform); + return new IxReplaySelector(this, nullCheck(transform, "transformer is null")); } + /** + * Caches and replays the the last {@code size} elements of this sequence for the duration of the given transform function + * without consuming this sequence multiple times. + *

+ * Consumption by any of the inner Ix' iterator() may move the shared sequence forward and subsequent iterator() + * consumers may get a different set of values + *

+ * The result's iterator() doesn't support remove(). + * @param the result value type + * @param size the maximum number of elements to keep replaying to new inner Ix iterator() consumers, positive + * @param transform the function receiving a view into the cache and returns an Iterable sequence whose + * elements will be emitted by this Ix. + * @return the new Ix instance + * @throws NullPointerException + * @since 1.0 + */ public final Ix replay(int size, Func1, ? extends Iterable> transform) { - return new IxReplaySizeSelector(this, size, transform); + return new IxReplaySizeSelector(this, positive(size, "size"), nullCheck(transform, "transform is null")); } + /** + * Removes those elements via Iterator.remove() from this sequence that don't match the + * given predicate. + *

+ * The result's iterator() forwards the calls to remove() to this' Iterator. + * @param predicate the function called with the current element and returns false + * if that particular element should be removed. + * @return the new Ix instance + * @throws NullPointerException if predicate is null + * @since 1.0 + * @see #remove(Pred) + */ public final Ix retain(Pred predicate) { - return new IxRetain(this, predicate); + return new IxRetain(this, nullCheck(predicate, "predicate is null")); } + /** + * Plays this sequence in reverse. + *

+ * The reversal requires consuming the entire sequence and doesn't work with + * infinite sequences. + *

+ * The result's iterator() doesn't support remove(). + * @return the new Ix instance + * @since 1.0 + */ public final Ix reverse() { return new IxReverse(this); } + /** + * Performs a running accumulation, that is, returns intermediate elements returned by the + * scanner function. + *

+ * The result's iterator() doesn't support remove(). + * @param scanner the function that receives the previous (or first) accumulated element and the current + * element and returns a value to be emitted and to become the accumulated element + * @return the new Ix instance + * @throws NullPointerException if scanner is null + * @since 1.0 + */ public final Ix scan(Func2 scanner) { - return new IxScan(this, scanner); + return new IxScan(this, nullCheck(scanner, "scanner is null")); } + /** + * Performs a running accumulation, that is, returns intermediate elements returned by the + * scanner function, starting with a per-iterator initial value. + *

+ * The result's iterator() doesn't support remove(). + * @param the accumulated value type + * @param initialFactory function called for each iterator() and returns the initial accumulator value + * @param scanner the function that receives the previous (or first) accumulated element and the current + * element and returns a value to be emitted and to become the accumulated element + * @return the new Ix instance + * @throws NullPointerException if initialFactory or scanner is null + * @since 1.0 + */ public final Ix scan(Func0 initialFactory, Func2 scanner) { - return new IxScanSeed(this, initialFactory, scanner); + return new IxScanSeed(this, nullCheck(initialFactory, "initialFactory is null"), nullCheck(scanner, "scanner is null")); } + /** + * Determines if two sequences have the same elements in the same order and are the same length based + * on null-safe object equality. + *

+ * The result's iterator() doesn't support remove(). + * @param other the other sequence to compare with + * @return the new Ix instance + * @throws NullPointerException if other is null + * @since 1.0 + */ public final Ix sequenceEqual(Iterable other) { - return sequenceEqual(other, EqualityHelper.INSTANCE); + return sequenceEqual(nullCheck(other, "other is null"), EqualityHelper.INSTANCE); } + /** + * Determines if two sequences have the same elements in the same order and are the same length based + * on the given comparer's boolean value. + *

+ * The result's iterator() doesn't support remove(). + * @param other the other sequence to compare with + * @param comparer the predicate receiving elements from this and the other sequence and returns true if those + * elements are equal + * @return the new Ix instance + * @throws NullPointerException if other is null + * @since 1.0 + */ public final Ix sequenceEqual(Iterable other, Pred2 comparer) { - return new IxSequenceEqual(this, other, comparer); + return new IxSequenceEqual(this, nullCheck(other, "other is null"), nullCheck(comparer, "comparer is null")); } + /** + * Skips the first n elements from this sequence. + *

+ * The result's iterator() forwards the calls to remove() to this' Iterator. + * @param n the elements to skip, non-positive values won't skip any elements + * @return the new Ix instance + * @since 1.0 + * @see #take(int) + */ public final Ix skip(int n) { - if (n == 0) { + if (n <= 0) { return this; } return new IxSkip(this, n); } + /** + * Skips the last n elements from this sequence. + *

+ * The result's iterator() doesn't support remove(). + * @param n the elements to skip, non-positive values won't skip any elements + * @return the new Ix instance + * @since 1.0 + * @see #takeLast(int) + */ public final Ix skipLast(int n) { - if (n == 0) { + if (n <= 0) { return this; } return new IxSkipLast(this, n); } + /** + * Skips the first elements while the given predicate returns true; once it returns false + * all subsequent elements are emitted. + *

+ * The result's iterator() forwards the calls to remove() to this' Iterator. + * @param predicate the predicate called with the current element and returns true + * to skip that element + * @return the new Ix instance + * @throws NullPointerException if predicate is null + * @since 1.0 + * @see #takeWhile(Pred) + */ public final Ix skipWhile(Pred predicate) { - return new IxSkipWhile(this, predicate); + return new IxSkipWhile(this, nullCheck(predicate, "predicate is null")); } - @SuppressWarnings("unchecked") + /** + * Emits elements of the given array followed by the elements of this sequence. + *

+ * The result's iterator() doesn't support remove(). + * @param values the array of values to emit first + * @return the new Ix instance + * @throws NullPointerException if values is null + * @since 1.0 + */ public final Ix startWith(T... values) { - return concatArray(fromArray(values), this); + return concat(fromArray(values), this); } @SuppressWarnings("unchecked") From 01ae5f3b47ba8fc4d9c510e8c7c00bf51504194f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?D=C3=A1vid=20Karnok?= Date: Sat, 16 Jul 2016 01:22:36 +0200 Subject: [PATCH 31/66] Javadoc part 6 --- src/main/java/ix/Ix.java | 267 ++++++++++++++++++++++++++++++++++++--- 1 file changed, 246 insertions(+), 21 deletions(-) diff --git a/src/main/java/ix/Ix.java b/src/main/java/ix/Ix.java index 82c9b64..945c040 100644 --- a/src/main/java/ix/Ix.java +++ b/src/main/java/ix/Ix.java @@ -552,8 +552,7 @@ public static Ix zip(Iterable> sources } /** - * Combines the next element from each source Iterable, provided as an Iterable itself, - * via a zipper function. + * Combines the next element from each source Iterable via a zipper function. *

* If one of the source Iterables is sorter the sequence terminates eagerly. *

@@ -577,8 +576,7 @@ public static Ix zip( } /** - * Combines the next element from each source Iterable, provided as an Iterable itself, - * via a zipper function. + * Combines the next element from each source Iterable via a zipper function. *

* If one of the source Iterables is sorter the sequence terminates eagerly. *

@@ -605,8 +603,7 @@ public static Ix zip( } /** - * Combines the next element from each source Iterable, provided as an Iterable itself, - * via a zipper function. + * Combines the next element from each source Iterable via a zipper function. *

* If one of the source Iterables is sorter the sequence terminates eagerly. *

@@ -987,6 +984,8 @@ public final Ix endWith(T... values) { * @return the new Ix instance * @throws NullPointerException if other is null * @since 1.0 + * @see #union(Iterable) + * @see #intersect(Iterable) */ public final Ix except(Iterable other) { return new IxExcept(this, nullCheck(other, "other is null")); @@ -1099,6 +1098,8 @@ public final Ix hide() { * @return the new Ix instance * @throws NullPointerException if other is null * @since 1.0 + * @see #except(Iterable) + * @see #union(Iterable) */ public final Ix intersect(Iterable other) { return new IxIntersect(this, nullCheck(other, "other is null")); @@ -1585,11 +1586,11 @@ public final Ix replay(int size) { * @param transform the function receiving a view into the cache and returns an Iterable sequence whose * elements will be emitted by this Ix. * @return the new Ix instance - * @throws NullPointerException + * @throws NullPointerException if transform is null * @since 1.0 */ public final Ix replay(Func1, ? extends Iterable> transform) { - return new IxReplaySelector(this, nullCheck(transform, "transformer is null")); + return new IxReplaySelector(this, nullCheck(transform, "transform is null")); } /** @@ -1605,7 +1606,8 @@ public final Ix replay(Func1, ? extends Iterable Ix replay(int size, Func1, ? extends Iterable> transform) { @@ -1765,94 +1767,317 @@ public final Ix startWith(T... values) { return concat(fromArray(values), this); } + /** + * Sums values of this sequence as integer. + *

+ * The operation may throw a ClassCastException if any of the elements + * is not an Integer. + *

+ * An empty sequence yields an empty sum. + *

+ * The result's iterator() doesn't support remove(). + * @return the new Ix instance + * @since 1.0 + */ @SuppressWarnings("unchecked") public final Ix sumInt() { return new IxSumInt((Ix)this); } + /** + * Sums values of this sequence as long. + *

+ * The operation may throw a ClassCastException if any of the elements + * is not an Long. + *

+ * An empty sequence yields an empty sum. + *

+ * The result's iterator() doesn't support remove(). + * @return the new Ix instance + * @since 1.0 + */ @SuppressWarnings("unchecked") public final Ix sumLong() { return new IxSumLong((Ix)this); } + /** + * Emits the elements of the other sequence if this sequence is empty. + *

+ * The result's Iterator forwards calls of remove() to this' or the other's Iterator. + * @param other the other Iterable instance, not null + * @return the new Ix instance + * @throws NullPointerException if other is null + * @since 1.0 + */ public final Ix switchIfEmpty(Iterable other) { - return new IxSwitchIfEmpty(this, other); + return new IxSwitchIfEmpty(this, nullCheck(other, "other is null")); } + /** + * Emits the first n elements (or less) of this sequence. + *

+ * The result's Iterator forwards calls of remove() to this' Iterator. + * @param n the number of items to emit at most, non-negative + * @return the new Ix instance + * @throws IllegalArgumentException if n is negative + * @since 1.0 + * @see #skip(int) + */ public final Ix take(int n) { - return new IxTake(this, n); + return new IxTake(this, nonNegative(n, "n")); } + /** + * Emits the last n elements (or fewer) of this sequence. + *

+ * The result's iterator() doesn't support remove(). + * @param n the number of last elements to emit + * @return the new Ix instance + * @throws IllegalArgumentException if n is negative + * @since 1.0 + * @see #skipLast(int) + */ public final Ix takeLast(int n) { - return new IxTakeLast(this, n); + return new IxTakeLast(this, nonNegative(n, "n")); } + /** + * Take elements from this sequence while the given predicate returns true + * for the current element (checked after emission of that element). + *

+ * The result's Iterator forwards calls of remove() to this' Iterator. + * @param stopPredicate the function receiving the current element and returns + * true if no further elements should be emitted after this element. + * @return the new Ix instance + * @throws NullPointerException if stopPredicate is null + * @since 1.0 + */ public final Ix takeUntil(Pred stopPredicate) { - return new IxTakeUntil(this, stopPredicate); + return new IxTakeUntil(this, nullCheck(stopPredicate, "stopPredicate is null")); } + /** + * Take elements from this sequence until the given predicate returns true + * for the current element (checked before emission of that element). + *

+ * The result's Iterator forwards calls of remove() to this' Iterator. + * @param predicate the function receiving the current element and returns + * false if no further elements should be emitted (not even the current). + * @return the new Ix instance + * @throws NullPointerException if predicate is null + * @since 1.0 + */ public final Ix takeWhile(Pred predicate) { - return new IxTakeWhile(this, predicate); + return new IxTakeWhile(this, nullCheck(predicate, "predicate is null")); } + /** + * Collects the elements of this sequence into an Object array. + *

+ * The result's iterator() doesn't support remove(). + * @return the new Ix instance + * @since 1.0 + */ public final Ix toArray() { return collect(ToListHelper.initialFactory(), ToListHelper.collector()) .map(ToListHelper.toArray()); } + /** + * Collects the elements of this sequence into a List. + *

+ * The result's iterator() doesn't support remove(). + * @return the new Ix instance + * @since 1.0 + */ public final Ix> toList() { return collect(ToListHelper.initialFactory(), ToListHelper.collector()); } + /** + * Maps this sequence of numbers into a sequence of longs. + *

+ * The sequence may throw a ClassCastException if any of the elements + * is not a subclass of Number. + *

+ * The result's Iterator forwards calls of remove() to this' Iterator. + * @return the new Ix instance + * @since 1.0 + */ @SuppressWarnings("unchecked") public final Ix toLong() { return ((Ix)this).map(NumberToLongHelper.INSTANCE); } + /** + * Collects the elements of this sequence into a Map where the key is + * determined from each element via the keySelector function; duplicates are + * overwritten. + *

+ * The result's iterator() doesn't support remove(). + * @param the key type + * @param keySelector the function that receives the current element and returns + * a key for it to be used as the Map key. + * @return the new Ix instance + * @throws NullPointerException if keySelector is null + * @since 1.0 + */ public final Ix> toMap(Func1 keySelector) { Func1 f = IdentityHelper.instance(); return this.toMap(keySelector, f); } + /** + * Collects the elements of this sequence into a Map where the key is + * determined from each element via the keySelector function and + * the value is derived from the same element via the valueSelector function; duplicates are + * overwritten. + *

+ * The result's iterator() doesn't support remove(). + * @param the key type + * @param the value type + * @param keySelector the function that receives the current element and returns + * a key for it to be used as the Map key. + * @param valueSelector the function that receives the current element and returns + * a value for it to be used as the Map value + * @return the new Ix instance + * @throws NullPointerException if keySelector or valueSelector is null + * @since 1.0 + */ public final Ix> toMap(Func1 keySelector, Func1 valueSelector) { - return new IxToMap(this, keySelector, valueSelector); + return new IxToMap(this, nullCheck(keySelector, "keySelector is null"), nullCheck(valueSelector, "valueSelector is null")); } + /** + * Collects the elements of this sequence into a multi-Map where the key is + * determined from each element via the keySelector function. + *

+ * The result's iterator() doesn't support remove(). + * @param the key type + * @param keySelector the function that receives the current element and returns + * a key for it to be used as the Map key. + * @return the new Ix instance + * @throws NullPointerException if keySelector is null + * @since 1.0 + */ public final Ix>> toMultimap(Func1 keySelector) { Func1 f = IdentityHelper.instance(); return this.toMultimap(keySelector, f); } + /** + * Collects the elements of this sequence into a multi-Map where the key is + * determined from each element via the keySelector function and + * the value is derived from the same element via the valueSelector function. + *

+ * The result's iterator() doesn't support remove(). + * @param the key type + * @param the value type + * @param keySelector the function that receives the current element and returns + * a key for it to be used as the Map key. + * @param valueSelector the function that receives the current element and returns + * a value for it to be used as the Map value + * @return the new Ix instance + * @throws NullPointerException if keySelector or valueSelector is null + * @since 1.0 + */ public final Ix>> toMultimap(Func1 keySelector, Func1 valueSelector) { return new IxToMultimap(this, keySelector, valueSelector); } + /** + * Collects the elements of this sequence into a Set. + *

+ * The result's iterator() doesn't support remove(). + * @return the new Ix instance + * @since 1.0 + */ public final Ix> toSet() { return new IxToSet(this); } + /** + * Allows working with the Iterator of this sequence and emit elements in + * a more flexible way + *

+ * The result's iterator() doesn't support remove(). + * @param the result value type + * @param transformer the functional interface whose moveNext is called with the + * current Iterator and should signal a value to be emitted for it. + * @return the new Ix instance + * @throws NullPointerException if transformer is null + */ public final Ix transform(IxTransform transformer) { - return new IxTransformer(this, transformer); + return new IxTransformer(this, nullCheck(transformer, "transformer is null")); } + /** + * Emits a distinct set of values from both this and the other sequence. + *

+ * The result's iterator() doesn't support remove(). + * @param other the other Iterable sequence, not null + * @return the new Ix instance + * @throws NullPointerException if other is null + * @since 1.0 + * @see #except(Iterable) + * @see #intersect(Iterable) + */ public final Ix union(Iterable other) { - return new IxUnion(this, other); + return new IxUnion(this, nullCheck(other, "other is null")); } + /** + * Emits inner Ix Iterables of non-overapping sequences mapped from this sequence + * with the given maximum size each. + * + *

+ * The result's and the inner Ix' iterator() don't support remove(). + * @param size the maximum size of the inner windows, positive + * @return the new Ix instance + * @throws IllegalArgumentException if size is non-positive + * @since 1.0 + * @see #window(int, int) + */ public final Ix> window(int size) { - return new IxWindow(this, size); + return new IxWindow(this, positive(size, "size")); } + /** + * Emits inner Ix Iterables of potentially overlapping sequences mapped from this + * sequence with the given maximum size each and started each {@code skip} source elements. + * @param size the maximum size of the inner windows, positive + * @param skip after how many elements to start a new window (repeatedly), positive + * @return the new Ix Iinstance + * @throws IllegalArgumentException if size or skip is non-positive + * @since 1.0 + * @see #window(int) + */ public final Ix> window(int size, int skip) { if (size == skip) { return window(size); } if (size < skip) { - return new IxWindowSkip(this, size, skip); + return new IxWindowSkip(this, positive(size, "size"), positive(skip, "skip")); } - return new IxWindowOverlap(this, size, skip); + return new IxWindowOverlap(this, positive(size, "size"), positive(skip, "skip")); } + /** + * Combines the next element from this and the other source Iterable via a zipper function. + *

+ * If one of the source Iterables is sorter the sequence terminates eagerly. + *

+ * The result's iterator() doesn't support remove(). + * + * @param the other source's element type + * @param the result value type + * @param other the the other source Iterable + * @param zipper the function that takesone from each source, not null + * @return the new Ix instance + * @throws NullPointerException if other or zipper is null + * @since 1.0 + */ public final Ix zipWith(Iterable other, Func2 zipper) { return zip(this, other, zipper); } @@ -1918,7 +2143,7 @@ public final void foreach(Action1 action) { * return true to continue the loop or false to quit the loop. * @throws NullPointerException if action is null * @since 1.0 - * @see #foreach(Pred) + * @see #foreach(Action1) */ public final void foreachWhile(Pred predicate) { for (T t : this) { From c9efbb5690321350cb4e85da6ca0c4ab1b48cd75 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?D=C3=A1vid=20Karnok?= Date: Sat, 16 Jul 2016 01:23:18 +0200 Subject: [PATCH 32/66] Update readme to reference 1.0.0-RC1 --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index b282b82..f284ab9 100644 --- a/README.md +++ b/README.md @@ -18,7 +18,7 @@ and interactive dataflows.** ``` dependencies { - compile "com.github.akarnokd:ixjava:1.0.0" + compile "com.github.akarnokd:ixjava:1.0.0-RC1" } ``` @@ -26,7 +26,7 @@ dependencies { ``` - + ``` From 4501e96df70c0ebe4621e51d54fcf77d9cdc53bd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?D=C3=A1vid=20Karnok?= Date: Sat, 16 Jul 2016 01:24:27 +0200 Subject: [PATCH 33/66] Reference RxJava 1.1.7 --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 64ac096..0454738 100644 --- a/build.gradle +++ b/build.gradle @@ -44,7 +44,7 @@ apply plugin: 'osgi' dependencies { signature 'org.codehaus.mojo.signature:java16:1.1@signature' - compile "io.reactivex:rxjava:1.1.6" + compile "io.reactivex:rxjava:1.1.7" testCompile group: 'junit', name: 'junit', version: '4.12' } From 2053c95aea7fc22f10964f4e2616e550fb518833 Mon Sep 17 00:00:00 2001 From: akarnokd Date: Fri, 22 Jul 2016 11:34:22 +0200 Subject: [PATCH 34/66] Rename in-sequence toX to collectToX, make toX be terminal consumers --- src/main/java/ix/Ix.java | 349 ++++++++++++++++++++--------- src/test/java/ix/FilterTest.java | 2 +- src/test/java/ix/GroupByTest.java | 6 +- src/test/java/ix/IxTestHelper.java | 2 +- src/test/java/ix/LeavingTest.java | 4 +- src/test/java/ix/MapTest.java | 2 +- src/test/java/ix/TakeTest.java | 2 +- src/test/java/ix/ToArrayTest.java | 2 +- src/test/java/ix/ToMapTest.java | 12 +- src/test/java/ix/ToSetTest.java | 6 +- src/test/java/ix/ToXTest.java | 138 ++++++++++++ src/test/java/ix/WindowTest.java | 36 +-- 12 files changed, 415 insertions(+), 146 deletions(-) create mode 100644 src/test/java/ix/ToXTest.java diff --git a/src/main/java/ix/Ix.java b/src/main/java/ix/Ix.java index 945c040..3d8cb77 100644 --- a/src/main/java/ix/Ix.java +++ b/src/main/java/ix/Ix.java @@ -743,6 +743,21 @@ public final Ix> buffer(int size, int skip) { return new IxBufferOverlap(this, positive(size, "size"), positive(skip, "skip")); } + /** + * Cast the elements to the specified class. + *

+ * Note that this is a forced cast on this Ix instance and if + * not compatible, a ClassCastException might be thrown downstream. + * @param the target type + * @param clazz the type token to capture the target type + * @return the new Ix instance + * @since 1.0 + */ + @SuppressWarnings({ "rawtypes", "unchecked" }) + public final Ix cast(Class clazz) { + return (Ix)this; + } + /** * Collect the elements into a collection via collector action and emit that collection * as a single item. @@ -758,6 +773,116 @@ public final Ix> buffer(int size, int skip) { public final Ix collect(Func0 initialFactory, Action2 collector) { return new IxCollect(this, nullCheck(initialFactory, "initalFactory is null"), nullCheck(collector, "collector")); } + + /** + * Collects the elements of this sequence into an Object array. + *

+ * The result's iterator() doesn't support remove(). + * @return the new Ix instance + * @since 1.0 + */ + public final Ix collectToArray() { + return collect(ToListHelper.initialFactory(), ToListHelper.collector()) + .map(ToListHelper.toArray()); + } + + /** + * Collects the elements of this sequence into a List. + *

+ * The result's iterator() doesn't support remove(). + * @return the new Ix instance + * @since 1.0 + */ + public final Ix> collectToList() { + return collect(ToListHelper.initialFactory(), ToListHelper.collector()); + } + + /** + * Collects the elements of this sequence into a Map where the key is + * determined from each element via the keySelector function; duplicates are + * overwritten. + *

+ * The result's iterator() doesn't support remove(). + * @param the key type + * @param keySelector the function that receives the current element and returns + * a key for it to be used as the Map key. + * @return the new Ix instance + * @throws NullPointerException if keySelector is null + * @since 1.0 + */ + public final Ix> collectToMap(Func1 keySelector) { + Func1 f = IdentityHelper.instance(); + return this.collectToMap(keySelector, f); + } + + /** + * Collects the elements of this sequence into a Map where the key is + * determined from each element via the keySelector function and + * the value is derived from the same element via the valueSelector function; duplicates are + * overwritten. + *

+ * The result's iterator() doesn't support remove(). + * @param the key type + * @param the value type + * @param keySelector the function that receives the current element and returns + * a key for it to be used as the Map key. + * @param valueSelector the function that receives the current element and returns + * a value for it to be used as the Map value + * @return the new Ix instance + * @throws NullPointerException if keySelector or valueSelector is null + * @since 1.0 + */ + public final Ix> collectToMap(Func1 keySelector, Func1 valueSelector) { + return new IxToMap(this, nullCheck(keySelector, "keySelector is null"), nullCheck(valueSelector, "valueSelector is null")); + } + + /** + * Collects the elements of this sequence into a multi-Map where the key is + * determined from each element via the keySelector function. + *

+ * The result's iterator() doesn't support remove(). + * @param the key type + * @param keySelector the function that receives the current element and returns + * a key for it to be used as the Map key. + * @return the new Ix instance + * @throws NullPointerException if keySelector is null + * @since 1.0 + */ + public final Ix>> collectToMultimap(Func1 keySelector) { + Func1 f = IdentityHelper.instance(); + return this.collectToMultimap(keySelector, f); + } + + /** + * Collects the elements of this sequence into a multi-Map where the key is + * determined from each element via the keySelector function and + * the value is derived from the same element via the valueSelector function. + *

+ * The result's iterator() doesn't support remove(). + * @param the key type + * @param the value type + * @param keySelector the function that receives the current element and returns + * a key for it to be used as the Map key. + * @param valueSelector the function that receives the current element and returns + * a value for it to be used as the Map value + * @return the new Ix instance + * @throws NullPointerException if keySelector or valueSelector is null + * @since 1.0 + */ + public final Ix>> collectToMultimap(Func1 keySelector, Func1 valueSelector) { + return new IxToMultimap(this, keySelector, valueSelector); + } + + /** + * Collects the elements of this sequence into a Set. + *

+ * The result's iterator() doesn't support remove(). + * @return the new Ix instance + * @since 1.0 + */ + public final Ix> collectToSet() { + return new IxToSet(this); + } /** * When the iterator() of the returned Ix is called, it calls the transformer function @@ -1872,28 +1997,6 @@ public final Ix takeWhile(Pred predicate) { return new IxTakeWhile(this, nullCheck(predicate, "predicate is null")); } - /** - * Collects the elements of this sequence into an Object array. - *

- * The result's iterator() doesn't support remove(). - * @return the new Ix instance - * @since 1.0 - */ - public final Ix toArray() { - return collect(ToListHelper.initialFactory(), ToListHelper.collector()) - .map(ToListHelper.toArray()); - } - - /** - * Collects the elements of this sequence into a List. - *

- * The result's iterator() doesn't support remove(). - * @return the new Ix instance - * @since 1.0 - */ - public final Ix> toList() { - return collect(ToListHelper.initialFactory(), ToListHelper.collector()); - } /** * Maps this sequence of numbers into a sequence of longs. @@ -1909,93 +2012,6 @@ public final Ix> toList() { public final Ix toLong() { return ((Ix)this).map(NumberToLongHelper.INSTANCE); } - - /** - * Collects the elements of this sequence into a Map where the key is - * determined from each element via the keySelector function; duplicates are - * overwritten. - *

- * The result's iterator() doesn't support remove(). - * @param the key type - * @param keySelector the function that receives the current element and returns - * a key for it to be used as the Map key. - * @return the new Ix instance - * @throws NullPointerException if keySelector is null - * @since 1.0 - */ - public final Ix> toMap(Func1 keySelector) { - Func1 f = IdentityHelper.instance(); - return this.toMap(keySelector, f); - } - - /** - * Collects the elements of this sequence into a Map where the key is - * determined from each element via the keySelector function and - * the value is derived from the same element via the valueSelector function; duplicates are - * overwritten. - *

- * The result's iterator() doesn't support remove(). - * @param the key type - * @param the value type - * @param keySelector the function that receives the current element and returns - * a key for it to be used as the Map key. - * @param valueSelector the function that receives the current element and returns - * a value for it to be used as the Map value - * @return the new Ix instance - * @throws NullPointerException if keySelector or valueSelector is null - * @since 1.0 - */ - public final Ix> toMap(Func1 keySelector, Func1 valueSelector) { - return new IxToMap(this, nullCheck(keySelector, "keySelector is null"), nullCheck(valueSelector, "valueSelector is null")); - } - - /** - * Collects the elements of this sequence into a multi-Map where the key is - * determined from each element via the keySelector function. - *

- * The result's iterator() doesn't support remove(). - * @param the key type - * @param keySelector the function that receives the current element and returns - * a key for it to be used as the Map key. - * @return the new Ix instance - * @throws NullPointerException if keySelector is null - * @since 1.0 - */ - public final Ix>> toMultimap(Func1 keySelector) { - Func1 f = IdentityHelper.instance(); - return this.toMultimap(keySelector, f); - } - - /** - * Collects the elements of this sequence into a multi-Map where the key is - * determined from each element via the keySelector function and - * the value is derived from the same element via the valueSelector function. - *

- * The result's iterator() doesn't support remove(). - * @param the key type - * @param the value type - * @param keySelector the function that receives the current element and returns - * a key for it to be used as the Map key. - * @param valueSelector the function that receives the current element and returns - * a value for it to be used as the Map value - * @return the new Ix instance - * @throws NullPointerException if keySelector or valueSelector is null - * @since 1.0 - */ - public final Ix>> toMultimap(Func1 keySelector, Func1 valueSelector) { - return new IxToMultimap(this, keySelector, valueSelector); - } - - /** - * Collects the elements of this sequence into a Set. - *

- * The result's iterator() doesn't support remove(). - * @return the new Ix instance - * @since 1.0 - */ - public final Ix> toSet() { - return new IxToSet(this); - } /** * Allows working with the Iterator of this sequence and emit elements in @@ -2512,6 +2528,121 @@ public final void subscribe(Subscriber subscriber) { subscriber.onCompleted(); } + /** + * Collects the elements of this sequence into an Object array. + *

+ * @return the new Object array instance + * @since 1.0 + */ + public final Object[] toArray() { + return toList().toArray(); + } + + /** + * Collects the elements of this sequence into a generic array provided. + *

+ * @param the output array type + * @param array the target array to fill in or use as a template if not long enough + * @return the new generic array instance + * @since 1.0 + */ + public final U[] toArray(U[] array) { + return toList().toArray(array); + } + + /** + * Collects the elements of this sequence into a List. + *

+ * @return the List instance + * @since 1.0 + */ + public final List toList() { + List list = new ArrayList(); + return into(list); + } + + + /** + * Collects the elements of this sequence into a Map where the key is + * determined from each element via the keySelector function; duplicates are + * overwritten. + *

+ * @param the key type + * @param keySelector the function that receives the current element and returns + * a key for it to be used as the Map key. + * @return the new Map instance + * @throws NullPointerException if keySelector is null + * @since 1.0 + */ + public final Map toMap(Func1 keySelector) { + return collectToMap(keySelector).first(); + } + + /** + * Collects the elements of this sequence into a Map where the key is + * determined from each element via the keySelector function and + * the value is derived from the same element via the valueSelector function; duplicates are + * overwritten. + *

+ * @param the key type + * @param the value type + * @param keySelector the function that receives the current element and returns + * a key for it to be used as the Map key. + * @param valueSelector the function that receives the current element and returns + * a value for it to be used as the Map value + * @return the new Map instance + * @throws NullPointerException if keySelector or valueSelector is null + * @since 1.0 + */ + public final Map toMap(Func1 keySelector, Func1 valueSelector) { + return collectToMap(keySelector, valueSelector).first(); + } + + /** + * Collects the elements of this sequence into a multi-Map where the key is + * determined from each element via the keySelector function. + *

+ * @param the key type + * @param keySelector the function that receives the current element and returns + * a key for it to be used as the Map key. + * @return the new Map instance + * @throws NullPointerException if keySelector is null + * @since 1.0 + */ + public final Map> toMultimap(Func1 keySelector) { + return collectToMultimap(keySelector).first(); + } + + /** + * Collects the elements of this sequence into a multi-Map where the key is + * determined from each element via the keySelector function and + * the value is derived from the same element via the valueSelector function. + *

+ * @param the key type + * @param the value type + * @param keySelector the function that receives the current element and returns + * a key for it to be used as the Map key. + * @param valueSelector the function that receives the current element and returns + * a value for it to be used as the Map value + * @return the new Map instance + * @throws NullPointerException if keySelector or valueSelector is null + * @since 1.0 + */ + public final Map> toMultimap(Func1 keySelector, Func1 valueSelector) { + return collectToMultimap(keySelector, valueSelector).first(); + } + + /** + * Collects the elements of this sequence into a Set. + *

+ * @return the new Ix instance + * @since 1.0 + */ + public final Set toSet() { + Set list = new HashSet(); + return into(list); + } + // -------------------------------------------------------------------------------------------- // Helper methods // -------------------------------------------------------------------------------------------- diff --git a/src/test/java/ix/FilterTest.java b/src/test/java/ix/FilterTest.java index fdfd2af..80c39f6 100644 --- a/src/test/java/ix/FilterTest.java +++ b/src/test/java/ix/FilterTest.java @@ -60,7 +60,7 @@ public boolean test(Integer v) { @Test public void removeComposes() { - List list = Ix.range(1, 10).toList().first(); + List list = Ix.range(1, 10).collectToList().first(); Ix.from(list).filter(new Pred() { @Override diff --git a/src/test/java/ix/GroupByTest.java b/src/test/java/ix/GroupByTest.java index c646747..5e05857 100644 --- a/src/test/java/ix/GroupByTest.java +++ b/src/test/java/ix/GroupByTest.java @@ -230,7 +230,7 @@ public Integer call(Integer v) { } }); - List> list = source.toList().first(); + List> list = source.collectToList().first(); IxTestHelper.assertValues(Ix.concat(list), 1, 2, 3, 4, 5); } @@ -249,7 +249,7 @@ public Integer call(Integer v) { } }); - List> list = source.toList().first(); + List> list = source.collectToList().first(); IxTestHelper.assertValues(Ix.concat(list), null, null, null, null, null); } @@ -268,7 +268,7 @@ public Integer call(Integer v) { } }); - List> list = source.toList().first(); + List> list = source.collectToList().first(); Assert.assertEquals("GroupedIterable[key=1, queue=5]", list.get(0).toString()); diff --git a/src/test/java/ix/IxTestHelper.java b/src/test/java/ix/IxTestHelper.java index 1cd12d5..202c478 100644 --- a/src/test/java/ix/IxTestHelper.java +++ b/src/test/java/ix/IxTestHelper.java @@ -97,6 +97,6 @@ public static void assertNoRemove(Iterable source) { } public static List range(int start, int count) { - return Ix.range(start, count).toList().first(); + return Ix.range(start, count).collectToList().first(); } } diff --git a/src/test/java/ix/LeavingTest.java b/src/test/java/ix/LeavingTest.java index 6d5ec3f..735af6c 100644 --- a/src/test/java/ix/LeavingTest.java +++ b/src/test/java/ix/LeavingTest.java @@ -386,7 +386,7 @@ public void onNext(Integer t) { @Test public void retainAll() { - List list = Ix.range(1, 10).toList().first(); + List list = Ix.range(1, 10).collectToList().first(); Ix.from(list).retainAll(new Pred() { @Override @@ -400,7 +400,7 @@ public boolean test(Integer v) { @Test public void removeAll() { - List list = Ix.range(1, 10).toList().first(); + List list = Ix.range(1, 10).collectToList().first(); Ix.from(list).removeAll(new Pred() { @Override diff --git a/src/test/java/ix/MapTest.java b/src/test/java/ix/MapTest.java index d3c5f1e..29c67f9 100644 --- a/src/test/java/ix/MapTest.java +++ b/src/test/java/ix/MapTest.java @@ -38,7 +38,7 @@ public Integer call(Integer v) { @Test public void removeComposes() { - List list = Ix.range(1, 10).toList().first(); + List list = Ix.range(1, 10).collectToList().first(); Ix.from(list).map(new Func1() { @Override diff --git a/src/test/java/ix/TakeTest.java b/src/test/java/ix/TakeTest.java index cdf769a..73cd0b2 100644 --- a/src/test/java/ix/TakeTest.java +++ b/src/test/java/ix/TakeTest.java @@ -66,7 +66,7 @@ public void empty() { @Test public void removeComposes() { - List list = Ix.range(1, 10).toList().first(); + List list = Ix.range(1, 10).collectToList().first(); Ix.from(list).take(5).removeAll(); diff --git a/src/test/java/ix/ToArrayTest.java b/src/test/java/ix/ToArrayTest.java index 9f5f681..7737f20 100644 --- a/src/test/java/ix/ToArrayTest.java +++ b/src/test/java/ix/ToArrayTest.java @@ -22,7 +22,7 @@ public class ToArrayTest { @Test public void normal() { - Ix source = Ix.range(1, 10).toArray(); + Ix source = Ix.range(1, 10).collectToArray(); IxTestHelper.assertValues(source, new Object[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }); } diff --git a/src/test/java/ix/ToMapTest.java b/src/test/java/ix/ToMapTest.java index e4b39bb..8c68fbc 100644 --- a/src/test/java/ix/ToMapTest.java +++ b/src/test/java/ix/ToMapTest.java @@ -27,7 +27,7 @@ public class ToMapTest { @SuppressWarnings("unchecked") @Test public void normal() { - Ix> source = Ix.range(1, 5).toMap(new Func1() { + Ix> source = Ix.range(1, 5).collectToMap(new Func1() { @Override public Integer call(Integer v) { return v % 3; @@ -45,7 +45,7 @@ public Integer call(Integer v) { @SuppressWarnings("unchecked") @Test public void normalValueSelector() { - Ix> source = Ix.range(1, 5).toMap(new Func1() { + Ix> source = Ix.range(1, 5).collectToMap(new Func1() { @Override public Integer call(Integer v) { return v % 3; @@ -67,7 +67,7 @@ public Integer call(Integer v) { @SuppressWarnings("unchecked") @Test public void empty() { - Ix> source = Ix.empty().toMap(new Func1() { + Ix> source = Ix.empty().collectToMap(new Func1() { @Override public Integer call(Integer v) { return v % 3; @@ -82,7 +82,7 @@ public Integer call(Integer v) { @SuppressWarnings("unchecked") @Test public void multimap() { - Ix>> source = Ix.range(1, 5).toMultimap(new Func1() { + Ix>> source = Ix.range(1, 5).collectToMultimap(new Func1() { @Override public Integer call(Integer v) { return v % 3; @@ -100,7 +100,7 @@ public Integer call(Integer v) { @SuppressWarnings("unchecked") @Test public void multimapValueSelector() { - Ix>> source = Ix.range(1, 5).toMultimap(new Func1() { + Ix>> source = Ix.range(1, 5).collectToMultimap(new Func1() { @Override public Integer call(Integer v) { return v % 3; @@ -122,7 +122,7 @@ public Integer call(Integer v) { @SuppressWarnings("unchecked") @Test public void multimapEmpty() { - Ix>> source = Ix.empty().toMultimap(new Func1() { + Ix>> source = Ix.empty().collectToMultimap(new Func1() { @Override public Integer call(Integer v) { return v % 3; diff --git a/src/test/java/ix/ToSetTest.java b/src/test/java/ix/ToSetTest.java index 20ad441..41ae7f5 100644 --- a/src/test/java/ix/ToSetTest.java +++ b/src/test/java/ix/ToSetTest.java @@ -25,7 +25,7 @@ public class ToSetTest { @SuppressWarnings("unchecked") @Test public void normal() { - Ix> source = Ix.range(1, 5).toSet(); + Ix> source = Ix.range(1, 5).collectToSet(); IxTestHelper.assertValues(source, new HashSet(Arrays.asList(1, 2, 3, 4, 5))); @@ -35,7 +35,7 @@ public void normal() { @SuppressWarnings("unchecked") @Test public void empty() { - Ix> source = Ix.empty().toSet(); + Ix> source = Ix.empty().collectToSet(); IxTestHelper.assertValues(source, new HashSet()); @@ -45,7 +45,7 @@ public void empty() { @SuppressWarnings("unchecked") @Test public void duplicates() { - Ix> source = Ix.fromArray(1, 2, 2, 3, 2, 4, 5, 1, 5).toSet(); + Ix> source = Ix.fromArray(1, 2, 2, 3, 2, 4, 5, 1, 5).collectToSet(); IxTestHelper.assertValues(source, new HashSet(Arrays.asList(1, 2, 3, 4, 5))); diff --git a/src/test/java/ix/ToXTest.java b/src/test/java/ix/ToXTest.java new file mode 100644 index 0000000..a31d7d5 --- /dev/null +++ b/src/test/java/ix/ToXTest.java @@ -0,0 +1,138 @@ +/* + * Copyright 2011-2016 David Karnok + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ix; + +import java.util.*; + +import org.junit.*; + +import rx.functions.Func1; + +public class ToXTest { + + @Test + public void cast() { + Ix source = Ix.just(1).cast(Object.class); + + IxTestHelper.assertValues(source, 1); + + IxTestHelper.assertNoRemove(source); + } + + @Test(expected = ClassCastException.class) + public void castInvalid() { + Ix source = Ix.just(1).cast(String.class); + + String s = source.first(); + + Assert.assertEquals("1", s); + } + + @Test + public void toArray() { + + Assert.assertArrayEquals(new Object[] {1, 2, 3, 4, 5}, Ix.range(1, 5).toArray()); + + } + + @Test + public void toArrayTemplate() { + + Assert.assertArrayEquals(new Integer[] {1, 2, 3, 4, 5}, Ix.range(1, 5).toArray(new Integer[5])); + + } + + @Test + public void toList() { + Assert.assertEquals(Arrays.asList(1, 2, 3, 4, 5), Ix.range(1, 5).toList()); + + } + + @Test + public void toSet() { + Assert.assertEquals(new HashSet(Arrays.asList(1, 2, 3, 4, 5)), Ix.range(1, 5).toSet()); + + } + + @Test + public void toMap() { + Map map = Ix.range(1, 5).toMap(IdentityHelper.instance()); + + Map expected = new HashMap(); + expected.put(1, 1); + expected.put(2, 2); + expected.put(3, 3); + expected.put(4, 4); + expected.put(5, 5); + + Assert.assertEquals(expected, map); + } + + + @Test + public void toMapCustomValues() { + Map map = Ix.range(1, 5).toMap(IdentityHelper.instance(), new Func1() { + @Override + public Integer call(Integer v) { + return v * v; + } + }); + + Map expected = new HashMap(); + expected.put(1, 1); + expected.put(2, 4); + expected.put(3, 9); + expected.put(4, 16); + expected.put(5, 25); + + Assert.assertEquals(expected, map); + } + + @Test + public void toMultimap() { + Map> map = Ix.range(1, 5).toMultimap(IdentityHelper.instance()); + + Map> expected = new HashMap>(); + expected.put(1, Collections.singletonList(1)); + expected.put(2, Collections.singletonList(2)); + expected.put(3, Collections.singletonList(3)); + expected.put(4, Collections.singletonList(4)); + expected.put(5, Collections.singletonList(5)); + + Assert.assertEquals(expected, map); + } + + + @Test + public void toMultimapCustomValues() { + Map> map = Ix.range(1, 5).toMultimap(IdentityHelper.instance(), new Func1() { + @Override + public Integer call(Integer v) { + return v * v; + } + }); + + Map> expected = new HashMap>(); + expected.put(1, Collections.singletonList(1)); + expected.put(2, Collections.singletonList(4)); + expected.put(3, Collections.singletonList(9)); + expected.put(4, Collections.singletonList(16)); + expected.put(5, Collections.singletonList(25)); + + Assert.assertEquals(expected, map); + } +} diff --git a/src/test/java/ix/WindowTest.java b/src/test/java/ix/WindowTest.java index d9974ea..00c6c28 100644 --- a/src/test/java/ix/WindowTest.java +++ b/src/test/java/ix/WindowTest.java @@ -26,7 +26,7 @@ public class WindowTest { public void normal() { Ix> source = Ix.range(1, 5).window(2); - List> list = source.toList().first(); + List> list = source.collectToList().first(); Assert.assertEquals(3, list.size()); IxTestHelper.assertValues(list.get(0), 1, 2); @@ -38,7 +38,7 @@ public void normal() { public void normalSizeSkipSame() { Ix> source = Ix.range(1, 5).window(2, 2); - List> list = source.toList().first(); + List> list = source.collectToList().first(); Assert.assertEquals(3, list.size()); IxTestHelper.assertValues(list.get(0), 1, 2); @@ -50,7 +50,7 @@ public void normalSizeSkipSame() { public void normalOne() { Ix> source = Ix.range(1, 5).window(1); - List> list = source.toList().first(); + List> list = source.collectToList().first(); Assert.assertEquals(5, list.size()); IxTestHelper.assertValues(list.get(0), 1); @@ -64,7 +64,7 @@ public void normalOne() { public void normalAll() { Ix> source = Ix.range(1, 5).window(5); - List> list = source.toList().first(); + List> list = source.collectToList().first(); Assert.assertEquals(1, list.size()); IxTestHelper.assertValues(list.get(0), 1, 2, 3, 4, 5); @@ -74,7 +74,7 @@ public void normalAll() { public void normalMore() { Ix> source = Ix.range(1, 5).window(10); - List> list = source.toList().first(); + List> list = source.collectToList().first(); Assert.assertEquals(1, list.size()); IxTestHelper.assertValues(list.get(0), 1, 2, 3, 4, 5); @@ -108,7 +108,7 @@ public void innerMovesParent() { public void normalSkip() { Ix> source = Ix.range(1, 5).window(2, 3); - List> list = source.toList().first(); + List> list = source.collectToList().first(); Assert.assertEquals(2, list.size()); IxTestHelper.assertValues(list.get(0), 1, 2); @@ -119,7 +119,7 @@ public void normalSkip() { public void normalSkip2() { Ix> source = Ix.range(1, 5).window(1, 2); - List> list = source.toList().first(); + List> list = source.collectToList().first(); Assert.assertEquals(3, list.size()); IxTestHelper.assertValues(list.get(0), 1); @@ -131,7 +131,7 @@ public void normalSkip2() { public void normalSkip3() { Ix> source = Ix.range(1, 5).window(1, 6); - List> list = source.toList().first(); + List> list = source.collectToList().first(); Assert.assertEquals(1, list.size()); IxTestHelper.assertValues(list.get(0), 1); @@ -141,7 +141,7 @@ public void normalSkip3() { public void normalAllSkip() { Ix> source = Ix.range(1, 5).window(5, 10); - List> list = source.toList().first(); + List> list = source.collectToList().first(); Assert.assertEquals(1, list.size()); IxTestHelper.assertValues(list.get(0), 1, 2, 3, 4, 5); @@ -151,7 +151,7 @@ public void normalAllSkip() { public void normalMoreSkip() { Ix> source = Ix.range(1, 5).window(10, 15); - List> list = source.toList().first(); + List> list = source.collectToList().first(); Assert.assertEquals(1, list.size()); IxTestHelper.assertValues(list.get(0), 1, 2, 3, 4, 5); @@ -161,7 +161,7 @@ public void normalMoreSkip() { public void justSkip() { Ix> source = Ix.just(1).window(2, 3); - List> list = source.toList().first(); + List> list = source.collectToList().first(); Assert.assertEquals(1, list.size()); IxTestHelper.assertValues(list.get(0), 1); @@ -171,7 +171,7 @@ public void justSkip() { public void emptySkip() { Ix> source = Ix.empty().window(2, 3); - List> list = source.toList().first(); + List> list = source.collectToList().first(); Assert.assertEquals(0, list.size()); } @@ -211,7 +211,7 @@ public void skipInnerMovesParent() { public void normalOverlap() { Ix> source = Ix.range(1, 5).window(2, 1); - List> list = source.toList().first(); + List> list = source.collectToList().first(); Assert.assertEquals(5, list.size()); IxTestHelper.assertValues(list.get(0), 1, 2); @@ -225,7 +225,7 @@ public void normalOverlap() { public void normalOverlap2() { Ix> source = Ix.range(1, 5).window(3, 1); - List> list = source.toList().first(); + List> list = source.collectToList().first(); Assert.assertEquals(5, list.size()); IxTestHelper.assertValues(list.get(0), 1, 2, 3); @@ -239,7 +239,7 @@ public void normalOverlap2() { public void normalOverlap3() { Ix> source = Ix.range(1, 5).window(3, 2); - List> list = source.toList().first(); + List> list = source.collectToList().first(); Assert.assertEquals(3, list.size()); IxTestHelper.assertValues(list.get(0), 1, 2, 3); @@ -251,7 +251,7 @@ public void normalOverlap3() { public void nullExact() { Ix> source = Ix.fromArray(null, null, null, null, null).window(2); - List> list = source.toList().first(); + List> list = source.collectToList().first(); Assert.assertEquals(3, list.size()); IxTestHelper.assertValues(list.get(0), null, null); @@ -277,7 +277,7 @@ public void nullExact2() { public void nullSkip() { Ix> source = Ix.fromArray(null, null, null, null, null).window(2, 3); - List> list = source.toList().first(); + List> list = source.collectToList().first(); Assert.assertEquals(2, list.size()); IxTestHelper.assertValues(list.get(0), null, null); @@ -288,7 +288,7 @@ public void nullSkip() { public void nullOverlap() { Ix> source = Ix.fromArray(null, null, null, null, null).window(2, 1); - List> list = source.toList().first(); + List> list = source.collectToList().first(); Assert.assertEquals(5, list.size()); IxTestHelper.assertValues(list.get(0), null, null); From 57d3ba0c7025f97d073201567c1900fc4895d80f Mon Sep 17 00:00:00 2001 From: Santiago Castro Date: Mon, 25 Jul 2016 03:15:49 -0300 Subject: [PATCH 35/66] Highlight code in README (#4) --- README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index f284ab9..8dbf770 100644 --- a/README.md +++ b/README.md @@ -16,17 +16,17 @@ and interactive dataflows.** **gradle** -``` +```groovy dependencies { - compile "com.github.akarnokd:ixjava:1.0.0-RC1" + compile 'com.github.akarnokd:ixjava:1.0.0-RC1' } ``` **ivy** -``` +```xml - + ``` From 9ee1da67dd75041cf339f34d9cd9a549800df8ae Mon Sep 17 00:00:00 2001 From: Santiago Castro Date: Mon, 25 Jul 2016 03:16:58 -0300 Subject: [PATCH 36/66] Fix typos in Ix javadocs (#5) * Fix typos in Ix javadocs * Fix typo: Interable -> Iterable --- src/main/java/ix/Ix.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/java/ix/Ix.java b/src/main/java/ix/Ix.java index 3d8cb77..718a11a 100644 --- a/src/main/java/ix/Ix.java +++ b/src/main/java/ix/Ix.java @@ -203,7 +203,7 @@ public static Ix empty() { } /** - * Wraps the given Interable source into an Ix instance (if + * Wraps the given Iterable source into an Ix instance (if * not already an Ix subclass). *

* The result's iterator() forwards the remove() calls to the source's @@ -2269,7 +2269,7 @@ public final void print(CharSequence separator, int charsPerLine) { System.out.print(separator); len += separator.length(); if (len > charsPerLine) { - System.out.println();; + System.out.println(); System.out.print(s); len = s.length(); } else { @@ -2394,9 +2394,9 @@ public final T single() { /** - * Returns the single element of this sequence, the defaltValue + * Returns the single element of this sequence, defalutValue * if this sequence is empty or IndexOutOfBoundsException if this sequence has more - * than on element + * than one element * @param defaultValue the value to return if this sequence is empty * @return the single element of the sequence * @throws IndexOutOfBoundsException if the sequence has more than one element From fac12ea8252c10afc0fd2469e98d47edbb397880 Mon Sep 17 00:00:00 2001 From: akarnokd Date: Thu, 18 Aug 2016 15:42:19 +0200 Subject: [PATCH 37/66] RxJava 1.1.9; release 1.0.0-RC2 --- README.md | 4 ++-- build.gradle | 4 ++-- gradle.properties | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 8dbf770..41517c1 100644 --- a/README.md +++ b/README.md @@ -18,7 +18,7 @@ and interactive dataflows.** ```groovy dependencies { - compile 'com.github.akarnokd:ixjava:1.0.0-RC1' + compile 'com.github.akarnokd:ixjava:1.0.0-RC2' } ``` @@ -26,7 +26,7 @@ dependencies { ```xml - + ``` diff --git a/build.gradle b/build.gradle index 0454738..11a0e1e 100644 --- a/build.gradle +++ b/build.gradle @@ -44,7 +44,7 @@ apply plugin: 'osgi' dependencies { signature 'org.codehaus.mojo.signature:java16:1.1@signature' - compile "io.reactivex:rxjava:1.1.7" + compile "io.reactivex:rxjava:1.1.9" testCompile group: 'junit', name: 'junit', version: '4.12' } @@ -89,7 +89,7 @@ publishing { } jmh { - jmhVersion = '1.11.3' + jmhVersion = '1.13' humanOutputFile = null if (project.hasProperty('jmh')) { include = ".*" + project.jmh + ".*" diff --git a/gradle.properties b/gradle.properties index 914942d..e547ca3 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1 +1 @@ -version=1.0.0-RC1 +version=1.0.0-RC2 From c9e0defea4b667ed0a0a5a059e573cac957906a6 Mon Sep 17 00:00:00 2001 From: David Karnok Date: Fri, 26 Aug 2016 11:12:25 +0200 Subject: [PATCH 38/66] Update README.md --- README.md | 35 ++++++++++++++++++++++++++++++++++- 1 file changed, 34 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 41517c1..4e60710 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,8 @@ ixjava Interactive Extensions for Java, the dual of RxJava. Originally implemented in the Reactive4Java framework, now converted to work with RxJava. -The aim is to provide pull-based datastream support with the same naming as in RxJava mainly for the pre-Java-8 world. The Stream API in Java 8 is not exactly the same thing because Streams can be only consumed once while Iterables can be consumed many times. Google Guava features a lot of Iterable operators but without method chaining support. +The aim is to provide, lazily evaluated, pull-based datastream support with the same naming as in RxJava mainly for the pre-Java-8 world. The Stream API in Java 8 is not exactly the same thing because Streams can be only consumed once while `Iterable`s can be consumed many times. Google Guava features a lot of Iterable operators, plus now they have the `FluentIterable` with similar setup +but far less operators available (and as of v19, their performance is 2x worse than Ix'). **This branch starts from scratch by reimplementing `ix.Ix` and all of its operators based on the +5 year experience with reactive and interactive dataflows.** @@ -33,3 +34,35 @@ dependencies { Maven search: [http://search.maven.org](http://search.maven.org/#search%7Cga%7C1%7Cg%3A%22com.github.akarnokd%22) + +# Examples + +The main (and only) entry point is the class `ix.Ix` which features a bunch of static factory methods: + +```java +List list = Arrays.asList(1, 2, 3, 4, 5); + +Ix seq = Ix.from(list); +``` + +Now we can apply instance methods on the `seq` sequence, just like in RxJava. Not all operators are available though due to the synchronous-pull nature of IxJava. + +```java +seq +.map(v -> v + 1) +.filter(v -> v % 2 == 0) +.flatMap(v -> Ix.fromArray(v * 10, v * 100))) +.subscribe(System.out::println) +; +``` + +Since `Ix` implements `Iterable`, you can use the for-each loop to consume it: + +```java + +for (Integer v : Ix.fromArray(5, 10).skip(1).concatWith(Ix.just(20))) { + System.out.println("Value: " + v); +} +``` + +For further details on the possibilities, please study the javadoc of `Ix`. From 7d0487ac9ce46551772d501bbec2283adee8b008 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?D=C3=A1vid=20Karnok?= Date: Wed, 14 Sep 2016 23:46:10 +0200 Subject: [PATCH 39/66] Don't depend on RxJava 1 anymore, some cleanup --- .idea/compiler.xml | 27 + .idea/copyright/profiles_settings.xml | 3 + .idea/dictionaries/akarnokd.xml | 8 + .idea/gradle.xml | 17 + .idea/inspectionProfiles/Project_Default.xml | 14 + .../inspectionProfiles/profiles_settings.xml | 7 + .idea/libraries/Gradle__junit_junit_4_12.xml | 11 + ...le__net_sf_jopt_simple_jopt_simple_4_6.xml | 11 + ...__org_apache_commons_commons_math3_3_2.xml | 11 + ...Gradle__org_hamcrest_hamcrest_core_1_3.xml | 11 + .../Gradle__org_openjdk_jmh_jmh_core_1_14.xml | 11 + ...njdk_jmh_jmh_generator_annprocess_1_14.xml | 11 + .idea/misc.xml | 19 + .idea/modules.xml | 11 + .idea/modules/ixjava.iml | 12 + .idea/modules/ixjava_jmh.iml | 18 + .idea/modules/ixjava_main.iml | 13 + .idea/modules/ixjava_test.iml | 17 + .idea/workspace.xml | 1719 +++++++++++++++++ README.md | 2 +- build.gradle | 4 +- src/jmh/java/ix/FlattenIterableArrayPerf.java | 26 +- src/jmh/java/ix/FlattenIterablePerf.java | 24 +- src/jmh/java/ix/IxPerf.java | 4 +- src/jmh/java/ix/RangePerf.java | 24 +- src/jmh/java/ix/ReducePerf.java | 6 +- src/main/java/ix/EqualityHelper.java | 4 +- src/main/java/ix/GroupedIx.java | 4 +- src/main/java/ix/IdentityHelper.java | 14 +- src/main/java/ix/Ix.java | 519 +++-- src/main/java/ix/IxAggregate.java | 24 +- src/main/java/ix/IxAll.java | 26 +- src/main/java/ix/IxAny.java | 26 +- src/main/java/ix/IxAverageDouble.java | 10 +- src/main/java/ix/IxAverageFloat.java | 10 +- src/main/java/ix/IxBaseIterator.java | 14 +- .../ix/{Pred0.java => IxBooleanSupplier.java} | 8 +- src/main/java/ix/IxBuffer.java | 20 +- src/main/java/ix/IxBufferOverlap.java | 36 +- src/main/java/ix/IxBufferSkip.java | 30 +- src/main/java/ix/IxCharacters.java | 20 +- src/main/java/ix/IxCollect.java | 32 +- src/main/java/ix/IxCompose.java | 10 +- src/main/java/ix/IxConsumer.java | 29 + src/main/java/ix/IxConsumer2.java | 31 + src/main/java/ix/IxContains.java | 14 +- src/main/java/ix/IxCount.java | 10 +- src/main/java/ix/IxCountLong.java | 10 +- src/main/java/ix/IxDefer.java | 12 +- src/main/java/ix/IxDistinct.java | 26 +- src/main/java/ix/IxDistinctUntilChanged.java | 54 +- src/main/java/ix/IxDoOn.java | 24 +- src/main/java/ix/IxEmitter.java | 36 + src/main/java/ix/IxEmpty.java | 6 +- src/main/java/ix/IxEmptyAction.java | 18 +- src/main/java/ix/IxExcept.java | 26 +- src/main/java/ix/IxFilter.java | 14 +- src/main/java/ix/IxFlattenArrayIterable.java | 22 +- src/main/java/ix/IxFlattenIterable.java | 32 +- src/main/java/ix/IxForloop.java | 54 +- src/main/java/ix/IxFromArray.java | 8 +- src/main/java/ix/IxFunction.java | 31 + src/main/java/ix/IxFunction2.java | 33 + src/main/java/ix/IxFunction3.java | 35 + src/main/java/ix/IxFunction4.java | 37 + src/main/java/ix/IxGenerate.java | 64 +- src/main/java/ix/IxGenerateStateless.java | 44 +- src/main/java/ix/IxGroupBy.java | 72 +- src/main/java/ix/IxHasElements.java | 6 +- src/main/java/ix/IxIgnoreElements.java | 10 +- src/main/java/ix/IxIntersect.java | 16 +- src/main/java/ix/IxJoin.java | 20 +- src/main/java/ix/IxJust.java | 20 +- src/main/java/ix/IxLift.java | 10 +- src/main/java/ix/IxMap.java | 20 +- src/main/java/ix/IxMaxInt.java | 8 +- src/main/java/ix/IxMaxLong.java | 8 +- src/main/java/ix/IxMinInt.java | 8 +- src/main/java/ix/IxMinLong.java | 8 +- src/main/java/ix/IxMinMax.java | 26 +- src/main/java/ix/IxOrderBy.java | 48 +- .../java/ix/{Pred.java => IxPredicate.java} | 13 +- .../java/ix/{Pred2.java => IxPredicate2.java} | 17 +- src/main/java/ix/IxPublish.java | 4 +- src/main/java/ix/IxPublishSelector.java | 18 +- src/main/java/ix/IxRange.java | 20 +- src/main/java/ix/IxReduce.java | 32 +- src/main/java/ix/IxRemove.java | 18 +- src/main/java/ix/IxRepeat.java | 16 +- src/main/java/ix/IxRepeatCount.java | 20 +- src/main/java/ix/IxRepeatPredicate.java | 26 +- src/main/java/ix/IxReplay.java | 20 +- src/main/java/ix/IxReplaySelector.java | 12 +- src/main/java/ix/IxReplaySize.java | 38 +- src/main/java/ix/IxReplaySizeSelector.java | 16 +- src/main/java/ix/IxRetain.java | 18 +- src/main/java/ix/IxReverse.java | 14 +- src/main/java/ix/IxScan.java | 30 +- src/main/java/ix/IxScanSeed.java | 34 +- src/main/java/ix/IxSequenceEqual.java | 40 +- src/main/java/ix/IxSkip.java | 13 +- src/main/java/ix/IxSkipLast.java | 20 +- src/main/java/ix/IxSkipWhile.java | 26 +- src/main/java/ix/IxSource.java | 8 +- src/main/java/ix/IxSourceIterator.java | 2 +- src/main/java/ix/IxSourceQueuedIterator.java | 40 +- src/main/java/ix/IxSplit.java | 14 +- src/main/java/ix/IxSumInt.java | 8 +- src/main/java/ix/IxSumLong.java | 8 +- src/main/java/ix/IxSupplier.java | 29 + src/main/java/ix/IxSwitchIfEmpty.java | 10 +- src/main/java/ix/IxTake.java | 17 +- src/main/java/ix/IxTakeLast.java | 14 +- src/main/java/ix/IxTakeUntil.java | 14 +- src/main/java/ix/IxTakeWhile.java | 14 +- src/main/java/ix/IxToMap.java | 44 +- src/main/java/ix/IxToMultimap.java | 46 +- src/main/java/ix/IxToSet.java | 12 +- src/main/java/ix/IxTransform.java | 10 +- src/main/java/ix/IxTransformer.java | 18 +- src/main/java/ix/IxUnion.java | 20 +- src/main/java/ix/IxWindow.java | 52 +- src/main/java/ix/IxWindowOverlap.java | 68 +- src/main/java/ix/IxWindowSkip.java | 62 +- src/main/java/ix/IxWrapper.java | 4 +- src/main/java/ix/IxZip2.java | 26 +- src/main/java/ix/IxZip3.java | 28 +- src/main/java/ix/IxZip4.java | 28 +- src/main/java/ix/IxZipArray.java | 48 +- src/main/java/ix/IxZipIterable.java | 23 +- src/main/java/ix/NumberToLongHelper.java | 8 +- src/main/java/ix/SelfComparator.java | 2 +- src/main/java/ix/ToListHelper.java | 24 +- src/test/java/ix/AggregateTest.java | 14 +- src/test/java/ix/AnyAllTest.java | 40 +- src/test/java/ix/AsComposeTest.java | 22 +- src/test/java/ix/AverageTest.java | 26 +- src/test/java/ix/BufferTest.java | 94 +- src/test/java/ix/CharactersTest.java | 26 +- src/test/java/ix/CollectTest.java | 16 +- src/test/java/ix/ConcatArrayTest.java | 54 +- src/test/java/ix/ContainsTest.java | 40 +- src/test/java/ix/CountTest.java | 28 +- src/test/java/ix/DeferTest.java | 8 +- src/test/java/ix/DistinctTest.java | 16 +- .../java/ix/DistinctUntilChangedTest.java | 30 +- src/test/java/ix/DoOnTest.java | 20 +- src/test/java/ix/EmptyActionTest.java | 6 +- src/test/java/ix/EmptyTest.java | 10 +- src/test/java/ix/EqualityHelperTest.java | 10 +- src/test/java/ix/ExceptTest.java | 36 +- src/test/java/ix/FilterTest.java | 20 +- src/test/java/ix/FirstTest.java | 14 +- src/test/java/ix/FlattenIterableTest.java | 42 +- src/test/java/ix/ForeachTest.java | 28 +- src/test/java/ix/ForloopTest.java | 32 +- src/test/java/ix/FromArrayTest.java | 22 +- src/test/java/ix/FromTest.java | 8 +- src/test/java/ix/GenerateStatelessTest.java | 53 +- src/test/java/ix/GenerateTest.java | 80 +- src/test/java/ix/GroupByTest.java | 150 +- src/test/java/ix/HasElementsTest.java | 4 +- src/test/java/ix/HelperTest.java | 4 +- src/test/java/ix/HideTest.java | 2 +- src/test/java/ix/IgnoreElementsTest.java | 8 +- src/test/java/ix/IntersectTest.java | 24 +- .../ix/IxOperatorsArePackageFinalTest.java | 65 + src/test/java/ix/IxTest.java | 20 +- src/test/java/ix/IxTestHelper.java | 28 +- src/test/java/ix/JoinTest.java | 24 +- src/test/java/ix/JustTest.java | 4 +- src/test/java/ix/LastTest.java | 14 +- src/test/java/ix/LeavingTest.java | 280 +-- src/test/java/ix/LiftTest.java | 14 +- src/test/java/ix/MapTest.java | 18 +- src/test/java/ix/MaxTest.java | 12 +- src/test/java/ix/MinMaxTest.java | 34 +- src/test/java/ix/MinTest.java | 12 +- src/test/java/ix/OrderByTest.java | 44 +- src/test/java/ix/PublishTest.java | 38 +- src/test/java/ix/RangeTest.java | 16 +- src/test/java/ix/ReduceTest.java | 32 +- src/test/java/ix/RemoveRetainTest.java | 72 +- src/test/java/ix/RepeatTest.java | 102 +- src/test/java/ix/ReplayTest.java | 86 +- src/test/java/ix/ReverseTest.java | 8 +- src/test/java/ix/ScanTest.java | 72 +- src/test/java/ix/SelfComparatorTest.java | 10 +- src/test/java/ix/SequenceEqualTest.java | 16 +- src/test/java/ix/SkipLastTest.java | 18 +- src/test/java/ix/SkipTest.java | 10 +- src/test/java/ix/SkipWhileTest.java | 18 +- .../java/ix/SourceQueuedIteratorTest.java | 34 +- src/test/java/ix/SplitTest.java | 28 +- src/test/java/ix/SumTest.java | 12 +- src/test/java/ix/SwitchIfEmptyTest.java | 22 +- src/test/java/ix/TakeLastTest.java | 18 +- src/test/java/ix/TakeTest.java | 18 +- src/test/java/ix/TakeUntilTest.java | 18 +- src/test/java/ix/TakeWhileTest.java | 18 +- src/test/java/ix/ToArrayTest.java | 2 +- src/test/java/ix/ToListTest.java | 7 +- src/test/java/ix/ToMapTest.java | 64 +- src/test/java/ix/ToSetTest.java | 14 +- src/test/java/ix/ToXTest.java | 50 +- src/test/java/ix/TransformTest.java | 40 +- src/test/java/ix/UnionTest.java | 46 +- src/test/java/ix/WindowTest.java | 106 +- src/test/java/ix/Zip2Test.java | 38 +- src/test/java/ix/Zip3Test.java | 40 +- src/test/java/ix/Zip4Test.java | 46 +- src/test/java/ix/ZipArrayTest.java | 40 +- src/test/java/ix/ZipIterableTest.java | 50 +- 213 files changed, 4826 insertions(+), 2903 deletions(-) create mode 100644 .idea/compiler.xml create mode 100644 .idea/copyright/profiles_settings.xml create mode 100644 .idea/dictionaries/akarnokd.xml create mode 100644 .idea/gradle.xml create mode 100644 .idea/inspectionProfiles/Project_Default.xml create mode 100644 .idea/inspectionProfiles/profiles_settings.xml create mode 100644 .idea/libraries/Gradle__junit_junit_4_12.xml create mode 100644 .idea/libraries/Gradle__net_sf_jopt_simple_jopt_simple_4_6.xml create mode 100644 .idea/libraries/Gradle__org_apache_commons_commons_math3_3_2.xml create mode 100644 .idea/libraries/Gradle__org_hamcrest_hamcrest_core_1_3.xml create mode 100644 .idea/libraries/Gradle__org_openjdk_jmh_jmh_core_1_14.xml create mode 100644 .idea/libraries/Gradle__org_openjdk_jmh_jmh_generator_annprocess_1_14.xml create mode 100644 .idea/misc.xml create mode 100644 .idea/modules.xml create mode 100644 .idea/modules/ixjava.iml create mode 100644 .idea/modules/ixjava_jmh.iml create mode 100644 .idea/modules/ixjava_main.iml create mode 100644 .idea/modules/ixjava_test.iml create mode 100644 .idea/workspace.xml rename src/main/java/ix/{Pred0.java => IxBooleanSupplier.java} (78%) create mode 100644 src/main/java/ix/IxConsumer.java create mode 100644 src/main/java/ix/IxConsumer2.java create mode 100644 src/main/java/ix/IxEmitter.java create mode 100644 src/main/java/ix/IxFunction.java create mode 100644 src/main/java/ix/IxFunction2.java create mode 100644 src/main/java/ix/IxFunction3.java create mode 100644 src/main/java/ix/IxFunction4.java rename src/main/java/ix/{Pred.java => IxPredicate.java} (70%) rename src/main/java/ix/{Pred2.java => IxPredicate2.java} (64%) create mode 100644 src/main/java/ix/IxSupplier.java create mode 100644 src/test/java/ix/IxOperatorsArePackageFinalTest.java diff --git a/.idea/compiler.xml b/.idea/compiler.xml new file mode 100644 index 0000000..8cbd3f4 --- /dev/null +++ b/.idea/compiler.xml @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/copyright/profiles_settings.xml b/.idea/copyright/profiles_settings.xml new file mode 100644 index 0000000..e7bedf3 --- /dev/null +++ b/.idea/copyright/profiles_settings.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/.idea/dictionaries/akarnokd.xml b/.idea/dictionaries/akarnokd.xml new file mode 100644 index 0000000..0e1ac72 --- /dev/null +++ b/.idea/dictionaries/akarnokd.xml @@ -0,0 +1,8 @@ + + + + forloop + karnok + + + \ No newline at end of file diff --git a/.idea/gradle.xml b/.idea/gradle.xml new file mode 100644 index 0000000..77e9972 --- /dev/null +++ b/.idea/gradle.xml @@ -0,0 +1,17 @@ + + + + + + \ No newline at end of file diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml new file mode 100644 index 0000000..fd947e6 --- /dev/null +++ b/.idea/inspectionProfiles/Project_Default.xml @@ -0,0 +1,14 @@ + + + + \ No newline at end of file diff --git a/.idea/inspectionProfiles/profiles_settings.xml b/.idea/inspectionProfiles/profiles_settings.xml new file mode 100644 index 0000000..3b31283 --- /dev/null +++ b/.idea/inspectionProfiles/profiles_settings.xml @@ -0,0 +1,7 @@ + + + + \ No newline at end of file diff --git a/.idea/libraries/Gradle__junit_junit_4_12.xml b/.idea/libraries/Gradle__junit_junit_4_12.xml new file mode 100644 index 0000000..04c10dd --- /dev/null +++ b/.idea/libraries/Gradle__junit_junit_4_12.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Gradle__net_sf_jopt_simple_jopt_simple_4_6.xml b/.idea/libraries/Gradle__net_sf_jopt_simple_jopt_simple_4_6.xml new file mode 100644 index 0000000..d1405f7 --- /dev/null +++ b/.idea/libraries/Gradle__net_sf_jopt_simple_jopt_simple_4_6.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Gradle__org_apache_commons_commons_math3_3_2.xml b/.idea/libraries/Gradle__org_apache_commons_commons_math3_3_2.xml new file mode 100644 index 0000000..75cc803 --- /dev/null +++ b/.idea/libraries/Gradle__org_apache_commons_commons_math3_3_2.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Gradle__org_hamcrest_hamcrest_core_1_3.xml b/.idea/libraries/Gradle__org_hamcrest_hamcrest_core_1_3.xml new file mode 100644 index 0000000..8262f72 --- /dev/null +++ b/.idea/libraries/Gradle__org_hamcrest_hamcrest_core_1_3.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Gradle__org_openjdk_jmh_jmh_core_1_14.xml b/.idea/libraries/Gradle__org_openjdk_jmh_jmh_core_1_14.xml new file mode 100644 index 0000000..47c0ab7 --- /dev/null +++ b/.idea/libraries/Gradle__org_openjdk_jmh_jmh_core_1_14.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Gradle__org_openjdk_jmh_jmh_generator_annprocess_1_14.xml b/.idea/libraries/Gradle__org_openjdk_jmh_jmh_generator_annprocess_1_14.xml new file mode 100644 index 0000000..e8189c8 --- /dev/null +++ b/.idea/libraries/Gradle__org_openjdk_jmh_jmh_generator_annprocess_1_14.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..b29bc37 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..63705b8 --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/modules/ixjava.iml b/.idea/modules/ixjava.iml new file mode 100644 index 0000000..fac74e1 --- /dev/null +++ b/.idea/modules/ixjava.iml @@ -0,0 +1,12 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/modules/ixjava_jmh.iml b/.idea/modules/ixjava_jmh.iml new file mode 100644 index 0000000..30f5371 --- /dev/null +++ b/.idea/modules/ixjava_jmh.iml @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/modules/ixjava_main.iml b/.idea/modules/ixjava_main.iml new file mode 100644 index 0000000..29a46d3 --- /dev/null +++ b/.idea/modules/ixjava_main.iml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/modules/ixjava_test.iml b/.idea/modules/ixjava_test.iml new file mode 100644 index 0000000..7ec8692 --- /dev/null +++ b/.idea/modules/ixjava_test.iml @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/workspace.xml b/.idea/workspace.xml new file mode 100644 index 0000000..8e90062 --- /dev/null +++ b/.idea/workspace.xml @@ -0,0 +1,1719 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + true + DEFINITION_ORDER + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1473888618399 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + No facets are configured + + + + + + + + + + + + + + + 1.8 + + + + + + + + ixjava + + + + + + + + 1.8 + + + + + + + + Gradle: junit:junit:4.12 + + + + + + + + \ No newline at end of file diff --git a/README.md b/README.md index 4e60710..f9db33f 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@ ixjava [![codecov.io](http://codecov.io/github/akarnokd/ixjava/coverage.svg?branch=1.x)](http://codecov.io/github/akarnokd/ixjava?branch=1.x) [![Maven Central](https://maven-badges.herokuapp.com/maven-central/com.github.akarnokd/ixjava/badge.svg)](https://maven-badges.herokuapp.com/maven-central/com.github.akarnokd/ixjava) -Interactive Extensions for Java, the dual of RxJava. Originally implemented in the Reactive4Java framework, now converted to work with RxJava. +Iterable Extensions for Java, the dual of RxJava. Originally implemented in the Reactive4Java framework, now converted to work with RxJava. The aim is to provide, lazily evaluated, pull-based datastream support with the same naming as in RxJava mainly for the pre-Java-8 world. The Stream API in Java 8 is not exactly the same thing because Streams can be only consumed once while `Iterable`s can be consumed many times. Google Guava features a lot of Iterable operators, plus now they have the `FluentIterable` with similar setup but far less operators available (and as of v19, their performance is 2x worse than Ix'). diff --git a/build.gradle b/build.gradle index 11a0e1e..e17625a 100644 --- a/build.gradle +++ b/build.gradle @@ -44,8 +44,6 @@ apply plugin: 'osgi' dependencies { signature 'org.codehaus.mojo.signature:java16:1.1@signature' - compile "io.reactivex:rxjava:1.1.9" - testCompile group: 'junit', name: 'junit', version: '4.12' } @@ -89,7 +87,7 @@ publishing { } jmh { - jmhVersion = '1.13' + jmhVersion = '1.14' humanOutputFile = null if (project.hasProperty('jmh')) { include = ".*" + project.jmh + ".*" diff --git a/src/jmh/java/ix/FlattenIterableArrayPerf.java b/src/jmh/java/ix/FlattenIterableArrayPerf.java index 1c997c8..e58efff 100644 --- a/src/jmh/java/ix/FlattenIterableArrayPerf.java +++ b/src/jmh/java/ix/FlattenIterableArrayPerf.java @@ -22,8 +22,6 @@ import org.openjdk.jmh.annotations.*; import org.openjdk.jmh.infra.Blackhole; -import rx.functions.Func1; - /** * Example benchmark. Run from command line as *
@@ -35,45 +33,45 @@ @OutputTimeUnit(TimeUnit.SECONDS) @Fork(value = 1) @State(Scope.Thread) -public class FlattenIterableArrayPerf implements Func1> { +public class FlattenIterableArrayPerf implements IxFunction> { @Param({"1", "10", "100", "1000", "10000", "100000", "1000000"}) public int count; - + Ix source; - + Ix inner; Ix flatMapJust; @Override - public Iterable call(Integer t) { + public Iterable apply(Integer t) { return inner; } - + @Setup public void setup(Blackhole bh) { int d = 1000000 / count; - + Integer[] countArray = new Integer[count]; Arrays.fill(countArray, 777); - + inner = Ix.fromArray(countArray); Integer[] sourceArray = new Integer[d]; Arrays.fill(sourceArray, 777); - + source = Ix.fromArray(sourceArray).flatMap(this); - - flatMapJust = inner.flatMap(new Func1>() { + + flatMapJust = inner.flatMap(new IxFunction>() { @Override - public Iterable call(Integer v) { + public Iterable apply(Integer v) { return Ix.just(v); } }); } - + @Benchmark public Object xrangeLast() { return source.last(); diff --git a/src/jmh/java/ix/FlattenIterablePerf.java b/src/jmh/java/ix/FlattenIterablePerf.java index 5fa5275..cbc4cf9 100644 --- a/src/jmh/java/ix/FlattenIterablePerf.java +++ b/src/jmh/java/ix/FlattenIterablePerf.java @@ -21,8 +21,6 @@ import org.openjdk.jmh.annotations.*; import org.openjdk.jmh.infra.Blackhole; -import rx.functions.Func1; - /** * Example benchmark. Run from command line as *
@@ -34,39 +32,39 @@ @OutputTimeUnit(TimeUnit.SECONDS) @Fork(value = 1) @State(Scope.Thread) -public class FlattenIterablePerf implements Func1> { +public class FlattenIterablePerf implements IxFunction> { @Param({"1", "10", "100", "1000", "10000", "100000", "1000000"}) public int count; - + Ix source; - + Ix inner; Ix flatMapJust; @Override - public Iterable call(Integer t) { + public Iterable apply(Integer t) { return inner; } - + @Setup public void setup(Blackhole bh) { int d = 1000000 / count; - + inner = Ix.range(1, count); - + source = Ix.range(1, d).flatMap(this); - - flatMapJust = Ix.range(1, count).flatMap(new Func1>() { + + flatMapJust = Ix.range(1, count).flatMap(new IxFunction>() { @Override - public Iterable call(Integer v) { + public Iterable apply(Integer v) { return Ix.just(v); } }); } - + @Benchmark public Object xrangeLast() { return source.last(); diff --git a/src/jmh/java/ix/IxPerf.java b/src/jmh/java/ix/IxPerf.java index 0efd963..a15b697 100644 --- a/src/jmh/java/ix/IxPerf.java +++ b/src/jmh/java/ix/IxPerf.java @@ -36,12 +36,12 @@ public class IxPerf { // @Param({"1", "10", "100", "1000", "10000", "100000", "1000000"}) // public int count; - + @Setup public void setup(Blackhole bh) { } - + @Benchmark public Object just() { return new IxJust(1).iterator().next(); diff --git a/src/jmh/java/ix/RangePerf.java b/src/jmh/java/ix/RangePerf.java index 7eb7ee2..985d01a 100644 --- a/src/jmh/java/ix/RangePerf.java +++ b/src/jmh/java/ix/RangePerf.java @@ -21,8 +21,6 @@ import org.openjdk.jmh.annotations.*; import org.openjdk.jmh.infra.Blackhole; -import rx.functions.Func1; - /** * Example benchmark. Run from command line as *
@@ -34,39 +32,39 @@ @OutputTimeUnit(TimeUnit.SECONDS) @Fork(value = 1) @State(Scope.Thread) -public class RangePerf implements Func1> { +public class RangePerf implements IxFunction> { @Param({"1", "10", "100", "1000", "10000", "100000", "1000000"}) public int count; - + Ix source; - + Ix inner; Ix flatMapJust; @Override - public Iterable call(Integer t) { + public Iterable apply(Integer t) { return inner; } - + @Setup public void setup(Blackhole bh) { int d = 1000000 / count; - + inner = Ix.range(1, count); - + source = Ix.range(1, d).flatMap(this); - - flatMapJust = Ix.range(1, count).flatMap(new Func1>() { + + flatMapJust = Ix.range(1, count).flatMap(new IxFunction>() { @Override - public Iterable call(Integer v) { + public Iterable apply(Integer v) { return Ix.just(v); } }); } - + @Benchmark public Object rangeLast() { return inner.last(); diff --git a/src/jmh/java/ix/ReducePerf.java b/src/jmh/java/ix/ReducePerf.java index c6efe16..40947a7 100644 --- a/src/jmh/java/ix/ReducePerf.java +++ b/src/jmh/java/ix/ReducePerf.java @@ -39,15 +39,15 @@ public class ReducePerf { public int count; Ix sum; - + @Setup public void setup(Blackhole bh) { Integer[] array = new Integer[count]; Arrays.fill(array, 1); - + sum = Ix.fromArray(array).sumInt(); } - + @Benchmark public Object sumLast() { return sum.last(); diff --git a/src/main/java/ix/EqualityHelper.java b/src/main/java/ix/EqualityHelper.java index 9d51f0a..d901495 100644 --- a/src/main/java/ix/EqualityHelper.java +++ b/src/main/java/ix/EqualityHelper.java @@ -16,9 +16,9 @@ package ix; -enum EqualityHelper implements Pred2 { +enum EqualityHelper implements IxPredicate2 { INSTANCE; - + @Override public boolean test(Object t, Object u) { return (t == u) || (t != null && t.equals(u)); diff --git a/src/main/java/ix/GroupedIx.java b/src/main/java/ix/GroupedIx.java index 18672e2..c6681fe 100644 --- a/src/main/java/ix/GroupedIx.java +++ b/src/main/java/ix/GroupedIx.java @@ -26,11 +26,11 @@ public abstract class GroupedIx extends Ix { protected final K key; - + public GroupedIx(K key) { this.key = key; } - + public final K key() { return key; } diff --git a/src/main/java/ix/IdentityHelper.java b/src/main/java/ix/IdentityHelper.java index ff5e680..f3358b9 100644 --- a/src/main/java/ix/IdentityHelper.java +++ b/src/main/java/ix/IdentityHelper.java @@ -16,19 +16,17 @@ package ix; -import rx.functions.Func1; - -enum IdentityHelper implements Func1 { +enum IdentityHelper implements IxFunction { INSTANCE ; - + @SuppressWarnings("unchecked") - public static Func1 instance() { - return (Func1)INSTANCE; + public static IxFunction instance() { + return (IxFunction)INSTANCE; } - + @Override - public Object call(Object t) { + public Object apply(Object t) { return t; } } \ No newline at end of file diff --git a/src/main/java/ix/Ix.java b/src/main/java/ix/Ix.java index 718a11a..46432ca 100644 --- a/src/main/java/ix/Ix.java +++ b/src/main/java/ix/Ix.java @@ -19,11 +19,6 @@ import java.util.*; import java.util.concurrent.Callable; -import rx.Observer; -import rx.Subscriber; -import rx.exceptions.Exceptions; -import rx.functions.*; - /** * Base class and entry point for fluent Iterables. *

@@ -48,7 +43,7 @@ public abstract class Ix implements Iterable { public static Ix characters(CharSequence cs) { return new IxCharacters(cs, 0, cs.length()); } - + /** * Emits a range of characters from the given CharSequence as integer values. *

@@ -85,7 +80,7 @@ public static Ix characters(CharSequence cs, int start, int end) { @SuppressWarnings({ "unchecked", "rawtypes" }) public static Ix concat(Iterable> sources) { return new IxFlattenIterable, T>( - (Iterable)nullCheck(sources, "sources is null"), + (Iterable)nullCheck(sources, "sources is null"), IdentityHelper.>instance()); } @@ -124,7 +119,7 @@ public static Ix concat(Iterable source1, Iterable Ix concat(Iterable source1, Iterable source2, Iterable source3) { - return concatArray(nullCheck(source1, "source1 is null"), + return concatArray(nullCheck(source1, "source1 is null"), nullCheck(source2, "source2 is null"), nullCheck(source3, "source3 is null")); } @@ -146,7 +141,7 @@ public static Ix concat(Iterable source1, Iterable Ix concat(Iterable source1, Iterable source2, Iterable source3, Iterable source4) { - return concatArray(nullCheck(source1, "source1 is null"), nullCheck(source2, "source2 is null"), + return concatArray(nullCheck(source1, "source1 is null"), nullCheck(source2, "source2 is null"), nullCheck(source3, "source3 is null"), nullCheck(source4, "source4 is null")); } @@ -186,10 +181,10 @@ public static Ix concatArray(Iterable... sources) { * @throws NullPointerException if factory is null * @since 1.0 */ - public static Ix defer(Func0> factory) { + public static Ix defer(IxSupplier> factory) { return new IxDefer(nullCheck(factory, "factory is null")); } - + /** * No elements are emitted. *

@@ -201,7 +196,7 @@ public static Ix defer(Func0> factory) { public static Ix empty() { return IxEmpty.instance(); } - + /** * Wraps the given Iterable source into an Ix instance (if * not already an Ix subclass). @@ -220,9 +215,9 @@ public static Ix from(Iterable source) { } return new IxWrapper(nullCheck(source, "source")); } - + /** - * Emits all the elements of the given array. + * Emits all the elements of the given array. *

* The result's iterator() doesn't support remove(). * @param the value type @@ -280,15 +275,15 @@ public static Ix fromArrayRange(int start, int end, T... values) { * @throws NullPointerException if condition, next or selector is null * @since 1.0 */ - public static Ix forloop(T seed, Pred condition, - Func1 next, - Func1 selector) { + public static Ix forloop(T seed, IxPredicate condition, + IxFunction next, + IxFunction selector) { return new IxForloop(seed, nullCheck(condition, "condition is null"), nullCheck(selector, "selector is null"), nullCheck(next, "next is null")); } /** - * Calls the given action to generate a value or terminate whenever the next() + * Calls the given action to generate a value or terminate whenever the next() * is called on the resulting Ix.iterator(). *

* The result's iterator() doesn't support remove(). @@ -296,19 +291,19 @@ public static Ix forloop(T seed, Pred condition, * The action may call {@code onNext} at most once to signal the next value per action invocation. * The {@code onCompleted} should be called to indicate no further values will be generated (may be * called with an onNext in the same action invocation). Calling {@code onError} will immediately - * throw the given exception (as is if it's a RuntimeException or Error; or wrapped into a RuntimeException). + * throw the given exception (as is if it's a RuntimeException or Error; or wrapped into a RuntimeException). * @param the value type - * @param nextSupplier the action called with an Observer API to receive value, not null + * @param nextSupplier the action called with an IxEmitter API to receive value, not null * @return the new Ix instance * @throws NullPointerException if nextSupplier is null * @since 1.0 */ - public static Ix generate(Action1> nextSupplier) { + public static Ix generate(IxConsumer> nextSupplier) { return new IxGenerateStateless(nullCheck(nextSupplier, "nextSupplier is null")); } /** - * Calls the given function (with per-iterator state) to generate a value or terminate + * Calls the given function (with per-iterator state) to generate a value or terminate * whenever the next() is called on the resulting Ix.iterator(). *

* The result's iterator() doesn't support remove(). @@ -316,21 +311,21 @@ public static Ix generate(Action1> nextSupplier) { * The action may call {@code onNext} at most once to signal the next value per action invocation. * The {@code onCompleted} should be called to indicate no further values will be generated (may be * called with an onNext in the same action invocation). Calling {@code onError} will immediately - * throw the given exception (as is if it's a RuntimeException or Error; or wrapped into a RuntimeException). + * throw the given exception (as is if it's a RuntimeException or Error; or wrapped into a RuntimeException). * @param the value type * @param the state type supplied to and returned by the nextSupplier function * @param stateSupplier the function that returns a state for each invocation of iterator() - * @param nextSupplier the action called with an Observer API to receive value, not null + * @param nextSupplier the action called with an IxEmitter API to receive value, not null * @return the new Ix instance * @throws NullPointerException if stateSupplier or nextSupplier is null * @since 1.0 */ - public static Ix generate(Func0 stateSupplier, Func2, S> nextSupplier) { + public static Ix generate(IxSupplier stateSupplier, IxFunction2, S> nextSupplier) { return generate(stateSupplier, nextSupplier, IxEmptyAction.instance1()); } /** - * Calls the given function (with per-iterator state) to generate a value or terminate + * Calls the given function (with per-iterator state) to generate a value or terminate * whenever the next() is called on the resulting Ix.iterator(). *

* The result's iterator() doesn't support remove(). @@ -341,18 +336,18 @@ public static Ix generate(Func0 stateSupplier, Func2 * throw the given exception (as is if it's a RuntimeException or Error; or wrapped into a RuntimeException). *

* Note that since there is no direct way to cancel an Iterator, the stateDisposer is only invoked - * when the nextSupplier calls a terminal method. + * when the nextSupplier calls a terminal method. * @param the value type * @param the state type supplied to and returned by the nextSupplier function * @param stateSupplier the function that returns a state for each invocation of iterator() - * @param nextSupplier the action called with an Observer API to receive value, not null + * @param nextSupplier the action called with an IxEmitter API to receive value, not null * @param stateDisposer the action called when the nextSupplier signals an {@code onError} or {@code onCompleted}. * @return the new Ix instance * @throws NullPointerException if stateSupplier, nextSupplier or stateDisposer is null * @since 1.0 */ - public static Ix generate(Func0 stateSupplier, Func2, S> nextSupplier, Action1 stateDisposer) { - return new IxGenerate(nullCheck(stateSupplier, "stateSupplier is null"), + public static Ix generate(IxSupplier stateSupplier, IxFunction2, S> nextSupplier, IxConsumer stateDisposer) { + return new IxGenerate(nullCheck(stateSupplier, "stateSupplier is null"), nullCheck(nextSupplier, "nextSupplier is null"), nullCheck(stateDisposer, "stateDisposer is null")); } @@ -385,7 +380,7 @@ public static Ix just(T value) { public static Ix merge(Iterable> sources) { return concat(sources); } - + /** * Concatenates the elements of Iterable sources, provided as an array, sequentially. *

@@ -402,7 +397,7 @@ public static Ix merge(Iterable> sources) public static Ix mergeArray(Iterable... sources) { return concatArray(sources); // concat and merge are the same in the Iterable world } - + /** * Emits a range of incrementing integer values, starting from {@code start} and * up to {@code count} times. @@ -471,7 +466,7 @@ public static Ix repeatValue(T value, long count) { * @throws NullPointerException if stopPredicate is null * @since 1.0 */ - public static Ix repeatValue(T value, Pred0 stopPredicate) { + public static Ix repeatValue(T value, IxBooleanSupplier stopPredicate) { return repeatValue(value, Long.MAX_VALUE, stopPredicate); } @@ -492,10 +487,10 @@ public static Ix repeatValue(T value, Pred0 stopPredicate) { * @throws NullPointerException if stopPredicate is null * @since 1.0 */ - public static Ix repeatValue(T value, long count, Pred0 stopPredicate) { + public static Ix repeatValue(T value, long count, IxBooleanSupplier stopPredicate) { return new IxRepeatPredicate(value, nonNegative(count, "count"), nullCheck(stopPredicate, "stopPredicate is null")); } - + /** * Emits a sequence of substring of a string split by the given separator. *

@@ -509,14 +504,14 @@ public static Ix repeatValue(T value, long count, Pred0 stopPredicate) { public static Ix split(String string, String by) { return new IxSplit(nullCheck(string, "string is null"), nullCheck(by, "by is null")); } - + /** * Combines the next element from each source Iterable via a zipper function. *

* If one of the source Iterables is sorter the sequence terminates eagerly. *

* The result's iterator() doesn't support remove(). - * + * * @param the common element type of the sources * @param the result value type * @param sources the array of Iterable sources, not null @@ -526,18 +521,18 @@ public static Ix split(String string, String by) { * @throws NullPointerException if sources or zipper is null * @since 1.0 */ - public static Ix zip(Iterable[] sources, FuncN zipper) { + public static Ix zip(Iterable[] sources, IxFunction zipper) { return new IxZipArray(nullCheck(sources, "sources is null"), nullCheck(zipper, "zipper is null")); } /** - * Combines the next element from each source Iterable, provided as an Iterable itself, + * Combines the next element from each source Iterable, provided as an Iterable itself, * via a zipper function. *

* If one of the source Iterables is sorter the sequence terminates eagerly. *

* The result's iterator() doesn't support remove(). - * + * * @param the common element type of the sources * @param the result value type * @param sources the Iterable of Iterable sources, not null @@ -547,7 +542,7 @@ public static Ix zip(Iterable[] sources, FuncN zipper) * @throws NullPointerException if sources or zipper is null * @since 1.0 */ - public static Ix zip(Iterable> sources, FuncN zipper) { + public static Ix zip(Iterable> sources, IxFunction zipper) { return new IxZipIterable(nullCheck(sources, "sources is null"), nullCheck(zipper, "zipper is null")); } @@ -557,21 +552,21 @@ public static Ix zip(Iterable> sources * If one of the source Iterables is sorter the sequence terminates eagerly. *

* The result's iterator() doesn't support remove(). - * + * * @param the first source's element type * @param the second source's element type * @param the result value type * @param source1 the first source Iterable * @param source2 the second source Iterable - * @param zipper the function that takesone from each source, not null + * @param zipper the function that takes one from each source, not null * @return the new Ix instance * @throws NullPointerException if any of the sources or zipper is null * @since 1.0 */ public static Ix zip( - Iterable source1, Iterable source2, - Func2 zipper) { - return new IxZip2(nullCheck(source1, "source1 is null"), + Iterable source1, Iterable source2, + IxFunction2 zipper) { + return new IxZip2(nullCheck(source1, "source1 is null"), nullCheck(source2, "source2 is null"), nullCheck(zipper, "zipper is null")); } @@ -581,7 +576,7 @@ public static Ix zip( * If one of the source Iterables is sorter the sequence terminates eagerly. *

* The result's iterator() doesn't support remove(). - * + * * @param the first source's element type * @param the second source's element type * @param the third source's element type @@ -589,16 +584,16 @@ public static Ix zip( * @param source1 the first source Iterable * @param source2 the second source Iterable * @param source3 the third source Iterable - * @param zipper the function that takesone from each source, not null + * @param zipper the function that takes one from each source, not null * @return the new Ix instance * @throws NullPointerException if any of the sources or zipper is null * @since 1.0 */ public static Ix zip( - Iterable source1, Iterable source2, + Iterable source1, Iterable source2, Iterable source3, - Func3 zipper) { - return new IxZip3(nullCheck(source1, "source1 is null"), nullCheck(source2, "source2 is null"), + IxFunction3 zipper) { + return new IxZip3(nullCheck(source1, "source1 is null"), nullCheck(source2, "source2 is null"), nullCheck(source3, "source3 is null"), nullCheck(zipper, "zipper is null")); } @@ -608,7 +603,7 @@ public static Ix zip( * If one of the source Iterables is sorter the sequence terminates eagerly. *

* The result's iterator() doesn't support remove(). - * + * * @param the first source's element type * @param the second source's element type * @param the third source's element type @@ -618,24 +613,24 @@ public static Ix zip( * @param source2 the second source Iterable * @param source3 the third source Iterable * @param source4 the fourth source Iterable - * @param zipper the function that takesone from each source, not null + * @param zipper the function that takes one from each source, not null * @return the new Ix instance * @throws NullPointerException if any of the sources or zipper is null * @since 1.0 */ public static Ix zip( - Iterable source1, Iterable source2, + Iterable source1, Iterable source2, Iterable source3, Iterable source4, - Func4 zipper) { - return new IxZip4(nullCheck(source1, "source1 is null"), - nullCheck(source2, "source2 is null"), nullCheck(source3, "source3 is null"), + IxFunction4 zipper) { + return new IxZip4(nullCheck(source1, "source1 is null"), + nullCheck(source2, "source2 is null"), nullCheck(source3, "source3 is null"), nullCheck(source4, "source4 is null"), nullCheck(zipper, "zipper is null")); } //--------------------------------------------------------------------------------------- // Instance operators //--------------------------------------------------------------------------------------- - + /** * Emits true if all elements of this sequence match a given predicate (including empty). *

@@ -643,12 +638,12 @@ public static Ix zip( * @param predicate the predicate receiving each element * @return the new Ix instance * @throws NullPointerException if predicate is null - * @since 1.0 + * @since 1.0 */ - public final Ix all(Pred predicate) { + public final Ix all(IxPredicate predicate) { return new IxAll(this, nullCheck(predicate, "predicate is null")); } - + /** * Emits true if any element of this sequence matches the given predicate, * false otherwise (or for empty sequences). @@ -659,7 +654,7 @@ public final Ix all(Pred predicate) { * @throws NullPointerException if predicate is null * @since 1.0 */ - public final Ix any(Pred predicate) { + public final Ix any(IxPredicate predicate) { return new IxAny(this, nullCheck(predicate, "predicate is null")); } @@ -672,10 +667,10 @@ public final Ix any(Pred predicate) { * @throws NullPointerException if transformer is null * @since 1.0 */ - public final R as(Func1, R> transformer) { - return transformer.call(this); + public final R as(IxFunction, R> transformer) { + return transformer.apply(this); } - + /** * Calculates the float-based average of this sequence of numbers. *

The returned sequence is empty if this sequence is empty. @@ -707,7 +702,7 @@ public final Ix averageFloat() { public final Ix averageDouble() { return new IxAverageDouble((Iterable)this); } - + /** * Buffers the subsequent {@code size} elements into a sequence of * non-overlapping Lists. @@ -721,9 +716,9 @@ public final Ix averageDouble() { public final Ix> buffer(int size) { return new IxBuffer(this, positive(size, "size")); } - + /** - * Buffers the subsequent {@code size} elemeints into a sequence of + * Buffers the subsequent {@code size} elements into a sequence of * potentially overlapping Lists. *

* The result's iterator() doesn't support remove(). @@ -742,7 +737,7 @@ public final Ix> buffer(int size, int skip) { } return new IxBufferOverlap(this, positive(size, "size"), positive(skip, "skip")); } - + /** * Cast the elements to the specified class. *

@@ -757,7 +752,7 @@ public final Ix> buffer(int size, int skip) { public final Ix cast(Class clazz) { return (Ix)this; } - + /** * Collect the elements into a collection via collector action and emit that collection * as a single item. @@ -770,10 +765,10 @@ public final Ix cast(Class clazz) { * @throws NullPointerException if initialFactory or collector is null * @since 1.0 */ - public final Ix collect(Func0 initialFactory, Action2 collector) { - return new IxCollect(this, nullCheck(initialFactory, "initalFactory is null"), nullCheck(collector, "collector")); + public final Ix collect(IxSupplier initialFactory, IxConsumer2 collector) { + return new IxCollect(this, nullCheck(initialFactory, "initialFactory is null"), nullCheck(collector, "collector")); } - + /** * Collects the elements of this sequence into an Object array. *

@@ -785,7 +780,7 @@ public final Ix collectToArray() { return collect(ToListHelper.initialFactory(), ToListHelper.collector()) .map(ToListHelper.toArray()); } - + /** * Collects the elements of this sequence into a List. *

@@ -796,7 +791,7 @@ public final Ix collectToArray() { public final Ix> collectToList() { return collect(ToListHelper.initialFactory(), ToListHelper.collector()); } - + /** * Collects the elements of this sequence into a Map where the key is * determined from each element via the keySelector function; duplicates are @@ -810,8 +805,8 @@ public final Ix> collectToList() { * @throws NullPointerException if keySelector is null * @since 1.0 */ - public final Ix> collectToMap(Func1 keySelector) { - Func1 f = IdentityHelper.instance(); + public final Ix> collectToMap(IxFunction keySelector) { + IxFunction f = IdentityHelper.instance(); return this.collectToMap(keySelector, f); } @@ -832,7 +827,7 @@ public final Ix> collectToMap(Func1 keySel * @throws NullPointerException if keySelector or valueSelector is null * @since 1.0 */ - public final Ix> collectToMap(Func1 keySelector, Func1 valueSelector) { + public final Ix> collectToMap(IxFunction keySelector, IxFunction valueSelector) { return new IxToMap(this, nullCheck(keySelector, "keySelector is null"), nullCheck(valueSelector, "valueSelector is null")); } @@ -848,8 +843,8 @@ public final Ix> collectToMap(Func1 key * @throws NullPointerException if keySelector is null * @since 1.0 */ - public final Ix>> collectToMultimap(Func1 keySelector) { - Func1 f = IdentityHelper.instance(); + public final Ix>> collectToMultimap(IxFunction keySelector) { + IxFunction f = IdentityHelper.instance(); return this.collectToMultimap(keySelector, f); } @@ -869,10 +864,10 @@ public final Ix>> collectToMultimap(Func1 Ix>> collectToMultimap(Func1 keySelector, Func1 valueSelector) { + public final Ix>> collectToMultimap(IxFunction keySelector, IxFunction valueSelector) { return new IxToMultimap(this, keySelector, valueSelector); } - + /** * Collects the elements of this sequence into a Set. *

@@ -889,36 +884,36 @@ public final Ix> collectToSet() { * with this Ix instance and emits the elements of the returned Iterable. *

* The result's iterator() forwards the call remove() to the returned Iterable's Iterator. - * + * * @param the result value type * @param transformer the transformer called with this Ix when Ix.iterator() is invoked * @return the new Ix instance * @throws NullPointerException if transformer is null * @since 1.0 */ - public final Ix compose(Func1, ? extends Iterable> transformer) { + public final Ix compose(IxFunction, ? extends Iterable> transformer) { return new IxCompose(this, nullCheck(transformer, "transformer is null")); } - + /** - * Maps each element from this sequence into subsequent Iterable sequences whose elmenents are + * Maps each element from this sequence into subsequent Iterable sequences whose elements are * concatenated in order. *

* Note that flatMap and concatMap operations are the same in the Iterable world. *

* The result's iterator() forwards the call remove() to the current inner Iterator. - * + * * @param the result value type - * @param mapper the function + * @param mapper the function * @return the new Ix instance * @throws NullPointerException if mapper is null * @since 1.0 - * @see #flatMap(Func1) + * @see #flatMap(IxFunction) */ - public final Ix concatMap(Func1> mapper) { + public final Ix concatMap(IxFunction> mapper) { return new IxFlattenIterable(this, nullCheck(mapper, "mapper is null")); } - + /** * Emits elements of this sequence followed by the elements of the other sequence. *

@@ -934,7 +929,7 @@ public final Ix concatMap(Func1 concatWith(Iterable other) { return concat(this, other); } - + /** * Emits true if the sequence contains the given Object, compared via null-safe * equals. @@ -947,7 +942,7 @@ public final Ix concatWith(Iterable other) { public final Ix contains(Object o) { return new IxContains(this, o); } - + /** * Emits the number of elements in this sequence. *

@@ -981,7 +976,7 @@ public final Ix countLong() { public final Ix defaultIfEmpty(T value) { return switchIfEmpty(Ix.just(value)); } - + /** * Emits only distinct, never before seen elements (according to null-safe equals()) * of this sequence. @@ -998,7 +993,7 @@ public final Ix distinct() { } /** - * Emits only distinct, never before seen keys extracted from elements + * Emits only distinct, never before seen keys extracted from elements * (according to null-safe equals()) of this sequence. *

* Note that this operator uses a memory of seen elements which may grow unbounded @@ -1012,7 +1007,7 @@ public final Ix distinct() { * @throws NullPointerException if keySelector is null * @since 1.0 */ - public final Ix distinct(Func1 keySelector) { + public final Ix distinct(IxFunction keySelector) { return new IxDistinct(this, nullCheck(keySelector, "keySelector is null")); } @@ -1039,13 +1034,13 @@ public final Ix distinctUntilChanged() { * @throws NullPointerException if comparer is null * @since 1.0 */ - public final Ix distinctUntilChanged(Pred2 comparer) { + public final Ix distinctUntilChanged(IxPredicate2 comparer) { return new IxDistinctUntilChanged(this, IdentityHelper.instance(), nullCheck(comparer, "comparer is null")); } /** * Emits elements from this sequence if each element is different from the previous element - * (according to a null-safe equals() of the extracted key), dropping elements that evaluate + * (according to a null-safe equals() of the extracted key), dropping elements that evaluate * to the same as the previous. *

* The result's iterator() doesn't support remove(). @@ -1056,10 +1051,10 @@ public final Ix distinctUntilChanged(Pred2 comparer) { * @throws NullPointerException if comparer is null * @since 1.0 */ - public final Ix distinctUntilChanged(Func1 keySelector) { + public final Ix distinctUntilChanged(IxFunction keySelector) { return new IxDistinctUntilChanged(this, keySelector, EqualityHelper.INSTANCE); } - + /** * Calls the given action just before when the consumer calls next() of this Ix.iterator(). *

@@ -1069,7 +1064,7 @@ public final Ix distinctUntilChanged(Func1 keySelector) { * @throws NullPointerException if action is null * @since 1.0 */ - public final Ix doOnNext(Action1 action) { + public final Ix doOnNext(IxConsumer action) { return new IxDoOn(this, nullCheck(action, "action is null"), IxEmptyAction.instance0()); } @@ -1083,7 +1078,7 @@ public final Ix doOnNext(Action1 action) { * @throws NullPointerException if action is null * @since 1.0 */ - public final Ix doOnCompleted(Action0 action) { + public final Ix doOnCompleted(Runnable action) { return new IxDoOn(this, IxEmptyAction.instance1(), nullCheck(action, "action is null")); } @@ -1099,9 +1094,9 @@ public final Ix doOnCompleted(Action0 action) { public final Ix endWith(T... values) { return concat(this, fromArray(values)); } - + /** - * Emits distinct elements from this and the other Iterable which are not + * Emits distinct elements from this and the other Iterable which are not * in the other sequence (i.e., (A union B) minus (A intersection B)). *

* The result's iterator() doesn't support remove(). @@ -1115,40 +1110,40 @@ public final Ix endWith(T... values) { public final Ix except(Iterable other) { return new IxExcept(this, nullCheck(other, "other is null")); } - + /** * Emits elements of this sequence which match the given predicate only. *

* The result's iterator() forwards the call to remove() to this' Iterator. * @param predicate the predicate receiving the current element and if it - * returns true, the value is emitted, ingored otherwise. + * returns true, the value is emitted, ignored otherwise. * @return the new Ix instance * @throws NullPointerException if predicate is null * @since 1.0 */ - public final Ix filter(Pred predicate) { + public final Ix filter(IxPredicate predicate) { return new IxFilter(this, nullCheck(predicate, "predicate is null")); } - + /** - * Maps each element from this sequence into subsequent Iterable sequences whose elmenents are + * Maps each element from this sequence into subsequent Iterable sequences whose elements are * concatenated in order. *

* Note that flatMap and concatMap operations are the same in the Iterable world. *

* The result's iterator() forwards the call remove() to the current inner Iterator. - * + * * @param the result value type - * @param mapper the function + * @param mapper the function * @return the new Ix instance * @throws NullPointerException if mapper is null * @since 1.0 - * @see #concatMap(Func1) + * @see #concatMap(IxFunction) */ - public final Ix flatMap(Func1> mapper) { + public final Ix flatMap(IxFunction> mapper) { return new IxFlattenIterable(this, mapper); } - + /** * Groups elements of this sequence into distinct groups keyed by the keys returned by the keySelector. *

@@ -1162,14 +1157,14 @@ public final Ix flatMap(Func1> * @return the new Ix instance * @throws NullPointerException if keySelector is null * @since 1.0 - * @see #groupBy(Func1, Func1) + * @see #groupBy(IxFunction, IxFunction) */ - public final Ix> groupBy(Func1 keySelector) { + public final Ix> groupBy(IxFunction keySelector) { return groupBy(keySelector, IdentityHelper.instance()); } /** - * Groups mapped elements (by the valueSelector) of this sequence into distinct groups + * Groups mapped elements (by the valueSelector) of this sequence into distinct groups * keyed by the keys returned by the keySelector. *

* The operator doesn't lose data and calling hasNext/next on either the returned Ix or on the inner @@ -1181,14 +1176,14 @@ public final Ix> groupBy(Func1 keySe * @param keySelector the function receiving the current element and returns the key to be used for * grouping the values into the same inner GroupedIx. * @param valueSelector the function receiving the current element and returns the value to be emitted - * by the appropriate group + * by the appropriate group * @return the new Ix instance * @throws NullPointerException if keySelector or valueSelector is null * @since 1.0 - * @see #groupBy(Func1, Func1) + * @see #groupBy(IxFunction, IxFunction) */ - public final Ix> groupBy(Func1 keySelector, - Func1 valueSelector) { + public final Ix> groupBy(IxFunction keySelector, + IxFunction valueSelector) { return new IxGroupBy(this, nullCheck(keySelector, "keySelector is null"), nullCheck(valueSelector, "valueSelector is null")); } @@ -1202,9 +1197,9 @@ public final Ix> groupBy(Func1 ke public final Ix hasElements() { return new IxHasElements(this); } - + /** - * Hides the identity of this Ix instance and prevents certain identity-based optimiziations. + * Hides the identity of this Ix instance and prevents certain identity-based optimizations. *

* The result's iterator() forwards the remove() calls to this' Iterator. * @return the new Ix instance @@ -1213,7 +1208,7 @@ public final Ix hasElements() { public final Ix hide() { return new IxWrapper(this); } - + /** * Emits distinct values of this and the other Iterables that are present in * both sequences. @@ -1229,7 +1224,7 @@ public final Ix hide() { public final Ix intersect(Iterable other) { return new IxIntersect(this, nullCheck(other, "other is null")); } - + /** * Runs through this sequence, ignoring all values until this sequence completes. *

@@ -1240,7 +1235,7 @@ public final Ix intersect(Iterable other) { public final Ix ignoreElements() { return new IxIgnoreElements(this); } - + /** * Converts elements of this sequence to String and concatenates them into * a single, comma separated String. @@ -1252,7 +1247,7 @@ public final Ix ignoreElements() { public final Ix join() { return join(", "); } - + /** * Converts elements of this sequence to String and concatenates them into * a single String separated by the given character sequence. @@ -1265,7 +1260,7 @@ public final Ix join() { public final Ix join(CharSequence separator) { return new IxJoin(this, separator); } - + /** * Calls the given lifter function with the iterator of this sequence and emits * elements of the returned Iterator. @@ -1278,10 +1273,10 @@ public final Ix join(CharSequence separator) { * @throws NullPointerException if lifter is null * @since 1.0 */ - public final Ix lift(Func1, ? extends Iterator> lifter) { + public final Ix lift(IxFunction, ? extends Iterator> lifter) { return new IxLift(this, nullCheck(lifter, "lifter is null")); } - + /** * Maps each element of this sequence to some other value. *

@@ -1293,10 +1288,10 @@ public final Ix lift(Func1, ? extends Iterator> li * @throws NullPointerException if mapper is null * @since 1.0 */ - public final Ix map(Func1 mapper) { + public final Ix map(IxFunction mapper) { return new IxMap(this, mapper); } - + /** * Emits the first maximum element according to the given comparator. *

@@ -1316,7 +1311,7 @@ public final Ix max(Comparator comparator) { /** * Emits the first maximum element according to their natural order. *

- * The sequence may throw a ClassCastException if any of the elements is + * The sequence may throw a ClassCastException if any of the elements is * not self-comparable (i.e., doesn't implement the Comparable interface). *

* The result's iterator() doesn't support remove(). @@ -1328,7 +1323,7 @@ public final Ix max(Comparator comparator) { public final Ix max() { return max((Comparator)SelfComparator.INSTANCE); } - + /** * Returns the first maximum integer value. *

@@ -1394,7 +1389,7 @@ public final Ix min(Comparator comparator) { /** * Emits the first minimum element according to their natural order. *

- * The sequence may throw a ClassCastException if any of the element is + * The sequence may throw a ClassCastException if any of the element is * not self-comparable (i.e., doesn't implement the Comparable interface). *

* The result's iterator() doesn't support remove(). @@ -1436,7 +1431,7 @@ public final Ix minInt() { public final Ix minLong() { return new IxMinLong((Ix)this); } - + /** * Orders elements according to their natural order. *

@@ -1453,7 +1448,7 @@ public final Ix minLong() { public final Ix orderBy() { return orderBy((Comparator)SelfComparator.INSTANCE); } - + /** * Orders elements according to the comparator. *

@@ -1470,7 +1465,7 @@ public final Ix orderBy() { public final Ix orderBy(Comparator comparator) { return new IxOrderBy(this, IdentityHelper.instance(), nullCheck(comparator, "comparator is null"), 1); } - + /** * Orders elements according to the natural order of the extracted keys from these elements. *

@@ -1480,9 +1475,9 @@ public final Ix orderBy(Comparator comparator) { * @return the new Ix instance * @throws NullPointerException if keySelector is null * @since 1.0 - * @see #orderByReverse(Func1) + * @see #orderByReverse(IxFunction) */ - public final > Ix orderBy(Func1 keySelector) { + public final > Ix orderBy(IxFunction keySelector) { return new IxOrderBy(this, nullCheck(keySelector, "keySelector is null"), SelfComparator.INSTANCE, 1); } @@ -1502,7 +1497,7 @@ public final > Ix orderBy(Func1 public final Ix orderByReverse() { return orderByReverse((Comparator)SelfComparator.INSTANCE); } - + /** * Orders elements according to the reversed comparator. *

@@ -1519,7 +1514,7 @@ public final Ix orderByReverse() { public final Ix orderByReverse(Comparator comparator) { return new IxOrderBy(this, IdentityHelper.instance(), nullCheck(comparator, "comparator is null"), -1); } - + /** * Orders elements according to the reverse natural order of the extracted keys from these elements. *

@@ -1529,9 +1524,9 @@ public final Ix orderByReverse(Comparator comparator) { * @return the new Ix instance * @throws NullPointerException if keySelector is null * @since 1.0 - * @see #orderByReverse(Func1) + * @see #orderByReverse(IxFunction) */ - public final > Ix orderByReverse(Func1 keySelector) { + public final > Ix orderByReverse(IxFunction keySelector) { return new IxOrderBy(this, nullCheck(keySelector, "keySelector is null"), SelfComparator.INSTANCE, -1); } @@ -1560,10 +1555,10 @@ public final Ix publish() { * @throws NullPointerException if transform is null * @since 1.0 */ - public final Ix publish(Func1, ? extends Iterable> transform) { - return new IxPublishSelector(this, nullCheck(transform, "transfrom is null")); + public final Ix publish(IxFunction, ? extends Iterable> transform) { + return new IxPublishSelector(this, nullCheck(transform, "transform is null")); } - + /** * Reduces the elements of this sequence into a single value via a reducer function. *

@@ -1573,12 +1568,12 @@ public final Ix publish(Func1, ? extends Iterable reduce(Func2 reducer) { + public final Ix reduce(IxFunction2 reducer) { return new IxAggregate(this, nullCheck(reducer, "reducer is null")); } - + /** * Given a per-iterator() initial value, reduces the elements of this sequence into a single * value via a reducer function. @@ -1592,12 +1587,12 @@ public final Ix reduce(Func2 reducer) { * @return the new Ix instance * @throws NullPointerException if initialFactory or reducer is null * @since 1.0 - * @see #reduce(Func2) + * @see #reduce(IxFunction2) */ - public final Ix reduce(Func0 initialFactory, Func2 reducer) { + public final Ix reduce(IxSupplier initialFactory, IxFunction2 reducer) { return new IxReduce(this, initialFactory, reducer); } - + /** * Removes those elements via Iterator.remove() from this sequence that match the * given predicate. @@ -1608,12 +1603,12 @@ public final Ix reduce(Func0 initialFactory, Func2 reducer) { * @return the new Ix instance * @throws NullPointerException if predicate is null * @since 1.0 - * @see #retain(Pred) + * @see #retain(IxPredicate) */ - public final Ix remove(Pred predicate) { + public final Ix remove(IxPredicate predicate) { return new IxRemove(this, nullCheck(predicate, "predicate is null")); } - + /** * Repeats this sequence indefinitely. *

@@ -1624,7 +1619,7 @@ public final Ix remove(Pred predicate) { public final Ix repeat() { return concat(repeatValue(this)); } - + /** * Repeats this sequence at most the given number of times. *

A count of zero will yield an empty sequence, a count of one @@ -1639,7 +1634,7 @@ public final Ix repeat() { public final Ix repeat(long times) { return concat(repeatValue(this, times)); } - + /** * Repeats this sequence if the given predicate returns true after the sequence * completes in a round. @@ -1651,7 +1646,7 @@ public final Ix repeat(long times) { * @throws NullPointerException if stopPredicate is null * @since 1.0 */ - public final Ix repeat(Pred0 stopPredicate) { + public final Ix repeat(IxBooleanSupplier stopPredicate) { return concat(repeatValue(this, stopPredicate)); } @@ -1671,7 +1666,7 @@ public final Ix repeat(Pred0 stopPredicate) { * @throws NullPointerException if stopPredicate is null * @since 1.0 */ - public final Ix repeat(long times, Pred0 stopPredicate) { + public final Ix repeat(long times, IxBooleanSupplier stopPredicate) { return concat(repeatValue(this, times, stopPredicate)); } @@ -1714,7 +1709,7 @@ public final Ix replay(int size) { * @throws NullPointerException if transform is null * @since 1.0 */ - public final Ix replay(Func1, ? extends Iterable> transform) { + public final Ix replay(IxFunction, ? extends Iterable> transform) { return new IxReplaySelector(this, nullCheck(transform, "transform is null")); } @@ -1735,7 +1730,7 @@ public final Ix replay(Func1, ? extends Iterable Ix replay(int size, Func1, ? extends Iterable> transform) { + public final Ix replay(int size, IxFunction, ? extends Iterable> transform) { return new IxReplaySizeSelector(this, positive(size, "size"), nullCheck(transform, "transform is null")); } @@ -1749,12 +1744,12 @@ public final Ix replay(int size, Func1, ? extends Iterable< * @return the new Ix instance * @throws NullPointerException if predicate is null * @since 1.0 - * @see #remove(Pred) + * @see #remove(IxPredicate) */ - public final Ix retain(Pred predicate) { + public final Ix retain(IxPredicate predicate) { return new IxRetain(this, nullCheck(predicate, "predicate is null")); } - + /** * Plays this sequence in reverse. *

@@ -1780,7 +1775,7 @@ public final Ix reverse() { * @throws NullPointerException if scanner is null * @since 1.0 */ - public final Ix scan(Func2 scanner) { + public final Ix scan(IxFunction2 scanner) { return new IxScan(this, nullCheck(scanner, "scanner is null")); } @@ -1797,10 +1792,10 @@ public final Ix scan(Func2 scanner) { * @throws NullPointerException if initialFactory or scanner is null * @since 1.0 */ - public final Ix scan(Func0 initialFactory, Func2 scanner) { + public final Ix scan(IxSupplier initialFactory, IxFunction2 scanner) { return new IxScanSeed(this, nullCheck(initialFactory, "initialFactory is null"), nullCheck(scanner, "scanner is null")); } - + /** * Determines if two sequences have the same elements in the same order and are the same length based * on null-safe object equality. @@ -1827,7 +1822,7 @@ public final Ix sequenceEqual(Iterable other) { * @throws NullPointerException if other is null * @since 1.0 */ - public final Ix sequenceEqual(Iterable other, Pred2 comparer) { + public final Ix sequenceEqual(Iterable other, IxPredicate2 comparer) { return new IxSequenceEqual(this, nullCheck(other, "other is null"), nullCheck(comparer, "comparer is null")); } @@ -1873,12 +1868,12 @@ public final Ix skipLast(int n) { * @return the new Ix instance * @throws NullPointerException if predicate is null * @since 1.0 - * @see #takeWhile(Pred) + * @see #takeWhile(IxPredicate) */ - public final Ix skipWhile(Pred predicate) { + public final Ix skipWhile(IxPredicate predicate) { return new IxSkipWhile(this, nullCheck(predicate, "predicate is null")); } - + /** * Emits elements of the given array followed by the elements of this sequence. *

@@ -1925,11 +1920,11 @@ public final Ix sumInt() { public final Ix sumLong() { return new IxSumLong((Ix)this); } - + /** * Emits the elements of the other sequence if this sequence is empty. *

- * The result's Iterator forwards calls of remove() to this' or the other's Iterator. + * The result's Iterator forwards calls of remove() to this' or the other's Iterator. * @param other the other Iterable instance, not null * @return the new Ix instance * @throws NullPointerException if other is null @@ -1942,7 +1937,7 @@ public final Ix switchIfEmpty(Iterable other) { /** * Emits the first n elements (or less) of this sequence. *

- * The result's Iterator forwards calls of remove() to this' Iterator. + * The result's Iterator forwards calls of remove() to this' Iterator. * @param n the number of items to emit at most, non-negative * @return the new Ix instance * @throws IllegalArgumentException if n is negative @@ -1952,7 +1947,7 @@ public final Ix switchIfEmpty(Iterable other) { public final Ix take(int n) { return new IxTake(this, nonNegative(n, "n")); } - + /** * Emits the last n elements (or fewer) of this sequence. *

@@ -1966,45 +1961,45 @@ public final Ix take(int n) { public final Ix takeLast(int n) { return new IxTakeLast(this, nonNegative(n, "n")); } - + /** - * Take elements from this sequence while the given predicate returns true + * Take elements from this sequence while the given predicate returns true * for the current element (checked after emission of that element). *

- * The result's Iterator forwards calls of remove() to this' Iterator. + * The result's Iterator forwards calls of remove() to this' Iterator. * @param stopPredicate the function receiving the current element and returns * true if no further elements should be emitted after this element. * @return the new Ix instance * @throws NullPointerException if stopPredicate is null * @since 1.0 */ - public final Ix takeUntil(Pred stopPredicate) { + public final Ix takeUntil(IxPredicate stopPredicate) { return new IxTakeUntil(this, nullCheck(stopPredicate, "stopPredicate is null")); } - + /** - * Take elements from this sequence until the given predicate returns true + * Take elements from this sequence until the given predicate returns true * for the current element (checked before emission of that element). *

- * The result's Iterator forwards calls of remove() to this' Iterator. + * The result's Iterator forwards calls of remove() to this' Iterator. * @param predicate the function receiving the current element and returns * false if no further elements should be emitted (not even the current). * @return the new Ix instance * @throws NullPointerException if predicate is null * @since 1.0 */ - public final Ix takeWhile(Pred predicate) { + public final Ix takeWhile(IxPredicate predicate) { return new IxTakeWhile(this, nullCheck(predicate, "predicate is null")); } - - + + /** * Maps this sequence of numbers into a sequence of longs. *

* The sequence may throw a ClassCastException if any of the elements * is not a subclass of Number. *

- * The result's Iterator forwards calls of remove() to this' Iterator. + * The result's Iterator forwards calls of remove() to this' Iterator. * @return the new Ix instance * @since 1.0 */ @@ -2027,7 +2022,7 @@ public final Ix toLong() { public final Ix transform(IxTransform transformer) { return new IxTransformer(this, nullCheck(transformer, "transformer is null")); } - + /** * Emits a distinct set of values from both this and the other sequence. *

@@ -2044,9 +2039,9 @@ public final Ix union(Iterable other) { } /** - * Emits inner Ix Iterables of non-overapping sequences mapped from this sequence + * Emits inner Ix Iterables of non-overlapping sequences mapped from this sequence * with the given maximum size each. - * + * *

* The result's and the inner Ix' iterator() don't support remove(). * @param size the maximum size of the inner windows, positive @@ -2064,7 +2059,7 @@ public final Ix> window(int size) { * sequence with the given maximum size each and started each {@code skip} source elements. * @param size the maximum size of the inner windows, positive * @param skip after how many elements to start a new window (repeatedly), positive - * @return the new Ix Iinstance + * @return the new Ix instance * @throws IllegalArgumentException if size or skip is non-positive * @since 1.0 * @see #window(int) @@ -2078,23 +2073,23 @@ public final Ix> window(int size, int skip) { } return new IxWindowOverlap(this, positive(size, "size"), positive(skip, "skip")); } - + /** * Combines the next element from this and the other source Iterable via a zipper function. *

* If one of the source Iterables is sorter the sequence terminates eagerly. *

* The result's iterator() doesn't support remove(). - * + * * @param the other source's element type * @param the result value type * @param other the the other source Iterable - * @param zipper the function that takesone from each source, not null + * @param zipper the function that takes one from each source, not null * @return the new Ix instance * @throws NullPointerException if other or zipper is null * @since 1.0 */ - public final Ix zipWith(Iterable other, Func2 zipper) { + public final Ix zipWith(Iterable other, IxFunction2 zipper) { return zip(this, other, zipper); } @@ -2138,17 +2133,17 @@ public final T first(T defaultValue) { } return defaultValue; } - + /** * Consumes the entire sequence and calls the given action with each value. * @param action the action to call * @throws NullPointerException if action is null * @since 1.0 - * @see #foreachWhile(Pred) + * @see #foreachWhile(IxPredicate) */ - public final void foreach(Action1 action) { + public final void foreach(IxConsumer action) { for (T t : this) { - action.call(t); + action.accept(t); } } @@ -2159,9 +2154,9 @@ public final void foreach(Action1 action) { * return true to continue the loop or false to quit the loop. * @throws NullPointerException if action is null * @since 1.0 - * @see #foreach(Action1) + * @see #foreach(IxConsumer) */ - public final void foreachWhile(Pred predicate) { + public final void foreachWhile(IxPredicate predicate) { for (T t : this) { if (!predicate.test(t)) { break; @@ -2201,7 +2196,7 @@ public final T last() { if (!it.hasNext()) { throw new NoSuchElementException(); } - + for (;;) { T t = it.next(); if (!it.hasNext()) { @@ -2209,7 +2204,7 @@ public final T last() { } } } - + /** * Returns the last element of this sequence or the defaultValue if * this sequence is empty. @@ -2228,7 +2223,7 @@ public final T last(T defaultValue) { if (!it.hasNext()) { return defaultValue; } - + for (;;) { T t = it.next(); if (!it.hasNext()) { @@ -2256,9 +2251,9 @@ public final void print() { public final void print(CharSequence separator, int charsPerLine) { boolean first = true; int len = 0; - + for (T v : this) { - + String s = String.valueOf(v); if (first) { @@ -2277,7 +2272,7 @@ public final void print(CharSequence separator, int charsPerLine) { len += s.length(); } } - + } } @@ -2301,7 +2296,7 @@ public final void println(CharSequence prefix) { System.out.print(prefix); System.out.println(v); } - } + } /** * Removes all elements by repeatedly calling this sequence's Iterator.remove(). */ @@ -2323,11 +2318,11 @@ public final void removeAll() { * for elements to keep. * @throws UnsupportedOperationException if the this Iterable * doesn't allow removing elements. - * @see #retainAll(Pred) + * @see #retainAll(IxPredicate) * @see #removeAll() * @since 1.0 */ - public final void removeAll(Pred predicate) { + public final void removeAll(IxPredicate predicate) { Iterator it = iterator(); while (it.hasNext()) { T v = it.next(); @@ -2346,10 +2341,10 @@ public final void removeAll(Pred predicate) { * for elements to remove. * @throws UnsupportedOperationException if the this Iterable * doesn't allow removing elements. - * @see #removeAll(Pred) + * @see #removeAll(IxPredicate) * @since 1.0 */ - public final void retainAll(Pred predicate) { + public final void retainAll(IxPredicate predicate) { Iterator it = iterator(); while (it.hasNext()) { T v = it.next(); @@ -2391,10 +2386,10 @@ public final T single() { } throw new NoSuchElementException("The source is empty."); } - + /** - * Returns the single element of this sequence, defalutValue + * Returns the single element of this sequence, defaultValue * if this sequence is empty or IndexOutOfBoundsException if this sequence has more * than one element * @param defaultValue the value to return if this sequence is empty @@ -2430,9 +2425,9 @@ public final void subscribe() { * @throws NullPointerException if consumer is null * @since 1.0 */ - public final void subscribe(Action1 onNext) { + public final void subscribe(IxConsumer onNext) { for (T v : this) { - onNext.call(v); + onNext.accept(v); } } @@ -2441,18 +2436,17 @@ public final void subscribe(Action1 onNext) { * each element and calls the onError with any exception thrown by the iteration * or the onNext action. * @param onNext the consumer to call with each element - * @param onError the consumer to call with the exception thrown + * @param onError the consumer to call with the exception thrown * @throws NullPointerException if onError is null * @since 1.0 */ - public final void subscribe(Action1 onNext, Action1 onError) { + public final void subscribe(IxConsumer onNext, IxConsumer onError) { try { for (T v : this) { - onNext.call(v); + onNext.accept(v); } } catch (Throwable ex) { - Exceptions.throwIfFatal(ex); - onError.call(ex); + onError.accept(ex); } } @@ -2463,71 +2457,22 @@ public final void subscribe(Action1 onNext, Action1 onErro * without exception. * @param onNext the consumer to call with each element * @param onError the consumer to call with the exception thrown - * @param onCompleted the action called after the sequence has been consumed + * @param onCompleted the action called after the sequence has been consumed * @throws NullPointerException if onError or onCompleted is null * @since 1.0 */ - public final void subscribe(Action1 onNext, Action1 onError, Action0 onCompleted) { + public final void subscribe(IxConsumer onNext, IxConsumer onError, Runnable onCompleted) { try { for (T v : this) { - onNext.call(v); + onNext.accept(v); } } catch (Throwable ex) { - Exceptions.throwIfFatal(ex); - onError.call(ex); + onError.accept(ex); return; } - onCompleted.call(); + onCompleted.run(); } - /** - * Consumes this sequence and calls the appropriate onXXX method on the given Observer instance. - * @param observer the observer to forward values, error or completion to. - * @throws NullPointerException if observer is null - * @since 1.0 - */ - public final void subscribe(Observer observer) { - try { - for (T v : this) { - observer.onNext(v); - } - } catch (Throwable ex) { - Exceptions.throwIfFatal(ex); - observer.onError(ex); - return; - } - observer.onCompleted(); - } - - /** - * Consumes this sequence and calls the appropriate onXXX method on the given Subscriber instance - * as long as it has not unsubscribed. - * @param subscriber the subscriber to forward values, error or completion to. - * @throws NullPointerException if subscriber is null - * @since 1.0 - */ - public final void subscribe(Subscriber subscriber) { - try { - for (T v : this) { - if (subscriber.isUnsubscribed()) { - return; - } - subscriber.onNext(v); - } - } catch (Throwable ex) { - Exceptions.throwIfFatal(ex); - if (subscriber.isUnsubscribed()) { - return; - } - subscriber.onError(ex); - return; - } - if (subscriber.isUnsubscribed()) { - return; - } - subscriber.onCompleted(); - } - /** * Collects the elements of this sequence into an Object array. *

@@ -2574,7 +2519,7 @@ public final List toList() { * @throws NullPointerException if keySelector is null * @since 1.0 */ - public final Map toMap(Func1 keySelector) { + public final Map toMap(IxFunction keySelector) { return collectToMap(keySelector).first(); } @@ -2594,7 +2539,7 @@ public final Map toMap(Func1 keySelector) { * @throws NullPointerException if keySelector or valueSelector is null * @since 1.0 */ - public final Map toMap(Func1 keySelector, Func1 valueSelector) { + public final Map toMap(IxFunction keySelector, IxFunction valueSelector) { return collectToMap(keySelector, valueSelector).first(); } @@ -2609,7 +2554,7 @@ public final Map toMap(Func1 keySelector, F * @throws NullPointerException if keySelector is null * @since 1.0 */ - public final Map> toMultimap(Func1 keySelector) { + public final Map> toMultimap(IxFunction keySelector) { return collectToMultimap(keySelector).first(); } @@ -2628,10 +2573,10 @@ public final Map> toMultimap(Func1 * @throws NullPointerException if keySelector or valueSelector is null * @since 1.0 */ - public final Map> toMultimap(Func1 keySelector, Func1 valueSelector) { + public final Map> toMultimap(IxFunction keySelector, IxFunction valueSelector) { return collectToMultimap(keySelector, valueSelector).first(); } - + /** * Collects the elements of this sequence into a Set. *

@@ -2646,7 +2591,7 @@ public final Set toSet() { // -------------------------------------------------------------------------------------------- // Helper methods // -------------------------------------------------------------------------------------------- - + /** * Checks if the value is null and if so, throws * a NullPointerException with the given message. @@ -2661,7 +2606,7 @@ protected static U nullCheck(U value, String message) { } return value; } - + /** * Calls the given callable and rethrows its exception * (as RuntimeException if necessary). @@ -2682,10 +2627,10 @@ protected static U checkedCall(Callable callable) { throw new RuntimeException(ex); } } - + /** * Checks if the given value is non-negative and returns it; throws - * an IllegalArgumentException otherwise + * an IllegalArgumentException otherwise. * @param n the number to check * @param name the name of the parameter * @return n @@ -2696,10 +2641,10 @@ protected static long nonNegative(long n, String name) { } return n; } - + /** * Checks if the given value is non-negative and returns it; throws - * an IllegalArgumentException otherwise + * an IllegalArgumentException otherwise. * @param n the number to check * @param name the name of the parameter * @return n @@ -2713,7 +2658,7 @@ protected static int nonNegative(int n, String name) { /** * Checks if the given value is positive and returns it; throws - * an IllegalArgumentException otherwise + * an IllegalArgumentException otherwise. * @param n the number to check * @param name the name of the parameter * @return n diff --git a/src/main/java/ix/IxAggregate.java b/src/main/java/ix/IxAggregate.java index 3749c4b..2a4b255 100644 --- a/src/main/java/ix/IxAggregate.java +++ b/src/main/java/ix/IxAggregate.java @@ -18,13 +18,11 @@ import java.util.Iterator; -import rx.functions.Func2; - final class IxAggregate extends IxSource { - final Func2 aggregator; - - public IxAggregate(Iterable source, Func2 aggregator) { + final IxFunction2 aggregator; + + IxAggregate(Iterable source, IxFunction2 aggregator) { super(source); this.aggregator = aggregator; } @@ -33,12 +31,12 @@ public IxAggregate(Iterable source, Func2 aggregator) { public Iterator iterator() { return new AggregateIterator(source.iterator(), aggregator); } - + static final class AggregateIterator extends IxSourceIterator { - - final Func2 aggregator; - - public AggregateIterator(Iterator it, Func2 aggregator) { + + final IxFunction2 aggregator; + + AggregateIterator(Iterator it, IxFunction2 aggregator) { super(it); this.aggregator = aggregator; } @@ -46,12 +44,12 @@ public AggregateIterator(Iterator it, Func2 aggregator) { @Override protected boolean moveNext() { Iterator it = this.it; - Func2 f = aggregator; - + IxFunction2 f = aggregator; + if (it.hasNext()) { T acc = it.next(); while (it.hasNext()) { - acc = f.call(acc, it.next()); + acc = f.apply(acc, it.next()); } value = acc; hasValue = true; diff --git a/src/main/java/ix/IxAll.java b/src/main/java/ix/IxAll.java index be72ccb..ceb6fd4 100644 --- a/src/main/java/ix/IxAll.java +++ b/src/main/java/ix/IxAll.java @@ -20,46 +20,46 @@ final class IxAll extends IxSource { - final Pred predicate; - - public IxAll(Iterable source, Pred predicate) { + final IxPredicate predicate; + + IxAll(Iterable source, IxPredicate predicate) { super(source); this.predicate = predicate; } - + @Override public Iterator iterator() { return new AllIterator(source.iterator(), predicate); } - + static final class AllIterator extends IxSourceIterator { - final Pred predicate; + final IxPredicate predicate; - public AllIterator(Iterator it, Pred predicate) { + AllIterator(Iterator it, IxPredicate predicate) { super(it); this.predicate = predicate; } - + @Override protected boolean moveNext() { Iterator it = this.it; - Pred pred = predicate; - + IxPredicate p = predicate; + while (it.hasNext()) { - if (!pred.test(it.next())) { + if (!p.test(it.next())) { hasValue = true; value = false; done = true; return true; } } - + hasValue = true; value = true; done = true; return true; } - + } } diff --git a/src/main/java/ix/IxAny.java b/src/main/java/ix/IxAny.java index 201ddf3..9589936 100644 --- a/src/main/java/ix/IxAny.java +++ b/src/main/java/ix/IxAny.java @@ -20,46 +20,46 @@ final class IxAny extends IxSource { - final Pred predicate; - - public IxAny(Iterable source, Pred predicate) { + final IxPredicate predicate; + + IxAny(Iterable source, IxPredicate predicate) { super(source); this.predicate = predicate; } - + @Override public Iterator iterator() { return new AnyIterator(source.iterator(), predicate); } - + static final class AnyIterator extends IxSourceIterator { - final Pred predicate; + final IxPredicate predicate; - public AnyIterator(Iterator it, Pred predicate) { + AnyIterator(Iterator it, IxPredicate predicate) { super(it); this.predicate = predicate; } - + @Override protected boolean moveNext() { Iterator it = this.it; - Pred pred = predicate; - + IxPredicate p = predicate; + while (it.hasNext()) { - if (pred.test(it.next())) { + if (p.test(it.next())) { hasValue = true; value = true; done = true; return true; } } - + hasValue = true; value = false; done = true; return true; } - + } } diff --git a/src/main/java/ix/IxAverageDouble.java b/src/main/java/ix/IxAverageDouble.java index 6de30b6..b51b692 100644 --- a/src/main/java/ix/IxAverageDouble.java +++ b/src/main/java/ix/IxAverageDouble.java @@ -20,7 +20,7 @@ final class IxAverageDouble extends IxSource { - public IxAverageDouble(Iterable source) { + IxAverageDouble(Iterable source) { super(source); } @@ -31,7 +31,7 @@ public Iterator iterator() { static final class AverageFloatIterator extends IxSourceIterator { - public AverageFloatIterator(Iterator it) { + AverageFloatIterator(Iterator it) { super(it); } @@ -41,17 +41,17 @@ protected boolean moveNext() { double accumulator = 0f; long count = 0; - + if (!it.hasNext()) { done = true; return false; } - + do { accumulator += it.next().doubleValue(); count++; } while (it.hasNext()); - + value = accumulator / count; hasValue = true; done = true; diff --git a/src/main/java/ix/IxAverageFloat.java b/src/main/java/ix/IxAverageFloat.java index cd3f05e..8cf3664 100644 --- a/src/main/java/ix/IxAverageFloat.java +++ b/src/main/java/ix/IxAverageFloat.java @@ -20,7 +20,7 @@ final class IxAverageFloat extends IxSource { - public IxAverageFloat(Iterable source) { + IxAverageFloat(Iterable source) { super(source); } @@ -31,7 +31,7 @@ public Iterator iterator() { static final class AverageFloatIterator extends IxSourceIterator { - public AverageFloatIterator(Iterator it) { + AverageFloatIterator(Iterator it) { super(it); } @@ -41,17 +41,17 @@ protected boolean moveNext() { float accumulator = 0f; int count = 0; - + if (!it.hasNext()) { done = true; return false; } - + do { accumulator += it.next().floatValue(); count++; } while (it.hasNext()); - + value = accumulator / count; hasValue = true; done = true; diff --git a/src/main/java/ix/IxBaseIterator.java b/src/main/java/ix/IxBaseIterator.java index b17930c..d46d00a 100644 --- a/src/main/java/ix/IxBaseIterator.java +++ b/src/main/java/ix/IxBaseIterator.java @@ -25,13 +25,13 @@ * @param the result value type */ public abstract class IxBaseIterator implements Iterator { - - /** Inidicates a value is available for consumption. */ + + /** Indicates a value is available for consumption. */ protected boolean hasValue; - + /** Indicates there are no more data available. */ protected boolean done; - + /** The current value if hasValue is true. */ protected R value; @@ -40,7 +40,7 @@ public abstract class IxBaseIterator implements Iterator { * @return what the hasNext should return */ protected abstract boolean moveNext(); - + @Override public final boolean hasNext() { boolean b = hasValue; @@ -51,7 +51,7 @@ public final boolean hasNext() { } return b; } - + @Override public final R next() { if (!hasValue && !hasNext()) { @@ -62,7 +62,7 @@ public final R next() { value = null; return v; } - + @Override public void remove() { throw new UnsupportedOperationException(); diff --git a/src/main/java/ix/Pred0.java b/src/main/java/ix/IxBooleanSupplier.java similarity index 78% rename from src/main/java/ix/Pred0.java rename to src/main/java/ix/IxBooleanSupplier.java index b23a207..c1ecdc2 100644 --- a/src/main/java/ix/Pred0.java +++ b/src/main/java/ix/IxBooleanSupplier.java @@ -17,12 +17,12 @@ package ix; /** - * A supplier of a single boolean value. + * A function callback with no inputs and a boolean output. */ -public interface Pred0 { +public interface IxBooleanSupplier { /** - * Returns a boolean value. - * @return a boolean value + * Calls the function which returns a boolean. + * @return the output boolean */ boolean getAsBoolean(); } diff --git a/src/main/java/ix/IxBuffer.java b/src/main/java/ix/IxBuffer.java index cb0ee10..1a03c38 100644 --- a/src/main/java/ix/IxBuffer.java +++ b/src/main/java/ix/IxBuffer.java @@ -21,12 +21,12 @@ final class IxBuffer extends IxSource> { final int size; - - public IxBuffer(Iterable source, int size) { + + IxBuffer(Iterable source, int size) { super(source); this.size = size; } - + @Override public Iterator> iterator() { return new BufferIterator(source.iterator(), size); @@ -35,7 +35,7 @@ public Iterator> iterator() { static final class BufferIterator extends IxSourceIterator> { final int size; - public BufferIterator(Iterator it, int size) { + BufferIterator(Iterator it, int size) { super(it); this.size = size; } @@ -43,16 +43,16 @@ public BufferIterator(Iterator it, int size) { @Override protected boolean moveNext() { int s = size; - + Iterator it = this.it; - + List list = new ArrayList(); - + while (s != 0 && it.hasNext()) { list.add(it.next()); s--; } - + if (list.isEmpty()) { done = true; return false; @@ -64,7 +64,7 @@ protected boolean moveNext() { } return true; } - - + + } } diff --git a/src/main/java/ix/IxBufferOverlap.java b/src/main/java/ix/IxBufferOverlap.java index ebbc07e..c801ddf 100644 --- a/src/main/java/ix/IxBufferOverlap.java +++ b/src/main/java/ix/IxBufferOverlap.java @@ -18,34 +18,32 @@ import java.util.*; -import rx.functions.Action2; - final class IxBufferOverlap extends IxSource> { final int size; - + final int skip; - - public IxBufferOverlap(Iterable source, int size, int skip) { + + IxBufferOverlap(Iterable source, int size, int skip) { super(source); this.size = size; this.skip = skip; } - + @Override public Iterator> iterator() { return new BufferIterator(source.iterator(), size, skip); } static final class BufferIterator extends IxSourceQueuedIterator, List> - implements Action2, T> { + implements IxConsumer2, T> { final int size; - + final int skip; - + int index; - - public BufferIterator(Iterator it, int size, int skip) { + + BufferIterator(Iterator it, int size, int skip) { super(it); this.size = size; this.skip = skip; @@ -55,12 +53,12 @@ public BufferIterator(Iterator it, int size, int skip) { @Override protected boolean moveNext() { Iterator it = this.it; - + int s = size; int k = skip; - + int i = index; - + while (it.hasNext()) { if (i == 0) { offer(new ArrayList()); @@ -70,26 +68,26 @@ protected boolean moveNext() { if (++i == k) { i = 0; } - + if (((List)peek()).size() == s) { break; } } index = i; - + List list = fromObject(poll()); if (list == null) { done = true; return false; } - + value = list; hasValue = true; return true; } - + @Override - public void call(List t1, T t2) { + public void accept(List t1, T t2) { t1.add(t2); } } diff --git a/src/main/java/ix/IxBufferSkip.java b/src/main/java/ix/IxBufferSkip.java index e275be1..70ca253 100644 --- a/src/main/java/ix/IxBufferSkip.java +++ b/src/main/java/ix/IxBufferSkip.java @@ -21,15 +21,15 @@ final class IxBufferSkip extends IxSource> { final int size; - + final int skip; - - public IxBufferSkip(Iterable source, int size, int skip) { + + IxBufferSkip(Iterable source, int size, int skip) { super(source); this.size = size; this.skip = skip; } - + @Override public Iterator> iterator() { return new BufferSkipIterator(source.iterator(), size, skip); @@ -37,12 +37,12 @@ public Iterator> iterator() { static final class BufferSkipIterator extends IxSourceIterator> { final int size; - + final int skip; - + boolean once; - public BufferSkipIterator(Iterator it, int size, int skip) { + BufferSkipIterator(Iterator it, int size, int skip) { super(it); this.size = size; this.skip = skip; @@ -51,28 +51,28 @@ public BufferSkipIterator(Iterator it, int size, int skip) { @Override protected boolean moveNext() { Iterator it = this.it; - + int s = size; - + if (once) { int k = skip - s; while (k != 0 && it.hasNext()) { it.next(); k--; } - + } else { once = true; } List list = new ArrayList(); - + while (s != 0 && it.hasNext()) { list.add(it.next()); s--; } - - + + if (list.isEmpty()) { done = true; return false; @@ -84,7 +84,7 @@ protected boolean moveNext() { } return true; } - - + + } } diff --git a/src/main/java/ix/IxCharacters.java b/src/main/java/ix/IxCharacters.java index 0f75588..c54a404 100644 --- a/src/main/java/ix/IxCharacters.java +++ b/src/main/java/ix/IxCharacters.java @@ -21,31 +21,31 @@ final class IxCharacters extends Ix { final CharSequence source; - + final int start; - + final int end; - - public IxCharacters(CharSequence source, int start, int end) { + + IxCharacters(CharSequence source, int start, int end) { this.source = source; this.start = start; this.end = end; } - + @Override public Iterator iterator() { return new CharactersIterator(source, start, end); } - + static final class CharactersIterator implements Iterator { final CharSequence source; final int end; - + int index; - - public CharactersIterator(CharSequence source, int start, int end) { + + CharactersIterator(CharSequence source, int start, int end) { this.source = source; this.index = start; this.end = end; @@ -65,7 +65,7 @@ public Integer next() { } throw new NoSuchElementException(); } - + @Override public void remove() { throw new UnsupportedOperationException(); diff --git a/src/main/java/ix/IxCollect.java b/src/main/java/ix/IxCollect.java index 5712589..4932bc2 100644 --- a/src/main/java/ix/IxCollect.java +++ b/src/main/java/ix/IxCollect.java @@ -18,15 +18,13 @@ import java.util.Iterator; -import rx.functions.*; - final class IxCollect extends IxSource { - final Func0 initialFactory; - - final Action2 collector; - - public IxCollect(Iterable source, Func0 initialFactory, Action2 collector) { + final IxSupplier initialFactory; + + final IxConsumer2 collector; + + IxCollect(Iterable source, IxSupplier initialFactory, IxConsumer2 collector) { super(source); this.initialFactory = initialFactory; this.collector = collector; @@ -34,14 +32,14 @@ public IxCollect(Iterable source, Func0 initialFactory, Action2 coll @Override public Iterator iterator() { - return new CollectorIterator(source.iterator(), collector, initialFactory.call()); + return new CollectorIterator(source.iterator(), collector, initialFactory.get()); } static final class CollectorIterator extends IxSourceIterator { - final Action2 collector; - - public CollectorIterator(Iterator it, Action2 collector, C value) { + final IxConsumer2 collector; + + CollectorIterator(Iterator it, IxConsumer2 collector, C value) { super(it); this.collector = collector; this.value = value; @@ -50,15 +48,15 @@ public CollectorIterator(Iterator it, Action2 collector, C value) { @Override protected boolean moveNext() { Iterator it = this.it; - - Action2 coll = collector; - + + IxConsumer2 coll = collector; + C c = value; - + while (it.hasNext()) { - coll.call(c, it.next()); + coll.accept(c, it.next()); } - + hasValue = true; done = true; return true; diff --git a/src/main/java/ix/IxCompose.java b/src/main/java/ix/IxCompose.java index 03775a9..c578bf8 100644 --- a/src/main/java/ix/IxCompose.java +++ b/src/main/java/ix/IxCompose.java @@ -18,13 +18,11 @@ import java.util.Iterator; -import rx.functions.Func1; - final class IxCompose extends IxSource { - final Func1, ? extends Iterable> transformer; - - public IxCompose(Iterable source, Func1, ? extends Iterable> transformer) { + final IxFunction, ? extends Iterable> transformer; + + IxCompose(Iterable source, IxFunction, ? extends Iterable> transformer) { super(source); this.transformer = transformer; } @@ -32,7 +30,7 @@ public IxCompose(Iterable source, Func1, ? extends Iterable iterator() { - return (Iterator)transformer.call(from(source)).iterator(); + return (Iterator)transformer.apply(from(source)).iterator(); } } diff --git a/src/main/java/ix/IxConsumer.java b/src/main/java/ix/IxConsumer.java new file mode 100644 index 0000000..b56463b --- /dev/null +++ b/src/main/java/ix/IxConsumer.java @@ -0,0 +1,29 @@ +/* + * Copyright 2011-2016 David Karnok + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ix; + +/** + * A function callback with one input value. + * @param the input value type + */ +public interface IxConsumer { + /** + * Applies a function to the input value. + * @param t the input value + */ + void accept(T t); +} diff --git a/src/main/java/ix/IxConsumer2.java b/src/main/java/ix/IxConsumer2.java new file mode 100644 index 0000000..5ec592c --- /dev/null +++ b/src/main/java/ix/IxConsumer2.java @@ -0,0 +1,31 @@ +/* + * Copyright 2011-2016 David Karnok + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ix; + +/** + * A function callback with two input values. + * @param the input value type + * @param the input value type + */ +public interface IxConsumer2 { + /** + * Applies a function to the input value. + * @param t the first input value + * @param u the second input value + */ + void accept(T t, U u); +} diff --git a/src/main/java/ix/IxContains.java b/src/main/java/ix/IxContains.java index b9f58aa..5e44c24 100644 --- a/src/main/java/ix/IxContains.java +++ b/src/main/java/ix/IxContains.java @@ -21,8 +21,8 @@ final class IxContains extends IxSource { final Object o; - - public IxContains(Iterable source, Object o) { + + IxContains(Iterable source, Object o) { super(source); this.o = o; } @@ -31,21 +31,21 @@ public IxContains(Iterable source, Object o) { public Iterator iterator() { return new ContainsIterator(source.iterator(), o); } - + static final class ContainsIterator extends IxSourceIterator { final Object o; - public ContainsIterator(Iterator it, Object o) { + ContainsIterator(Iterator it, Object o) { super(it); this.o = o; } - + @Override protected boolean moveNext() { Iterator it = this.it; Object o = this.o; - + while (it.hasNext()) { T v = it.next(); if (o == v || (o != null && o.equals(v))) { @@ -55,7 +55,7 @@ protected boolean moveNext() { return true; } } - + value = false; hasValue = true; done = true; diff --git a/src/main/java/ix/IxCount.java b/src/main/java/ix/IxCount.java index 2866a5d..882f662 100644 --- a/src/main/java/ix/IxCount.java +++ b/src/main/java/ix/IxCount.java @@ -20,7 +20,7 @@ final class IxCount extends IxSource { - public IxCount(Iterable source) { + IxCount(Iterable source) { super(source); } @@ -31,21 +31,21 @@ public Iterator iterator() { static final class CountIterator extends IxSourceIterator { - public CountIterator(Iterator it) { + CountIterator(Iterator it) { super(it); } @Override protected boolean moveNext() { int c = 0; - + Iterator it = this.it; - + while (it.hasNext()) { it.next(); c++; } - + value = c; hasValue = true; done = true; diff --git a/src/main/java/ix/IxCountLong.java b/src/main/java/ix/IxCountLong.java index 240fde1..f06a40f 100644 --- a/src/main/java/ix/IxCountLong.java +++ b/src/main/java/ix/IxCountLong.java @@ -20,7 +20,7 @@ final class IxCountLong extends IxSource { - public IxCountLong(Iterable source) { + IxCountLong(Iterable source) { super(source); } @@ -31,21 +31,21 @@ public Iterator iterator() { static final class CountLongIterator extends IxSourceIterator { - public CountLongIterator(Iterator it) { + CountLongIterator(Iterator it) { super(it); } @Override protected boolean moveNext() { long c = 0; - + Iterator it = this.it; - + while (it.hasNext()) { it.next(); c++; } - + value = c; hasValue = true; done = true; diff --git a/src/main/java/ix/IxDefer.java b/src/main/java/ix/IxDefer.java index af03c3c..6d5b409 100644 --- a/src/main/java/ix/IxDefer.java +++ b/src/main/java/ix/IxDefer.java @@ -18,19 +18,17 @@ import java.util.Iterator; -import rx.functions.Func0; - final class IxDefer extends Ix { - final Func0> factory; - - public IxDefer(Func0> factory) { + final IxSupplier> factory; + + IxDefer(IxSupplier> factory) { this.factory = factory; } - + @SuppressWarnings("unchecked") @Override public Iterator iterator() { - return (Iterator)factory.call().iterator(); + return (Iterator)factory.get().iterator(); } } diff --git a/src/main/java/ix/IxDistinct.java b/src/main/java/ix/IxDistinct.java index 97a13d0..94ac42d 100644 --- a/src/main/java/ix/IxDistinct.java +++ b/src/main/java/ix/IxDistinct.java @@ -18,28 +18,26 @@ import java.util.*; -import rx.functions.Func1; - final class IxDistinct extends IxSource { - final Func1 keySelector; - - public IxDistinct(Iterable source, Func1 keySelector) { + final IxFunction keySelector; + + IxDistinct(Iterable source, IxFunction keySelector) { super(source); this.keySelector = keySelector; } - + @Override public Iterator iterator() { return new DistinctIterator(source.iterator(), keySelector); } static final class DistinctIterator extends IxSourceIterator { - final Func1 keySelector; + final IxFunction keySelector; final Set set; - - public DistinctIterator(Iterator it, Func1 keySelector) { + + DistinctIterator(Iterator it, IxFunction keySelector) { super(it); this.keySelector = keySelector; this.set = new HashSet(); @@ -48,19 +46,19 @@ public DistinctIterator(Iterator it, Func1 keySelector) { @Override protected boolean moveNext() { Iterator it = this.it; - + while (it.hasNext()) { T v = it.next(); - - K k = keySelector.call(v); - + + K k = keySelector.apply(v); + if (set.add(k)) { value = v; hasValue = true; return true; } } - + done = true; return false; } diff --git a/src/main/java/ix/IxDistinctUntilChanged.java b/src/main/java/ix/IxDistinctUntilChanged.java index 9915650..9f7b44a 100644 --- a/src/main/java/ix/IxDistinctUntilChanged.java +++ b/src/main/java/ix/IxDistinctUntilChanged.java @@ -18,16 +18,14 @@ import java.util.Iterator; -import rx.functions.Func1; - final class IxDistinctUntilChanged extends IxSource { - final Func1 keySelector; - - final Pred2 comparer; - - public IxDistinctUntilChanged(Iterable source, Func1 keySelector, - Pred2 comparer) { + final IxFunction keySelector; + + final IxPredicate2 comparer; + + IxDistinctUntilChanged(Iterable source, IxFunction keySelector, + IxPredicate2 comparer) { super(source); this.keySelector = keySelector; this.comparer = comparer; @@ -39,17 +37,17 @@ public Iterator iterator() { } static final class DistinctUntilChangedIterator extends IxSourceIterator { - - final Func1 keySelector; - - final Pred2 comparer; + + final IxFunction keySelector; + + final IxPredicate2 comparer; K last; - + boolean once; - - public DistinctUntilChangedIterator(Iterator it, Func1 keySelector, - Pred2 comparer) { + + DistinctUntilChangedIterator(Iterator it, IxFunction keySelector, + IxPredicate2 comparer) { super(it); this.keySelector = keySelector; this.comparer = comparer; @@ -58,40 +56,40 @@ public DistinctUntilChangedIterator(Iterator it, Func1 keySelec @Override protected boolean moveNext() { Iterator it = this.it; - + K prev = last; - K curr = null; - + K curr; + while (it.hasNext()) { T v = it.next(); - curr = keySelector.call(v); + curr = keySelector.apply(v); if (!once) { once = true; - + last = curr; - + value = v; hasValue = true; return true; } - + if (!comparer.test(prev, curr)) { last = curr; - + value = v; hasValue = true; return true; } - + prev = curr; } - - + + done = true; return false; } - + } } diff --git a/src/main/java/ix/IxDoOn.java b/src/main/java/ix/IxDoOn.java index d4c74b9..57feef6 100644 --- a/src/main/java/ix/IxDoOn.java +++ b/src/main/java/ix/IxDoOn.java @@ -18,15 +18,13 @@ import java.util.Iterator; -import rx.functions.*; - final class IxDoOn extends IxSource { - final Action1 onNext; - - final Action0 onCompleted; - - public IxDoOn(Iterable source, Action1 onNext, Action0 onCompleted) { + final IxConsumer onNext; + + final Runnable onCompleted; + + IxDoOn(Iterable source, IxConsumer onNext, Runnable onCompleted) { super(source); this.onNext = onNext; this.onCompleted = onCompleted; @@ -38,11 +36,11 @@ public Iterator iterator() { } static final class DoOnIterator extends IxSourceIterator { - final Action1 onNext; - - final Action0 onCompleted; + final IxConsumer onNext; + + final Runnable onCompleted; - public DoOnIterator(Iterator it, Action1 onNext, Action0 onCompleted) { + DoOnIterator(Iterator it, IxConsumer onNext, Runnable onCompleted) { super(it); this.onNext = onNext; this.onCompleted = onCompleted; @@ -54,10 +52,10 @@ protected boolean moveNext() { T v = it.next(); value = v; hasValue = true; - onNext.call(v); + onNext.accept(v); return true; } - onCompleted.call(); + onCompleted.run(); done = true; return false; } diff --git a/src/main/java/ix/IxEmitter.java b/src/main/java/ix/IxEmitter.java new file mode 100644 index 0000000..f1a0e61 --- /dev/null +++ b/src/main/java/ix/IxEmitter.java @@ -0,0 +1,36 @@ +/* + * Copyright 2011-2016 David Karnok + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ix; + +/** + * Allows signalling values or completion in an imperative manner. + * + * @param the value type emitted + */ +public interface IxEmitter { + + /** + * The next value to signal. + * @param value the value to signal + */ + void onNext(T value); + + /** + * Indicate no more values will be generated. + */ + void onComplete(); +} diff --git a/src/main/java/ix/IxEmpty.java b/src/main/java/ix/IxEmpty.java index a19d66e..7e76d4d 100644 --- a/src/main/java/ix/IxEmpty.java +++ b/src/main/java/ix/IxEmpty.java @@ -21,12 +21,12 @@ final class IxEmpty extends Ix implements Iterator { static final IxEmpty INSTANCE = new IxEmpty(); - + @SuppressWarnings("unchecked") static Ix instance() { return (Ix)INSTANCE; } - + @Override public Iterator iterator() { return this; @@ -41,7 +41,7 @@ public boolean hasNext() { public Object next() { throw new NoSuchElementException(); } - + @Override public void remove() { throw new UnsupportedOperationException(); diff --git a/src/main/java/ix/IxEmptyAction.java b/src/main/java/ix/IxEmptyAction.java index dcd81f3..44bf72c 100644 --- a/src/main/java/ix/IxEmptyAction.java +++ b/src/main/java/ix/IxEmptyAction.java @@ -16,28 +16,26 @@ package ix; -import rx.functions.*; - -enum IxEmptyAction implements Action1, Action0 { +enum IxEmptyAction implements IxConsumer, Runnable { INSTANCE; @SuppressWarnings("unchecked") - public static Action1 instance1() { - return (Action1)INSTANCE; + public static IxConsumer instance1() { + return (IxConsumer)INSTANCE; } - public static Action0 instance0() { + public static Runnable instance0() { return INSTANCE; } @Override - public void call(Object t) { + public void accept(Object t) { // deliberately no op } - + @Override - public void call() { + public void run() { // deliberately no op } - + } diff --git a/src/main/java/ix/IxExcept.java b/src/main/java/ix/IxExcept.java index a8380ee..af4bdb5 100644 --- a/src/main/java/ix/IxExcept.java +++ b/src/main/java/ix/IxExcept.java @@ -23,33 +23,33 @@ final class IxExcept extends IxSource { final Iterable other; - public IxExcept(Iterable source, Iterable other) { + IxExcept(Iterable source, Iterable other) { super(source); this.other = other; } - + @Override public Iterator iterator() { return new ExceptIterator(source.iterator(), other.iterator()); } - + static final class ExceptIterator extends IxSourceIterator { final Iterator other; - + final LinkedHashMap set; - + Iterator> setIterator; - + boolean once; - + boolean second; - public ExceptIterator(Iterator it, Iterator other) { + ExceptIterator(Iterator it, Iterator other) { super(it); this.other = other; this.set = new LinkedHashMap(); } - + @Override protected boolean moveNext() { LinkedHashMap secondSet = set; @@ -59,13 +59,13 @@ protected boolean moveNext() { secondSet.put(other.next(), true); } } - + for (;;) { if (second) { Iterator> sIt = setIterator; while (sIt.hasNext()) { Entry e = sIt.next(); - + if (e.getValue()) { value = e.getKey(); hasValue = true; @@ -78,7 +78,7 @@ protected boolean moveNext() { Iterator fIt = it; while (fIt.hasNext()) { T v = fIt.next(); - + Boolean b = secondSet.get(v); if (b == null) { value = v; @@ -92,7 +92,7 @@ protected boolean moveNext() { second = true; setIterator = secondSet.entrySet().iterator(); } - } + } } } } diff --git a/src/main/java/ix/IxFilter.java b/src/main/java/ix/IxFilter.java index e530c6e..c26a036 100644 --- a/src/main/java/ix/IxFilter.java +++ b/src/main/java/ix/IxFilter.java @@ -20,9 +20,9 @@ final class IxFilter extends IxSource { - final Pred predicate; - - public IxFilter(Iterable source, Pred predicate) { + final IxPredicate predicate; + + IxFilter(Iterable source, IxPredicate predicate) { super(source); this.predicate = predicate; } @@ -34,9 +34,9 @@ public Iterator iterator() { static final class FilterIterator extends IxSourceIterator { - final Pred predicate; - - public FilterIterator(Iterator it, Pred predicate) { + final IxPredicate predicate; + + FilterIterator(Iterator it, IxPredicate predicate) { super(it); this.predicate = predicate; } @@ -57,7 +57,7 @@ protected boolean moveNext() { } } } - + @Override public void remove() { it.remove(); diff --git a/src/main/java/ix/IxFlattenArrayIterable.java b/src/main/java/ix/IxFlattenArrayIterable.java index aa89bfa..e8656ce 100644 --- a/src/main/java/ix/IxFlattenArrayIterable.java +++ b/src/main/java/ix/IxFlattenArrayIterable.java @@ -22,8 +22,8 @@ final class IxFlattenArrayIterable extends Ix { final Iterable[] sources; - - public IxFlattenArrayIterable(Iterable[] sources) { + + IxFlattenArrayIterable(Iterable[] sources) { this.sources = sources; } @@ -31,7 +31,7 @@ public IxFlattenArrayIterable(Iterable[] sources) { public Iterator iterator() { return new FlattenIterator(sources); } - + static final class FlattenIterator extends IxBaseIterator { final Iterable[] sources; @@ -39,8 +39,8 @@ static final class FlattenIterator extends IxBaseIterator { Iterator current; int index; - - public FlattenIterator(Iterable[] sources) { + + FlattenIterator(Iterable[] sources) { this.sources = sources; } @@ -48,7 +48,7 @@ public FlattenIterator(Iterable[] sources) { @Override protected boolean moveNext() { Iterator c = current; - + while (c == null) { int i = index; if (i != sources.length) { @@ -59,9 +59,9 @@ protected boolean moveNext() { hasValue = true; return true; } - + c = inner.iterator(); - + if (c.hasNext()) { current = c; break; @@ -73,16 +73,16 @@ protected boolean moveNext() { return false; } } - + value = c.next(); hasValue = true; - + if (!c.hasNext()) { current = null; } return true; } - + } } diff --git a/src/main/java/ix/IxFlattenIterable.java b/src/main/java/ix/IxFlattenIterable.java index 6b4aa63..d1969c1 100644 --- a/src/main/java/ix/IxFlattenIterable.java +++ b/src/main/java/ix/IxFlattenIterable.java @@ -19,13 +19,11 @@ import java.util.Iterator; import java.util.concurrent.Callable; -import rx.functions.Func1; - final class IxFlattenIterable extends IxSource { - final Func1> mapper; - - public IxFlattenIterable(Iterable source, Func1> mapper) { + final IxFunction> mapper; + + IxFlattenIterable(Iterable source, IxFunction> mapper) { super(source); this.mapper = mapper; } @@ -34,18 +32,18 @@ public IxFlattenIterable(Iterable source, Func1 iterator() { if (source instanceof Callable) { - return (Iterator)(mapper.call(checkedCall((Callable)source)).iterator()); + return (Iterator)(mapper.apply(checkedCall((Callable)source)).iterator()); } return new FlattenIterator(source.iterator(), mapper); } - + static final class FlattenIterator extends IxSourceIterator { - final Func1> mapper; + final IxFunction> mapper; Iterator current; - - public FlattenIterator(Iterator it, Func1> mapper) { + + FlattenIterator(Iterator it, IxFunction> mapper) { super(it); this.mapper = mapper; } @@ -54,18 +52,18 @@ public FlattenIterator(Iterator it, Func1 c = current; - + while (c == null) { if (it.hasNext()) { - Iterable inner = mapper.call(it.next()); + Iterable inner = mapper.apply(it.next()); if (inner instanceof Callable) { value = checkedCall((Callable)inner); hasValue = true; return true; } - + c = inner.iterator(); - + if (c.hasNext()) { current = c; break; @@ -77,16 +75,16 @@ protected boolean moveNext() { return false; } } - + value = c.next(); hasValue = true; - + if (!c.hasNext()) { current = null; } return true; } - + } } diff --git a/src/main/java/ix/IxForloop.java b/src/main/java/ix/IxForloop.java index acf1cf1..7035e9a 100644 --- a/src/main/java/ix/IxForloop.java +++ b/src/main/java/ix/IxForloop.java @@ -18,45 +18,43 @@ import java.util.Iterator; -import rx.functions.Func1; - final class IxForloop extends Ix { final T seed; - - final Pred condition; - - final Func1 selector; - - final Func1 next; - - public IxForloop(T seed, Pred condition, Func1 selector, - Func1 next) { + + final IxPredicate condition; + + final IxFunction selector; + + final IxFunction next; + + IxForloop(T seed, IxPredicate condition, IxFunction selector, + IxFunction next) { this.seed = seed; this.condition = condition; this.selector = selector; this.next = next; } - + @Override public Iterator iterator() { return new ForloopIterator(seed, condition, selector, next); } - + static final class ForloopIterator extends IxBaseIterator { - + T index; - final Pred condition; - - final Func1 selector; - - final Func1 next; + final IxPredicate condition; + + final IxFunction selector; + + final IxFunction next; boolean exceptFirst; - - public ForloopIterator(T index, Pred condition, Func1 selector, - Func1 next) { + + ForloopIterator(T index, IxPredicate condition, IxFunction selector, + IxFunction next) { this.index = index; this.condition = condition; this.selector = selector; @@ -66,22 +64,22 @@ public ForloopIterator(T index, Pred condition, Func1 extends Ix { final int start; final int end; final T[] array; - - public IxFromArray(int start, int end, T[] array) { + + IxFromArray(int start, int end, T[] array) { this.start = start; this.end = end; this.array = array; @@ -39,10 +39,10 @@ static final class FromArray implements Iterator { final T[] array; final int end; - + int index; - public FromArray(int start, int end, T[] array) { + FromArray(int start, int end, T[] array) { this.index = start; this.end = end; this.array = array; diff --git a/src/main/java/ix/IxFunction.java b/src/main/java/ix/IxFunction.java new file mode 100644 index 0000000..3086135 --- /dev/null +++ b/src/main/java/ix/IxFunction.java @@ -0,0 +1,31 @@ +/* + * Copyright 2011-2016 David Karnok + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ix; + +/** + * A function callback with one input value and one output value. + * @param the input value type + * @param the output value type + */ +public interface IxFunction { + /** + * Applies a function to the input value and returns an output value. + * @param t the input value + * @return the output value + */ + R apply(T t); +} diff --git a/src/main/java/ix/IxFunction2.java b/src/main/java/ix/IxFunction2.java new file mode 100644 index 0000000..64cceac --- /dev/null +++ b/src/main/java/ix/IxFunction2.java @@ -0,0 +1,33 @@ +/* + * Copyright 2011-2016 David Karnok + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ix; + +/** + * A function callback with two input values and one output value. + * @param the first input value type + * @param the second input value type + * @param the output value type + */ +public interface IxFunction2 { + /** + * Applies a function to the input values and returns an output value. + * @param t the first input value + * @param u the second input value + * @return the output value + */ + R apply(T t, U u); +} diff --git a/src/main/java/ix/IxFunction3.java b/src/main/java/ix/IxFunction3.java new file mode 100644 index 0000000..827f97c --- /dev/null +++ b/src/main/java/ix/IxFunction3.java @@ -0,0 +1,35 @@ +/* + * Copyright 2011-2016 David Karnok + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ix; + +/** + * A function callback with three input values and one output value. + * @param the first input value type + * @param the second input value type + * @param the third input value type + * @param the output value type + */ +public interface IxFunction3 { + /** + * Applies a function to the input values and returns an output value. + * @param t the first input value + * @param u the second input value + * @param v the third input value + * @return the output value + */ + R apply(T t, U u, V v); +} diff --git a/src/main/java/ix/IxFunction4.java b/src/main/java/ix/IxFunction4.java new file mode 100644 index 0000000..562601c --- /dev/null +++ b/src/main/java/ix/IxFunction4.java @@ -0,0 +1,37 @@ +/* + * Copyright 2011-2016 David Karnok + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ix; + +/** + * A function callback with four input values and one output value. + * @param the first input value type + * @param the second input value type + * @param the third input value type + * @param the fourth input value type + * @param the output value type + */ +public interface IxFunction4 { + /** + * Applies a function to the input values and returns an output value. + * @param t the first input value + * @param u the second input value + * @param v the third input value + * @param w the fourth input value + * @return the output value + */ + R apply(T t, U u, V v, W w); +} diff --git a/src/main/java/ix/IxGenerate.java b/src/main/java/ix/IxGenerate.java index e324c1e..b7740d8 100644 --- a/src/main/java/ix/IxGenerate.java +++ b/src/main/java/ix/IxGenerate.java @@ -18,38 +18,35 @@ import java.util.Iterator; -import rx.Observer; -import rx.functions.*; - final class IxGenerate extends Ix { - final Func0 stateFactory; - - final Func2, S> generator; - - final Action1 stateDisposer; - - public IxGenerate(Func0 stateFactory, Func2, S> generator, Action1 stateDisposer) { + final IxSupplier stateFactory; + + final IxFunction2, S> generator; + + final IxConsumer stateDisposer; + + IxGenerate(IxSupplier stateFactory, IxFunction2, S> generator, IxConsumer stateDisposer) { this.stateFactory = stateFactory; this.generator = generator; this.stateDisposer = stateDisposer; } - + @Override public Iterator iterator() { - return new GenerateIterator(stateFactory.call(), generator, stateDisposer); + return new GenerateIterator(stateFactory.get(), generator, stateDisposer); } - + static final class GenerateIterator extends IxBaseIterator - implements Observer { + implements IxEmitter { - final Func2, S> generator; - - final Action1 stateDisposer; + final IxFunction2, S> generator; + + final IxConsumer stateDisposer; S state; - - public GenerateIterator(S state, Func2, S> generator, Action1 stateDisposer) { + + GenerateIterator(S state, IxFunction2, S> generator, IxConsumer stateDisposer) { this.state = state; this.generator = generator; this.stateDisposer = stateDisposer; @@ -57,42 +54,29 @@ public GenerateIterator(S state, Func2, S> generator, Action1 extends Ix { - final Action1> generator; - - public IxGenerateStateless(Action1> generator) { + final IxConsumer> generator; + + IxGenerateStateless(IxConsumer> generator) { this.generator = generator; } - + @Override public Iterator iterator() { return new GenerateIterator(generator); } - + static final class GenerateIterator extends IxBaseIterator - implements Observer { + implements IxEmitter { - final Action1> generator; - - public GenerateIterator(Action1> generator) { + final IxConsumer> generator; + + GenerateIterator(IxConsumer> generator) { this.generator = generator; } @Override protected boolean moveNext() { - - generator.call(this); - + + generator.accept(this); + boolean hv = hasValue; if (!hv && !done) { throw new IllegalStateException("The generator didn't call any of the onXXX methods!"); } return hv; } - + @Override public void onNext(T t) { value = t; hasValue = true; } - - @Override - public void onError(Throwable e) { - if (e instanceof RuntimeException) { - throw (RuntimeException)e; - } - if (e instanceof Error) { - throw (Error)e; - } - throw new RuntimeException(e); - } - + @Override - public void onCompleted() { + public void onComplete() { done = true; } } diff --git a/src/main/java/ix/IxGroupBy.java b/src/main/java/ix/IxGroupBy.java index 93e3da7..e23d9f3 100644 --- a/src/main/java/ix/IxGroupBy.java +++ b/src/main/java/ix/IxGroupBy.java @@ -18,18 +18,16 @@ import java.util.*; -import rx.functions.Func1; - final class IxGroupBy extends IxSource> { static final Object NULL = new Object(); - - final Func1 keySelector; - - final Func1 valueSelector; - - public IxGroupBy(Iterable source, Func1 keySelector, - Func1 valueSelector) { + + final IxFunction keySelector; + + final IxFunction valueSelector; + + IxGroupBy(Iterable source, IxFunction keySelector, + IxFunction valueSelector) { super(source); this.keySelector = keySelector; this.valueSelector = valueSelector; @@ -41,16 +39,16 @@ public Iterator> iterator() { } static final class GroupByIterator extends IxSourceIterator> { - final Func1 keySelector; - - final Func1 valueSelector; + final IxFunction keySelector; + + final IxFunction valueSelector; final Map> groups; final Queue> queue; - - public GroupByIterator(Iterator it, Func1 keySelector, - Func1 valueSelector) { + + GroupByIterator(Iterator it, IxFunction keySelector, + IxFunction valueSelector) { super(it); this.keySelector = keySelector; this.valueSelector = valueSelector; @@ -82,18 +80,18 @@ boolean mainMoveNext() { groups.clear(); return false; } - + T v = it.next(); - - K key = keySelector.call(v); - V val = valueSelector.call(v); - + + K key = keySelector.apply(v); + V val = valueSelector.apply(v); + GroupedIterable g = groups.get(key); if (g == null) { g = new GroupedIterable(key, this); groups.put(key, g); g.iterator.queue.offer(val != null ? val : NULL); - + queue.offer(g); return true; } else { @@ -101,7 +99,7 @@ boolean mainMoveNext() { } } } - + boolean groupMoveNext(GroupByGroupIterator groupIterator) { if (done) { return false; @@ -111,12 +109,12 @@ boolean groupMoveNext(GroupByGroupIterator groupIterator) { groups.clear(); return false; } - + T v = it.next(); - - K key = keySelector.call(v); - V val = valueSelector.call(v); - + + K key = keySelector.apply(v); + V val = valueSelector.apply(v); + GroupedIterable g = groups.get(key); if (g == null) { g = new GroupedIterable(key, this); @@ -132,14 +130,14 @@ boolean groupMoveNext(GroupByGroupIterator groupIterator) { } } } - + static final class GroupedIterable extends GroupedIx { final GroupByGroupIterator iterator; - + boolean once; - - public GroupedIterable(K key, GroupByIterator parent) { + + GroupedIterable(K key, GroupByIterator parent) { super(key); this.iterator = new GroupByGroupIterator(parent, key); } @@ -152,26 +150,26 @@ public Iterator iterator() { } throw new IllegalStateException("This GroupedIx iterable can be consumed only once."); } - + @Override public String toString() { return "GroupedIterable[key=" + iterator.key + ", queue=" + iterator.queue.size() + "]"; } } - + static final class GroupByGroupIterator extends IxBaseIterator { final GroupByIterator parent; - + final K key; final ArrayDeque queue; - - public GroupByGroupIterator(GroupByIterator parent, K key) { + + GroupByGroupIterator(GroupByIterator parent, K key) { this.parent = parent; this.key = key; this.queue = new ArrayDeque(); } - + @SuppressWarnings("unchecked") @Override protected boolean moveNext() { diff --git a/src/main/java/ix/IxHasElements.java b/src/main/java/ix/IxHasElements.java index 3b6405c..1d2d9b9 100644 --- a/src/main/java/ix/IxHasElements.java +++ b/src/main/java/ix/IxHasElements.java @@ -20,7 +20,7 @@ final class IxHasElements extends IxSource { - public IxHasElements(Iterable source) { + IxHasElements(Iterable source) { super(source); } @@ -31,10 +31,10 @@ public Iterator iterator() { static final class HasElementsIterator extends IxSourceIterator { - public HasElementsIterator(Iterator it) { + HasElementsIterator(Iterator it) { super(it); } - + @Override protected boolean moveNext() { value = it.hasNext(); diff --git a/src/main/java/ix/IxIgnoreElements.java b/src/main/java/ix/IxIgnoreElements.java index f431128..f7240f5 100644 --- a/src/main/java/ix/IxIgnoreElements.java +++ b/src/main/java/ix/IxIgnoreElements.java @@ -20,7 +20,7 @@ final class IxIgnoreElements extends IxSource { - public IxIgnoreElements(Iterable source) { + IxIgnoreElements(Iterable source) { super(source); } @@ -31,21 +31,21 @@ public Iterator iterator() { static final class IgnoreElementsIterator extends IxSourceIterator { - public IgnoreElementsIterator(Iterator it) { + IgnoreElementsIterator(Iterator it) { super(it); } @Override protected boolean moveNext() { Iterator it = this.it; - + while (it.hasNext()) { it.next(); } - + done = true; return false; } - + } } diff --git a/src/main/java/ix/IxIntersect.java b/src/main/java/ix/IxIntersect.java index 33e1548..40a1332 100644 --- a/src/main/java/ix/IxIntersect.java +++ b/src/main/java/ix/IxIntersect.java @@ -22,29 +22,29 @@ final class IxIntersect extends IxSource { final Iterable other; - public IxIntersect(Iterable source, Iterable other) { + IxIntersect(Iterable source, Iterable other) { super(source); this.other = other; } - + @Override public Iterator iterator() { return new IntersectIterator(source.iterator(), other.iterator()); } - + static final class IntersectIterator extends IxSourceIterator { final Iterator other; - + final Set set; - + boolean once; - public IntersectIterator(Iterator it, Iterator other) { + IntersectIterator(Iterator it, Iterator other) { super(it); this.other = other; this.set = new HashSet(); } - + @Override protected boolean moveNext() { Set secondSet = set; @@ -59,7 +59,7 @@ protected boolean moveNext() { Iterator fIt = it; while (fIt.hasNext()) { T v = fIt.next(); - + if (secondSet.contains(v)) { value = v; hasValue = true; diff --git a/src/main/java/ix/IxJoin.java b/src/main/java/ix/IxJoin.java index 4142c06..85566bd 100644 --- a/src/main/java/ix/IxJoin.java +++ b/src/main/java/ix/IxJoin.java @@ -21,8 +21,8 @@ final class IxJoin extends IxSource { final CharSequence separator; - - public IxJoin(Iterable source, CharSequence separator) { + + IxJoin(Iterable source, CharSequence separator) { super(source); this.separator = separator; } @@ -31,32 +31,32 @@ public IxJoin(Iterable source, CharSequence separator) { public Iterator iterator() { return new JoinIterator(source.iterator(), separator); } - + static final class JoinIterator extends IxSourceIterator { final CharSequence separator; - public JoinIterator(Iterator it, CharSequence separator) { + JoinIterator(Iterator it, CharSequence separator) { super(it); this.separator = separator; } - + @Override protected boolean moveNext() { CharSequence sep = separator; - + Iterator it = this.it; - + StringBuilder b = new StringBuilder(); - + if (it.hasNext()) { b.append(it.next()); - + while (it.hasNext()) { b.append(sep); b.append(it.next()); } } - + value = b.toString(); hasValue = true; done = true; diff --git a/src/main/java/ix/IxJust.java b/src/main/java/ix/IxJust.java index ba34558..b28fa2f 100644 --- a/src/main/java/ix/IxJust.java +++ b/src/main/java/ix/IxJust.java @@ -21,31 +21,31 @@ final class IxJust extends Ix implements IxScalarCallable { final T value; - - public IxJust(T value) { + + IxJust(T value) { this.value = value; } - + @Override public T call() { return value; } - + @Override public Iterator iterator() { return new JustIterator(value); } - + static final class JustIterator implements Iterator { final T value; - + boolean empty; - - public JustIterator(T value) { + + JustIterator(T value) { this.value = value; } - + @Override public boolean hasNext() { return !empty; @@ -59,7 +59,7 @@ public T next() { } throw new NoSuchElementException(); } - + @Override public void remove() { throw new UnsupportedOperationException(); diff --git a/src/main/java/ix/IxLift.java b/src/main/java/ix/IxLift.java index e3e14bc..0c4ec67 100644 --- a/src/main/java/ix/IxLift.java +++ b/src/main/java/ix/IxLift.java @@ -18,20 +18,18 @@ import java.util.Iterator; -import rx.functions.Func1; - final class IxLift extends IxSource { - final Func1, ? extends Iterator> lifter; - - public IxLift(Iterable source, Func1, ? extends Iterator> lifter) { + final IxFunction, ? extends Iterator> lifter; + + IxLift(Iterable source, IxFunction, ? extends Iterator> lifter) { super(source); this.lifter = lifter; } @Override public Iterator iterator() { - return lifter.call(source.iterator()); + return lifter.apply(source.iterator()); } } diff --git a/src/main/java/ix/IxMap.java b/src/main/java/ix/IxMap.java index b542f4f..684de67 100644 --- a/src/main/java/ix/IxMap.java +++ b/src/main/java/ix/IxMap.java @@ -18,13 +18,11 @@ import java.util.Iterator; -import rx.functions.Func1; - final class IxMap extends IxSource { - final Func1 mapper; - - public IxMap(Iterable source, Func1 mapper) { + final IxFunction mapper; + + IxMap(Iterable source, IxFunction mapper) { super(source); this.mapper = mapper; } @@ -35,12 +33,12 @@ public Iterator iterator() { } static final class MapIterator implements Iterator { - + final Iterator it; - - final Func1 mapper; - public MapIterator(Iterator it, Func1 mapper) { + final IxFunction mapper; + + MapIterator(Iterator it, IxFunction mapper) { this.it = it; this.mapper = mapper; } @@ -52,9 +50,9 @@ public boolean hasNext() { @Override public R next() { - return mapper.call(it.next()); + return mapper.apply(it.next()); } - + @Override public void remove() { it.remove(); diff --git a/src/main/java/ix/IxMaxInt.java b/src/main/java/ix/IxMaxInt.java index af7b419..394a340 100644 --- a/src/main/java/ix/IxMaxInt.java +++ b/src/main/java/ix/IxMaxInt.java @@ -20,7 +20,7 @@ final class IxMaxInt extends IxSource { - public IxMaxInt(Iterable source) { + IxMaxInt(Iterable source) { super(source); } @@ -31,7 +31,7 @@ public Iterator iterator() { static final class MaxIntIterator extends IxSourceIterator { - public MaxIntIterator(Iterator it) { + MaxIntIterator(Iterator it) { super(it); } @@ -47,12 +47,12 @@ protected boolean moveNext() { while (it.hasNext()) { sum = Math.max(sum, it.next()); } - + value = sum; hasValue = true; done = true; return true; } - + } } diff --git a/src/main/java/ix/IxMaxLong.java b/src/main/java/ix/IxMaxLong.java index e9877d3..652255d 100644 --- a/src/main/java/ix/IxMaxLong.java +++ b/src/main/java/ix/IxMaxLong.java @@ -20,7 +20,7 @@ final class IxMaxLong extends IxSource { - public IxMaxLong(Iterable source) { + IxMaxLong(Iterable source) { super(source); } @@ -31,7 +31,7 @@ public Iterator iterator() { static final class MaxLongIterator extends IxSourceIterator { - public MaxLongIterator(Iterator it) { + MaxLongIterator(Iterator it) { super(it); } @@ -47,12 +47,12 @@ protected boolean moveNext() { while (it.hasNext()) { sum = Math.max(sum, it.next()); } - + value = sum; hasValue = true; done = true; return true; } - + } } diff --git a/src/main/java/ix/IxMinInt.java b/src/main/java/ix/IxMinInt.java index f310560..0f5f627 100644 --- a/src/main/java/ix/IxMinInt.java +++ b/src/main/java/ix/IxMinInt.java @@ -20,7 +20,7 @@ final class IxMinInt extends IxSource { - public IxMinInt(Iterable source) { + IxMinInt(Iterable source) { super(source); } @@ -31,7 +31,7 @@ public Iterator iterator() { static final class MinIntIterator extends IxSourceIterator { - public MinIntIterator(Iterator it) { + MinIntIterator(Iterator it) { super(it); } @@ -47,12 +47,12 @@ protected boolean moveNext() { while (it.hasNext()) { sum = Math.min(sum, it.next()); } - + value = sum; hasValue = true; done = true; return true; } - + } } diff --git a/src/main/java/ix/IxMinLong.java b/src/main/java/ix/IxMinLong.java index 0f8670e..7a04e9f 100644 --- a/src/main/java/ix/IxMinLong.java +++ b/src/main/java/ix/IxMinLong.java @@ -20,7 +20,7 @@ final class IxMinLong extends IxSource { - public IxMinLong(Iterable source) { + IxMinLong(Iterable source) { super(source); } @@ -31,7 +31,7 @@ public Iterator iterator() { static final class MinLongIterator extends IxSourceIterator { - public MinLongIterator(Iterator it) { + MinLongIterator(Iterator it) { super(it); } @@ -47,12 +47,12 @@ protected boolean moveNext() { while (it.hasNext()) { sum = Math.min(sum, it.next()); } - + value = sum; hasValue = true; done = true; return true; } - + } } diff --git a/src/main/java/ix/IxMinMax.java b/src/main/java/ix/IxMinMax.java index 1adf261..d2e2e24 100644 --- a/src/main/java/ix/IxMinMax.java +++ b/src/main/java/ix/IxMinMax.java @@ -21,10 +21,10 @@ final class IxMinMax extends IxSource { final Comparator comparator; - + final int flag; - - public IxMinMax(Iterable source, Comparator comparator, int flag) { + + IxMinMax(Iterable source, Comparator comparator, int flag) { super(source); this.comparator = comparator; this.flag = flag; @@ -34,14 +34,14 @@ public IxMinMax(Iterable source, Comparator comparator, int flag) public Iterator iterator() { return new MinMaxIterator(source.iterator(), comparator, flag); } - + static final class MinMaxIterator extends IxSourceIterator { final Comparator comparator; - + final int flag; - - public MinMaxIterator(Iterator it, Comparator comparator, int flag) { + + MinMaxIterator(Iterator it, Comparator comparator, int flag) { super(it); this.comparator = comparator; this.flag = flag; @@ -50,16 +50,16 @@ public MinMaxIterator(Iterator it, Comparator comparator, int flag @Override protected boolean moveNext() { T v; - + Iterator it = this.it; - + if (!it.hasNext()) { done = true; return false; } - + v = it.next(); - + Comparator f = comparator; int g = flag; @@ -69,13 +69,13 @@ protected boolean moveNext() { v = w; } } - + value = v; hasValue = true; done = true; return true; } - + } } diff --git a/src/main/java/ix/IxOrderBy.java b/src/main/java/ix/IxOrderBy.java index a57c6df..b77e66a 100644 --- a/src/main/java/ix/IxOrderBy.java +++ b/src/main/java/ix/IxOrderBy.java @@ -18,17 +18,15 @@ import java.util.*; -import rx.functions.Func1; - final class IxOrderBy extends IxSource { - final Func1 keySelector; - + final IxFunction keySelector; + final Comparator comparator; - + final int flag; - - public IxOrderBy(Iterable source, Func1 keySelector, Comparator comparator, int flag) { + + IxOrderBy(Iterable source, IxFunction keySelector, Comparator comparator, int flag) { super(source); this.keySelector = keySelector; this.comparator = comparator; @@ -39,20 +37,20 @@ public IxOrderBy(Iterable source, Func1 keySelector, Comparator public Iterator iterator() { return new OrderByIterator(source.iterator(), keySelector, comparator, flag); } - + static final class OrderByIterator extends IxSourceIterator implements Comparator { - final Func1 keySelector; - + final IxFunction keySelector; + final Comparator comparator; final int flag; - + List values; - + int index; - - public OrderByIterator(Iterator it, Func1 keySelector, Comparator comparator, int flag) { + + OrderByIterator(Iterator it, IxFunction keySelector, Comparator comparator, int flag) { super(it); this.keySelector = keySelector; this.comparator = comparator; @@ -61,28 +59,28 @@ public OrderByIterator(Iterator it, Func1 keySelector, Comparat @Override protected boolean moveNext() { - + List list = values; - + if (list == null) { list = new ArrayList(); - + Iterator it = this.it; - + while (it.hasNext()) { list.add(it.next()); } - + if (list.isEmpty()) { done = true; return false; } - + Collections.sort(list, this); - + values = list; } - + int i = index; if (i != list.size()) { index = i + 1; @@ -94,11 +92,11 @@ protected boolean moveNext() { done = true; return false; } - + @Override public int compare(T o1, T o2) { - K k1 = keySelector.call(o1); - K k2 = keySelector.call(o2); + K k1 = keySelector.apply(o1); + K k2 = keySelector.apply(o2); return comparator.compare(k1, k2) * flag; } } diff --git a/src/main/java/ix/Pred.java b/src/main/java/ix/IxPredicate.java similarity index 70% rename from src/main/java/ix/Pred.java rename to src/main/java/ix/IxPredicate.java index 390f87f..3b81236 100644 --- a/src/main/java/ix/Pred.java +++ b/src/main/java/ix/IxPredicate.java @@ -17,15 +17,14 @@ package ix; /** - * A predicate functional interface to test a value and return a primitive - * boolean. - * @param the value to test + * A function callback with one input value and a boolean return value. + * @param the input value type */ -public interface Pred { +public interface IxPredicate { /** - * Test the given value. - * @param t the value to test - * @return true if the value passes the test + * Applies a function to the input value and returns a boolean value. + * @param t the input value + * @return the output boolean */ boolean test(T t); } diff --git a/src/main/java/ix/Pred2.java b/src/main/java/ix/IxPredicate2.java similarity index 64% rename from src/main/java/ix/Pred2.java rename to src/main/java/ix/IxPredicate2.java index e80f56f..1f39934 100644 --- a/src/main/java/ix/Pred2.java +++ b/src/main/java/ix/IxPredicate2.java @@ -17,17 +17,16 @@ package ix; /** - * A predicate functional interface to test a value and return a primitive - * boolean. - * @param the first value to test - * @param the second value to test + * A function callback with two input values and a boolean return value. + * @param the first input value type + * @param the second input value */ -public interface Pred2 { +public interface IxPredicate2 { /** - * Test the given value. - * @param t the first value to test - * @param u the second value to test - * @return true if the value passes the test + * Applies a function to the input value and returns a boolean value. + * @param t the first input value + * @param u the second input value + * @return the output boolean */ boolean test(T t, U u); } diff --git a/src/main/java/ix/IxPublish.java b/src/main/java/ix/IxPublish.java index 74651e6..4570ce0 100644 --- a/src/main/java/ix/IxPublish.java +++ b/src/main/java/ix/IxPublish.java @@ -21,8 +21,8 @@ final class IxPublish extends IxSource { Iterator current; - - public IxPublish(Iterable source) { + + IxPublish(Iterable source) { super(source); } diff --git a/src/main/java/ix/IxPublishSelector.java b/src/main/java/ix/IxPublishSelector.java index 7ae68d8..f03130e 100644 --- a/src/main/java/ix/IxPublishSelector.java +++ b/src/main/java/ix/IxPublishSelector.java @@ -18,13 +18,11 @@ import java.util.Iterator; -import rx.functions.Func1; - final class IxPublishSelector extends IxSource { - final Func1, ? extends Iterable> selector; - - public IxPublishSelector(Iterable source, Func1, ? extends Iterable> selector) { + final IxFunction, ? extends Iterable> selector; + + IxPublishSelector(Iterable source, IxFunction, ? extends Iterable> selector) { super(source); this.selector = selector; } @@ -32,18 +30,18 @@ public IxPublishSelector(Iterable source, Func1, ? extends Iter @SuppressWarnings("unchecked") @Override public Iterator iterator() { - - return (Iterator)selector.call(new PublishSelectorIterable(source.iterator())).iterator(); + + return (Iterator)selector.apply(new PublishSelectorIterable(source.iterator())).iterator(); } static final class PublishSelectorIterable extends Ix { - + final Iterator source; - public PublishSelectorIterable(Iterator source) { + PublishSelectorIterable(Iterator source) { this.source = source; } - + @Override public Iterator iterator() { return source; diff --git a/src/main/java/ix/IxRange.java b/src/main/java/ix/IxRange.java index 2aa8bcd..06ff9a9 100644 --- a/src/main/java/ix/IxRange.java +++ b/src/main/java/ix/IxRange.java @@ -21,26 +21,26 @@ final class IxRange extends Ix { final int start; - + final int end; - - public IxRange(int start, int count) { + + IxRange(int start, int count) { this.start = start; this.end = start + count; } - + @Override public Iterator iterator() { return new RangeIterator(start, end); } - + static final class RangeIterator implements Iterator { - + final int end; - + int index; - - public RangeIterator(int start, int end) { + + RangeIterator(int start, int end) { this.index = start; this.end = end; } @@ -59,7 +59,7 @@ public Integer next() { } throw new NoSuchElementException(); } - + @Override public void remove() { throw new UnsupportedOperationException(); diff --git a/src/main/java/ix/IxReduce.java b/src/main/java/ix/IxReduce.java index 8d28540..aa58af7 100644 --- a/src/main/java/ix/IxReduce.java +++ b/src/main/java/ix/IxReduce.java @@ -18,15 +18,13 @@ import java.util.Iterator; -import rx.functions.*; - final class IxReduce extends IxSource { - final Func0 initialFactory; - - final Func2 reducer; - - public IxReduce(Iterable source, Func0 initialFactory, Func2 reducer) { + final IxSupplier initialFactory; + + final IxFunction2 reducer; + + IxReduce(Iterable source, IxSupplier initialFactory, IxFunction2 reducer) { super(source); this.initialFactory = initialFactory; this.reducer = reducer; @@ -34,14 +32,14 @@ public IxReduce(Iterable source, Func0 initialFactory, Func2 redu @Override public Iterator iterator() { - return new CollectorIterator(source.iterator(), reducer, initialFactory.call()); + return new CollectorIterator(source.iterator(), reducer, initialFactory.get()); } static final class CollectorIterator extends IxSourceIterator { - final Func2 reducer; - - public CollectorIterator(Iterator it, Func2 reducer, C value) { + final IxFunction2 reducer; + + CollectorIterator(Iterator it, IxFunction2 reducer, C value) { super(it); this.reducer = reducer; this.value = value; @@ -50,15 +48,15 @@ public CollectorIterator(Iterator it, Func2 reducer, C value) { @Override protected boolean moveNext() { Iterator it = this.it; - - Func2 f = reducer; - + + IxFunction2 f = reducer; + C c = value; - + while (it.hasNext()) { - c = f.call(c, it.next()); + c = f.apply(c, it.next()); } - + value = c; hasValue = true; done = true; diff --git a/src/main/java/ix/IxRemove.java b/src/main/java/ix/IxRemove.java index ef2ba4c..fe99cd8 100644 --- a/src/main/java/ix/IxRemove.java +++ b/src/main/java/ix/IxRemove.java @@ -20,9 +20,9 @@ final class IxRemove extends IxSource { - final Pred predicate; - - public IxRemove(Iterable source, Pred predicate) { + final IxPredicate predicate; + + IxRemove(Iterable source, IxPredicate predicate) { super(source); this.predicate = predicate; } @@ -33,24 +33,24 @@ public Iterator iterator() { } static final class RemoveIterator extends IxSourceIterator { - final Pred predicate; + final IxPredicate predicate; - public RemoveIterator(Iterator it, Pred predicate) { + RemoveIterator(Iterator it, IxPredicate predicate) { super(it); this.predicate = predicate; } @Override protected boolean moveNext() { - + for (;;) { if (!it.hasNext()) { done = true; return false; } - + T v = it.next(); - + if (predicate.test(v)) { it.remove(); } else { @@ -60,7 +60,7 @@ protected boolean moveNext() { } } } - + @Override public void remove() { it.remove(); diff --git a/src/main/java/ix/IxRepeat.java b/src/main/java/ix/IxRepeat.java index 481af71..c06f8f0 100644 --- a/src/main/java/ix/IxRepeat.java +++ b/src/main/java/ix/IxRepeat.java @@ -21,8 +21,8 @@ final class IxRepeat extends Ix { final T value; - - public IxRepeat(T value) { + + IxRepeat(T value) { this.value = value; } @@ -32,23 +32,23 @@ public Iterator iterator() { } static final class RepeatIterator implements Iterator { - + final T value; - - public RepeatIterator(T value) { + + RepeatIterator(T value) { this.value = value; } - + @Override public boolean hasNext() { return true; } - + @Override public T next() { return value; } - + @Override public void remove() { throw new UnsupportedOperationException(); diff --git a/src/main/java/ix/IxRepeatCount.java b/src/main/java/ix/IxRepeatCount.java index 4e07497..c974425 100644 --- a/src/main/java/ix/IxRepeatCount.java +++ b/src/main/java/ix/IxRepeatCount.java @@ -21,10 +21,10 @@ final class IxRepeatCount extends Ix { final T value; - + final long count; - - public IxRepeatCount(T value, long count) { + + IxRepeatCount(T value, long count) { this.value = value; this.count = count; } @@ -35,21 +35,21 @@ public Iterator iterator() { } static final class RepeatCountIterator implements Iterator { - + final T value; - + long count; - - public RepeatCountIterator(T value, long count) { + + RepeatCountIterator(T value, long count) { this.value = value; this.count = count; } - + @Override public boolean hasNext() { return count != 0L; } - + @Override public T next() { long c = count; @@ -59,7 +59,7 @@ public T next() { } throw new NoSuchElementException(); } - + @Override public void remove() { throw new UnsupportedOperationException(); diff --git a/src/main/java/ix/IxRepeatPredicate.java b/src/main/java/ix/IxRepeatPredicate.java index c6780e0..8c21013 100644 --- a/src/main/java/ix/IxRepeatPredicate.java +++ b/src/main/java/ix/IxRepeatPredicate.java @@ -16,17 +16,17 @@ package ix; -import java.util.*; +import java.util.Iterator; final class IxRepeatPredicate extends Ix { final T value; - + final long count; - - final Pred0 stopPredicate; - - public IxRepeatPredicate(T value, long count, Pred0 stopPredicate) { + + final IxBooleanSupplier stopPredicate; + + IxRepeatPredicate(T value, long count, IxBooleanSupplier stopPredicate) { this.value = value; this.stopPredicate = stopPredicate; this.count = count; @@ -40,17 +40,17 @@ public Iterator iterator() { static final class RepeatPredicateIterator extends IxBaseIterator { final T valueToRepeat; - + long count; - - final Pred0 stopPredicate; - - public RepeatPredicateIterator(T value, long count, Pred0 stopPredicate) { + + final IxBooleanSupplier stopPredicate; + + RepeatPredicateIterator(T value, long count, IxBooleanSupplier stopPredicate) { this.valueToRepeat = value; this.stopPredicate = stopPredicate; this.count = count; } - + @Override protected boolean moveNext() { long c = count--; @@ -62,6 +62,6 @@ protected boolean moveNext() { done = true; return false; } - + } } diff --git a/src/main/java/ix/IxReplay.java b/src/main/java/ix/IxReplay.java index 7226409..9f588ba 100644 --- a/src/main/java/ix/IxReplay.java +++ b/src/main/java/ix/IxReplay.java @@ -23,8 +23,8 @@ final class IxReplay extends IxSource { List list; Iterator it; - - public IxReplay(Iterable source) { + + IxReplay(Iterable source) { super(source); } @@ -35,37 +35,37 @@ public Iterator iterator() { } return new ReplayIterator(this); } - + boolean moveNext() { if (!it.hasNext()) { return false; } - + List list = this.list; if (list == null) { list = new ArrayList(); this.list = list; } - + list.add(it.next()); return true; } static final class ReplayIterator extends IxBaseIterator { - + final IxReplay parent; - + int index; - public ReplayIterator(IxReplay parent) { + ReplayIterator(IxReplay parent) { this.parent = parent; } - + @Override protected boolean moveNext() { int i = index; List list = parent.list; - + if (list == null || i == list.size()) { if (!parent.moveNext()) { done = true; diff --git a/src/main/java/ix/IxReplaySelector.java b/src/main/java/ix/IxReplaySelector.java index d8041cb..943a835 100644 --- a/src/main/java/ix/IxReplaySelector.java +++ b/src/main/java/ix/IxReplaySelector.java @@ -18,13 +18,11 @@ import java.util.Iterator; -import rx.functions.Func1; - final class IxReplaySelector extends IxSource { - final Func1, ? extends Iterable> selector; - - public IxReplaySelector(Iterable source, Func1, ? extends Iterable> selector) { + final IxFunction, ? extends Iterable> selector; + + IxReplaySelector(Iterable source, IxFunction, ? extends Iterable> selector) { super(source); this.selector = selector; } @@ -32,7 +30,7 @@ public IxReplaySelector(Iterable source, Func1, ? extends Itera @SuppressWarnings("unchecked") @Override public Iterator iterator() { - - return (Iterator)selector.call(new IxReplay(source)).iterator(); + + return (Iterator)selector.apply(new IxReplay(source)).iterator(); } } diff --git a/src/main/java/ix/IxReplaySize.java b/src/main/java/ix/IxReplaySize.java index 778e248..edfc5e5 100644 --- a/src/main/java/ix/IxReplaySize.java +++ b/src/main/java/ix/IxReplaySize.java @@ -21,21 +21,21 @@ final class IxReplaySize extends IxSource { final int maxSize; - + Iterator it; - + Node head; - + Node tail; int size; - - public IxReplaySize(Iterable source, int maxSize) { + + IxReplaySize(Iterable source, int maxSize) { super(source); this.maxSize = maxSize; this.head = this.tail = new Node(null); } - + @Override public Iterator iterator() { if (it == null) { @@ -43,16 +43,16 @@ public Iterator iterator() { } return new ReplaySizeIterator(this, head); } - + boolean moveNext() { if (!it.hasNext()) { return false; } - + Node n = new Node(it.next()); tail.next = n; tail = n; - + int s = size; if (s != maxSize) { size = s + 1; @@ -61,23 +61,23 @@ boolean moveNext() { } return true; } - + static final class Node { final T value; - + Node next; - - public Node(T value) { + + Node(T value) { this.value = value; } } - + static final class ReplaySizeIterator extends IxBaseIterator { final IxReplaySize parent; Node node; - - public ReplaySizeIterator(IxReplaySize parent, Node node) { + + ReplaySizeIterator(IxReplaySize parent, Node node) { this.parent = parent; this.node = node; } @@ -85,7 +85,7 @@ public ReplaySizeIterator(IxReplaySize parent, Node node) { @Override protected boolean moveNext() { Node n = node; - + if (n.next == null) { if (!parent.moveNext()) { done = true; @@ -93,11 +93,11 @@ protected boolean moveNext() { } } n = n.next; - + value = n.value; hasValue = true; node = n; - + return true; } } diff --git a/src/main/java/ix/IxReplaySizeSelector.java b/src/main/java/ix/IxReplaySizeSelector.java index 11dca1d..fa52393 100644 --- a/src/main/java/ix/IxReplaySizeSelector.java +++ b/src/main/java/ix/IxReplaySizeSelector.java @@ -18,16 +18,14 @@ import java.util.Iterator; -import rx.functions.Func1; - final class IxReplaySizeSelector extends IxSource { final int maxSize; - - final Func1, ? extends Iterable> selector; - - public IxReplaySizeSelector(Iterable source, int maxSize, - Func1, ? extends Iterable> selector) { + + final IxFunction, ? extends Iterable> selector; + + IxReplaySizeSelector(Iterable source, int maxSize, + IxFunction, ? extends Iterable> selector) { super(source); this.maxSize = maxSize; this.selector = selector; @@ -36,7 +34,7 @@ public IxReplaySizeSelector(Iterable source, int maxSize, @SuppressWarnings("unchecked") @Override public Iterator iterator() { - - return (Iterator)selector.call(new IxReplaySize(source, maxSize)).iterator(); + + return (Iterator)selector.apply(new IxReplaySize(source, maxSize)).iterator(); } } diff --git a/src/main/java/ix/IxRetain.java b/src/main/java/ix/IxRetain.java index 6be2f4a..d467853 100644 --- a/src/main/java/ix/IxRetain.java +++ b/src/main/java/ix/IxRetain.java @@ -20,9 +20,9 @@ final class IxRetain extends IxSource { - final Pred predicate; - - public IxRetain(Iterable source, Pred predicate) { + final IxPredicate predicate; + + IxRetain(Iterable source, IxPredicate predicate) { super(source); this.predicate = predicate; } @@ -33,24 +33,24 @@ public Iterator iterator() { } static final class RetainIterator extends IxSourceIterator { - final Pred predicate; + final IxPredicate predicate; - public RetainIterator(Iterator it, Pred predicate) { + RetainIterator(Iterator it, IxPredicate predicate) { super(it); this.predicate = predicate; } @Override protected boolean moveNext() { - + for (;;) { if (!it.hasNext()) { done = true; return false; } - + T v = it.next(); - + if (predicate.test(v)) { value = v; hasValue = true; @@ -60,7 +60,7 @@ protected boolean moveNext() { } } } - + @Override public void remove() { it.remove(); diff --git a/src/main/java/ix/IxReverse.java b/src/main/java/ix/IxReverse.java index 013ffb9..6faf720 100644 --- a/src/main/java/ix/IxReverse.java +++ b/src/main/java/ix/IxReverse.java @@ -20,7 +20,7 @@ final class IxReverse extends IxSource { - public IxReverse(Iterable source) { + IxReverse(Iterable source) { super(source); } @@ -32,17 +32,17 @@ public Iterator iterator() { static final class ReverseIterator extends IxSourceIterator { List list; - + int index; - - public ReverseIterator(Iterator it) { + + ReverseIterator(Iterator it) { super(it); } - + @Override protected boolean moveNext() { List list = this.list; - + if (list == null) { list = new ArrayList(); this.list = list; @@ -51,7 +51,7 @@ protected boolean moveNext() { } index = list.size(); } - + int i = index; if (i == 0) { done = true; diff --git a/src/main/java/ix/IxScan.java b/src/main/java/ix/IxScan.java index d227995..e618c34 100644 --- a/src/main/java/ix/IxScan.java +++ b/src/main/java/ix/IxScan.java @@ -18,13 +18,11 @@ import java.util.Iterator; -import rx.functions.Func2; - final class IxScan extends IxSource { - final Func2 scanner; - - public IxScan(Iterable source, Func2 scanner) { + final IxFunction2 scanner; + + IxScan(Iterable source, IxFunction2 scanner) { super(source); this.scanner = scanner; } @@ -35,25 +33,25 @@ public Iterator iterator() { } static final class ScanIterator extends IxSourceIterator { - - final Func2 scanner; + + final IxFunction2 scanner; T last; - + boolean once; - - public ScanIterator(Iterator it, Func2 scanner) { + + ScanIterator(Iterator it, IxFunction2 scanner) { super(it); this.scanner = scanner; } - + @Override protected boolean moveNext() { if (!once) { if (it.hasNext()) { once = true; T v = it.next(); - + last = v; value = v; hasValue = true; @@ -62,17 +60,17 @@ protected boolean moveNext() { done = true; return false; } - + if (it.hasNext()) { T v = it.next(); - - v = scanner.call(last, v); + + v = scanner.apply(last, v); last = v; value = v; hasValue = true; return true; } - + last = null; done = true; return false; diff --git a/src/main/java/ix/IxScanSeed.java b/src/main/java/ix/IxScanSeed.java index c44778a..d02bbf3 100644 --- a/src/main/java/ix/IxScanSeed.java +++ b/src/main/java/ix/IxScanSeed.java @@ -18,15 +18,13 @@ import java.util.Iterator; -import rx.functions.*; - final class IxScanSeed extends IxSource { - final Func0 seed; - - final Func2 scanner; - - public IxScanSeed(Iterable source, Func0 seed, Func2 scanner) { + final IxSupplier seed; + + final IxFunction2 scanner; + + IxScanSeed(Iterable source, IxSupplier seed, IxFunction2 scanner) { super(source); this.seed = seed; this.scanner = scanner; @@ -34,22 +32,22 @@ public IxScanSeed(Iterable source, Func0 seed, Func2 scanner) { @Override public Iterator iterator() { - return new ScanSeedIterator(source.iterator(), seed.call(), scanner); + return new ScanSeedIterator(source.iterator(), seed.get(), scanner); } - + static final class ScanSeedIterator extends IxSourceIterator { - final Func2 scanner; + final IxFunction2 scanner; R accumulator; - + boolean once; - public ScanSeedIterator(Iterator it, R accumulator, Func2 scanner) { + ScanSeedIterator(Iterator it, R accumulator, IxFunction2 scanner) { super(it); this.accumulator = accumulator; this.scanner = scanner; } - + @Override protected boolean moveNext() { if (!once) { @@ -58,17 +56,17 @@ protected boolean moveNext() { hasValue = true; return true; } - + if (it.hasNext()) { - - R v = scanner.call(accumulator, it.next()); - + + R v = scanner.apply(accumulator, it.next()); + accumulator = v; value = v; hasValue = true; return true; } - + accumulator = null; done = true; return false; diff --git a/src/main/java/ix/IxSequenceEqual.java b/src/main/java/ix/IxSequenceEqual.java index caf74cd..b26f1e5 100644 --- a/src/main/java/ix/IxSequenceEqual.java +++ b/src/main/java/ix/IxSequenceEqual.java @@ -21,11 +21,11 @@ final class IxSequenceEqual extends IxSource { final Iterable other; - - final Pred2 comparer; - - public IxSequenceEqual(Iterable source, Iterable other, - Pred2 comparer) { + + final IxPredicate2 comparer; + + IxSequenceEqual(Iterable source, Iterable other, + IxPredicate2 comparer) { super(source); this.other = other; this.comparer = comparer; @@ -35,15 +35,15 @@ public IxSequenceEqual(Iterable source, Iterable other, public Iterator iterator() { return new SequenceEqualIterator(source.iterator(), other.iterator(), comparer); } - + static final class SequenceEqualIterator extends IxSourceIterator { - + final Iterator other; - final Pred2 comparer; - - public SequenceEqualIterator(Iterator it, Iterator other, - Pred2 comparer) { + final IxPredicate2 comparer; + + SequenceEqualIterator(Iterator it, Iterator other, + IxPredicate2 comparer) { super(it); this.other = other; this.comparer = comparer; @@ -51,19 +51,19 @@ public SequenceEqualIterator(Iterator it, Iterator other, @Override protected boolean moveNext() { - + Iterator it2 = it; - + while (it2.hasNext()) { - + T v = it2.next(); - + if (other.hasNext()) { T u = other.next(); - + if (!comparer.test(v, u)) { - + value = false; hasValue = true; done = true; @@ -82,14 +82,14 @@ protected boolean moveNext() { done = true; return true; } - + value = true; hasValue = true; done = true; return true; } - - + + } } diff --git a/src/main/java/ix/IxSkip.java b/src/main/java/ix/IxSkip.java index 2c319d2..ef56e1f 100644 --- a/src/main/java/ix/IxSkip.java +++ b/src/main/java/ix/IxSkip.java @@ -21,8 +21,8 @@ final class IxSkip extends IxSource { final int n; - - public IxSkip(Iterable source, int n) { + + IxSkip(Iterable source, int n) { super(source); this.n = n; } @@ -35,7 +35,8 @@ public Iterator iterator() { static final class SkipIterator extends IxSourceIterator { int n; - public SkipIterator(Iterator it, int n) { + + SkipIterator(Iterator it, int n) { super(it); this.n = n; } @@ -43,7 +44,7 @@ public SkipIterator(Iterator it, int n) { protected boolean moveNext() { Iterator it = this.it; int n = this.n; - + if (n != 0) { while (n != 0) { if (it.hasNext()) { @@ -64,7 +65,7 @@ protected boolean moveNext() { done = true; return false; } - - + + } } diff --git a/src/main/java/ix/IxSkipLast.java b/src/main/java/ix/IxSkipLast.java index b8cbc31..09e4aa2 100644 --- a/src/main/java/ix/IxSkipLast.java +++ b/src/main/java/ix/IxSkipLast.java @@ -21,8 +21,8 @@ final class IxSkipLast extends IxSource { final int n; - - public IxSkipLast(Iterable source, int n) { + + IxSkipLast(Iterable source, int n) { super(source); this.n = n; } @@ -31,14 +31,14 @@ public IxSkipLast(Iterable source, int n) { public Iterator iterator() { return new SkipLastIterator(source.iterator(), n); } - + static final class SkipLastIterator extends IxSourceQueuedIterator { final int n; - + int size; - - public SkipLastIterator(Iterator it, int n) { + + SkipLastIterator(Iterator it, int n) { super(it); this.n = n; } @@ -47,13 +47,13 @@ public SkipLastIterator(Iterator it, int n) { protected boolean moveNext() { int s = size; int n = this.n; - + Iterator it = this.it; if (!it.hasNext()) { done = true; return false; } - + if (s != n) { while (s != n) { offer(toObject(it.next())); @@ -70,9 +70,9 @@ protected boolean moveNext() { offer(toObject(it.next())); hasValue = true; - + return true; } - + } } diff --git a/src/main/java/ix/IxSkipWhile.java b/src/main/java/ix/IxSkipWhile.java index d17f91c..158ea62 100644 --- a/src/main/java/ix/IxSkipWhile.java +++ b/src/main/java/ix/IxSkipWhile.java @@ -20,9 +20,9 @@ final class IxSkipWhile extends IxSource { - final Pred predicate; - - public IxSkipWhile(Iterable source, Pred predicate) { + final IxPredicate predicate; + + IxSkipWhile(Iterable source, IxPredicate predicate) { super(source); this.predicate = predicate; } @@ -31,21 +31,21 @@ public IxSkipWhile(Iterable source, Pred predicate) { public Iterator iterator() { return new SkipWhileIterator(source.iterator(), predicate); } - + static final class SkipWhileIterator extends IxSourceIterator { - final Pred predicate; + final IxPredicate predicate; + + boolean passThrough; - boolean passthrough; - - public SkipWhileIterator(Iterator it, Pred predicate) { + SkipWhileIterator(Iterator it, IxPredicate predicate) { super(it); this.predicate = predicate; } @Override protected boolean moveNext() { - if (passthrough) { + if (passThrough) { if (it.hasNext()) { hasValue = true; value = it.next(); @@ -54,21 +54,21 @@ protected boolean moveNext() { done = true; return false; } - + while (it.hasNext()) { T v = it.next(); if (!predicate.test(v)) { - passthrough = true; + passThrough = true; hasValue = true; value = v; return true; } } - + done = true; return false; } - + @Override public void remove() { it.remove(); diff --git a/src/main/java/ix/IxSource.java b/src/main/java/ix/IxSource.java index 4ef6f3c..f3a0364 100644 --- a/src/main/java/ix/IxSource.java +++ b/src/main/java/ix/IxSource.java @@ -17,16 +17,16 @@ package ix; /** - * Abstract base class for Ix operators that take a source Iterable. + * Abstract base class for Ix operators that take a source Iterable. * @param the source value type * @param the result value type */ abstract class IxSource extends Ix { protected final Iterable source; - - public IxSource(Iterable source) { + + IxSource(Iterable source) { this.source = source; } - + } diff --git a/src/main/java/ix/IxSourceIterator.java b/src/main/java/ix/IxSourceIterator.java index e7b87c6..da541fb 100644 --- a/src/main/java/ix/IxSourceIterator.java +++ b/src/main/java/ix/IxSourceIterator.java @@ -29,7 +29,7 @@ public abstract class IxSourceIterator extends IxBaseIterator { /** The upstream's iterator. */ protected final Iterator it; - + public IxSourceIterator(Iterator it) { this.it = it; } diff --git a/src/main/java/ix/IxSourceQueuedIterator.java b/src/main/java/ix/IxSourceQueuedIterator.java index 05e10e7..c1584a5 100644 --- a/src/main/java/ix/IxSourceQueuedIterator.java +++ b/src/main/java/ix/IxSourceQueuedIterator.java @@ -18,8 +18,6 @@ import java.util.Iterator; -import rx.functions.*; - /** * A base iterator that extends a custom ArrayDeque, references an upstream iterator * and manages the state between hasNext() and the next() calls; plus defines @@ -28,21 +26,21 @@ * @param the queued element types * @param the result value type */ -public abstract class IxSourceQueuedIterator +public abstract class IxSourceQueuedIterator extends IxSourceIterator { - protected static final Object NULL = new Object(); - + protected static final Object NULL = new Object(); + private Object[] array; - + private int producerIndex; - + private int consumerIndex; - + public IxSourceQueuedIterator(Iterator it) { super(it); } - + /** * Cast the value into an object and turn * a null value into a sentinel value. @@ -53,7 +51,7 @@ public IxSourceQueuedIterator(Iterator it) { protected final Object toObject(U value) { return value != null ? value : NULL; } - + /** * Cast the object back to a typed value. * @param value the value to cast back @@ -63,7 +61,7 @@ protected final Object toObject(U value) { protected final U fromObject(Object value) { return value == NULL ? null : (U)value; } - + protected final boolean offer(Object value) { if (value == null) { throw new NullPointerException("The queue doesn't support null values."); @@ -75,7 +73,7 @@ protected final boolean offer(Object value) { } int mask = a.length - 1; int pi = producerIndex; - + int offset = pi & mask; if (a[offset] != null) { int newLen = mask * 2 + 2; @@ -93,14 +91,14 @@ protected final boolean offer(Object value) { } return true; } - + protected final Object poll() { Object[] a = array; if (a != null) { int m = a.length - 1; int ci = consumerIndex; int offset = ci & m; - + Object v = a[offset]; if (v != null) { a[offset] = null; @@ -110,30 +108,30 @@ protected final Object poll() { } return null; } - + protected final Object peek() { Object[] a = array; if (a != null) { int m = a.length - 1; int ci = consumerIndex; int offset = ci & m; - + return a[offset]; } return null; } - + protected final boolean isEmpty() { return consumerIndex == producerIndex; } - + protected final void clear() { array = null; consumerIndex = 0; producerIndex = 0; } - - protected final void foreach(Action2 action, S state) { + + protected final void foreach(IxConsumer2 action, S state) { Object[] a = array; if (a != null) { int m = a.length - 1; @@ -141,7 +139,7 @@ protected final void foreach(Action2 action, S state) { for (int ci = consumerIndex; ci != pi; ci++) { int offset = ci & m; Object o = a[offset]; - action.call(fromObject(o), state); + action.accept(fromObject(o), state); } } } diff --git a/src/main/java/ix/IxSplit.java b/src/main/java/ix/IxSplit.java index bee3e0a..117e8d6 100644 --- a/src/main/java/ix/IxSplit.java +++ b/src/main/java/ix/IxSplit.java @@ -21,10 +21,10 @@ final class IxSplit extends Ix { final String string; - + final String by; - - public IxSplit(String string, String by) { + + IxSplit(String string, String by) { this.string = string; this.by = by; } @@ -36,21 +36,21 @@ public Iterator iterator() { static final class SplitIterator extends IxBaseIterator { final String string; - + final String by; int index; - public SplitIterator(String string, String by) { + SplitIterator(String string, String by) { this.string = string; this.by = by; } - + @Override protected boolean moveNext() { int i = index; int j = string.indexOf(by, i); - + if (j < 0) { value = string.substring(i); hasValue = true; diff --git a/src/main/java/ix/IxSumInt.java b/src/main/java/ix/IxSumInt.java index 897885e..bb312d6 100644 --- a/src/main/java/ix/IxSumInt.java +++ b/src/main/java/ix/IxSumInt.java @@ -20,7 +20,7 @@ final class IxSumInt extends IxSource { - public IxSumInt(Iterable source) { + IxSumInt(Iterable source) { super(source); } @@ -31,7 +31,7 @@ public Iterator iterator() { static final class SumIntIterator extends IxSourceIterator { - public SumIntIterator(Iterator it) { + SumIntIterator(Iterator it) { super(it); } @@ -47,12 +47,12 @@ protected boolean moveNext() { while (it.hasNext()) { sum += it.next(); } - + value = sum; hasValue = true; done = true; return true; } - + } } diff --git a/src/main/java/ix/IxSumLong.java b/src/main/java/ix/IxSumLong.java index 8a6e2c6..6e9f7ab 100644 --- a/src/main/java/ix/IxSumLong.java +++ b/src/main/java/ix/IxSumLong.java @@ -20,7 +20,7 @@ final class IxSumLong extends IxSource { - public IxSumLong(Iterable source) { + IxSumLong(Iterable source) { super(source); } @@ -31,7 +31,7 @@ public Iterator iterator() { static final class SumLongIterator extends IxSourceIterator { - public SumLongIterator(Iterator it) { + SumLongIterator(Iterator it) { super(it); } @@ -47,12 +47,12 @@ protected boolean moveNext() { while (it.hasNext()) { sum += it.next(); } - + value = sum; hasValue = true; done = true; return true; } - + } } diff --git a/src/main/java/ix/IxSupplier.java b/src/main/java/ix/IxSupplier.java new file mode 100644 index 0000000..23df3fb --- /dev/null +++ b/src/main/java/ix/IxSupplier.java @@ -0,0 +1,29 @@ +/* + * Copyright 2011-2016 David Karnok + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ix; + +/** + * A function callback with no inputs and one output value. + * @param the output value type + */ +public interface IxSupplier { + /** + * Calls the function which returns a value. + * @return the output value + */ + R get(); +} diff --git a/src/main/java/ix/IxSwitchIfEmpty.java b/src/main/java/ix/IxSwitchIfEmpty.java index bd43a9c..aa4d6dd 100644 --- a/src/main/java/ix/IxSwitchIfEmpty.java +++ b/src/main/java/ix/IxSwitchIfEmpty.java @@ -22,7 +22,7 @@ final class IxSwitchIfEmpty extends IxSource { final Iterable other; - public IxSwitchIfEmpty(Iterable source, Iterable other) { + IxSwitchIfEmpty(Iterable source, Iterable other) { super(source); this.other = other; } @@ -40,7 +40,7 @@ static final class SwitchIfEmptyIterator extends IxSourceIterator { boolean nonEmpty; - public SwitchIfEmptyIterator(Iterator it, Iterable other) { + SwitchIfEmptyIterator(Iterator it, Iterable other) { super(it); this.other = other; } @@ -57,7 +57,7 @@ protected boolean moveNext() { done = true; return false; } - + if (nonEmpty) { if (it.hasNext()) { value = it.next(); @@ -67,14 +67,14 @@ protected boolean moveNext() { done = true; return false; } - + if (it.hasNext()) { nonEmpty = true; value = it.next(); hasValue = true; return true; } - + ot = other.iterator(); otherIterator = ot; if (ot.hasNext()) { diff --git a/src/main/java/ix/IxTake.java b/src/main/java/ix/IxTake.java index 93e0ca6..698171c 100644 --- a/src/main/java/ix/IxTake.java +++ b/src/main/java/ix/IxTake.java @@ -21,8 +21,8 @@ final class IxTake extends IxSource { final int n; - - public IxTake(Iterable source, int n) { + + IxTake(Iterable source, int n) { super(source); this.n = n; } @@ -31,15 +31,16 @@ public IxTake(Iterable source, int n) { public Iterator iterator() { return new TakeIterator(source.iterator(), n); } - + static final class TakeIterator extends IxSourceIterator { int n; - public TakeIterator(Iterator it, int n) { + + TakeIterator(Iterator it, int n) { super(it); this.n = n; } - + @Override protected boolean moveNext() { int n = this.n; @@ -47,14 +48,14 @@ protected boolean moveNext() { done = true; return false; } - + value = it.next(); hasValue = true; this.n = n - 1; - + return true; } - + @Override public void remove() { it.remove(); diff --git a/src/main/java/ix/IxTakeLast.java b/src/main/java/ix/IxTakeLast.java index 35bff0a..278a354 100644 --- a/src/main/java/ix/IxTakeLast.java +++ b/src/main/java/ix/IxTakeLast.java @@ -21,8 +21,8 @@ final class IxTakeLast extends IxSource { final int n; - - public IxTakeLast(Iterable source, int n) { + + IxTakeLast(Iterable source, int n) { super(source); this.n = n; } @@ -31,16 +31,16 @@ public IxTakeLast(Iterable source, int n) { public Iterator iterator() { return new TakeLastIterator(source.iterator(), n); } - + static final class TakeLastIterator extends IxSourceQueuedIterator { int n; - - public TakeLastIterator(Iterator it, int n) { + + TakeLastIterator(Iterator it, int n) { super(it); this.n = n; } - + @Override protected boolean moveNext() { @@ -57,7 +57,7 @@ protected boolean moveNext() { } this.n = n; } - + Object o = poll(); if (o != null) { value = fromObject(o); diff --git a/src/main/java/ix/IxTakeUntil.java b/src/main/java/ix/IxTakeUntil.java index 38f61fa..ff89ad4 100644 --- a/src/main/java/ix/IxTakeUntil.java +++ b/src/main/java/ix/IxTakeUntil.java @@ -20,9 +20,9 @@ final class IxTakeUntil extends IxSource { - final Pred predicate; - - public IxTakeUntil(Iterable source, Pred predicate) { + final IxPredicate predicate; + + IxTakeUntil(Iterable source, IxPredicate predicate) { super(source); this.predicate = predicate; } @@ -31,12 +31,12 @@ public IxTakeUntil(Iterable source, Pred predicate) { public Iterator iterator() { return new TakeUntilIterator(source.iterator(), predicate); } - + static final class TakeUntilIterator extends IxSourceIterator { - final Pred predicate; + final IxPredicate predicate; - public TakeUntilIterator(Iterator it, Pred predicate) { + TakeUntilIterator(Iterator it, IxPredicate predicate) { super(it); this.predicate = predicate; } @@ -55,7 +55,7 @@ protected boolean moveNext() { done = true; return false; } - + @Override public void remove() { it.remove(); diff --git a/src/main/java/ix/IxTakeWhile.java b/src/main/java/ix/IxTakeWhile.java index 438f966..5da9258 100644 --- a/src/main/java/ix/IxTakeWhile.java +++ b/src/main/java/ix/IxTakeWhile.java @@ -20,9 +20,9 @@ final class IxTakeWhile extends IxSource { - final Pred predicate; - - public IxTakeWhile(Iterable source, Pred predicate) { + final IxPredicate predicate; + + IxTakeWhile(Iterable source, IxPredicate predicate) { super(source); this.predicate = predicate; } @@ -31,12 +31,12 @@ public IxTakeWhile(Iterable source, Pred predicate) { public Iterator iterator() { return new TakeWhileIterator(source.iterator(), predicate); } - + static final class TakeWhileIterator extends IxSourceIterator { - final Pred predicate; + final IxPredicate predicate; - public TakeWhileIterator(Iterator it, Pred predicate) { + TakeWhileIterator(Iterator it, IxPredicate predicate) { super(it); this.predicate = predicate; } @@ -56,7 +56,7 @@ protected boolean moveNext() { done = true; return false; } - + @Override public void remove() { it.remove(); diff --git a/src/main/java/ix/IxToMap.java b/src/main/java/ix/IxToMap.java index deb8144..f9c3527 100644 --- a/src/main/java/ix/IxToMap.java +++ b/src/main/java/ix/IxToMap.java @@ -18,15 +18,13 @@ import java.util.*; -import rx.functions.Func1; - final class IxToMap extends IxSource> { - final Func1 keySelector; - - final Func1 valueSelector; + final IxFunction keySelector; + + final IxFunction valueSelector; - public IxToMap(Iterable source, Func1 keySelector, Func1 valueSelector) { + IxToMap(Iterable source, IxFunction keySelector, IxFunction valueSelector) { super(source); this.keySelector = keySelector; this.valueSelector = valueSelector; @@ -36,14 +34,14 @@ public IxToMap(Iterable source, Func1 keySelector, Fu public Iterator> iterator() { return new ToMapIterator(source.iterator(), keySelector, valueSelector); } - + static final class ToMapIterator extends IxSourceIterator> { - final Func1 keySelector; - - final Func1 valueSelector; + final IxFunction keySelector; - public ToMapIterator(Iterator it, Func1 keySelector, Func1 valueSelector) { + final IxFunction valueSelector; + + ToMapIterator(Iterator it, IxFunction keySelector, IxFunction valueSelector) { super(it); this.keySelector = keySelector; this.valueSelector = valueSelector; @@ -52,23 +50,23 @@ public ToMapIterator(Iterator it, Func1 keySelector, @Override protected boolean moveNext() { Iterator it = this.it; - - Func1 keySelector = this.keySelector; - - Func1 valueSelector = this.valueSelector; - + + IxFunction keySelector = this.keySelector; + + IxFunction valueSelector = this.valueSelector; + Map result = new HashMap(); - + while (it.hasNext()) { T t = it.next(); - - K k = keySelector.call(t); - - V v = valueSelector.call(t); - + + K k = keySelector.apply(t); + + V v = valueSelector.apply(t); + result.put(k, v); } - + value = result; hasValue = true; done = true; diff --git a/src/main/java/ix/IxToMultimap.java b/src/main/java/ix/IxToMultimap.java index b4baecd..a01c5db 100644 --- a/src/main/java/ix/IxToMultimap.java +++ b/src/main/java/ix/IxToMultimap.java @@ -18,15 +18,13 @@ import java.util.*; -import rx.functions.Func1; - final class IxToMultimap extends IxSource>> { - final Func1 keySelector; - - final Func1 valueSelector; + final IxFunction keySelector; + + final IxFunction valueSelector; - public IxToMultimap(Iterable source, Func1 keySelector, Func1 valueSelector) { + IxToMultimap(Iterable source, IxFunction keySelector, IxFunction valueSelector) { super(source); this.keySelector = keySelector; this.valueSelector = valueSelector; @@ -36,14 +34,14 @@ public IxToMultimap(Iterable source, Func1 keySelecto public Iterator>> iterator() { return new ToMapIterator(source.iterator(), keySelector, valueSelector); } - + static final class ToMapIterator extends IxSourceIterator>> { - final Func1 keySelector; - - final Func1 valueSelector; + final IxFunction keySelector; + + final IxFunction valueSelector; - public ToMapIterator(Iterator it, Func1 keySelector, Func1 valueSelector) { + ToMapIterator(Iterator it, IxFunction keySelector, IxFunction valueSelector) { super(it); this.keySelector = keySelector; this.valueSelector = valueSelector; @@ -52,29 +50,29 @@ public ToMapIterator(Iterator it, Func1 keySelector, @Override protected boolean moveNext() { Iterator it = this.it; - - Func1 keySelector = this.keySelector; - - Func1 valueSelector = this.valueSelector; - + + IxFunction keySelector = this.keySelector; + + IxFunction valueSelector = this.valueSelector; + Map> result = new HashMap>(); - + while (it.hasNext()) { T t = it.next(); - - K k = keySelector.call(t); - + + K k = keySelector.apply(t); + Collection coll = result.get(k); if (coll == null) { coll = new ArrayList(); result.put(k, coll); } - - V v = valueSelector.call(t); - + + V v = valueSelector.apply(t); + coll.add(v); } - + value = result; hasValue = true; done = true; diff --git a/src/main/java/ix/IxToSet.java b/src/main/java/ix/IxToSet.java index 7924ee3..b3e6983 100644 --- a/src/main/java/ix/IxToSet.java +++ b/src/main/java/ix/IxToSet.java @@ -20,7 +20,7 @@ final class IxToSet extends IxSource> { - public IxToSet(Iterable source) { + IxToSet(Iterable source) { super(source); } @@ -28,24 +28,24 @@ public IxToSet(Iterable source) { public Iterator> iterator() { return new ToSetIterator(source.iterator()); } - + static final class ToSetIterator extends IxSourceIterator> { - public ToSetIterator(Iterator it) { + ToSetIterator(Iterator it) { super(it); } @Override protected boolean moveNext() { - + Set set = new HashSet(); Iterator it = this.it; - + while (it.hasNext()) { set.add(it.next()); } - + value = set; hasValue = true; done = true; diff --git a/src/main/java/ix/IxTransform.java b/src/main/java/ix/IxTransform.java index 797f4d9..a6b8e1b 100644 --- a/src/main/java/ix/IxTransform.java +++ b/src/main/java/ix/IxTransform.java @@ -18,8 +18,6 @@ import java.util.Iterator; -import rx.functions.Action1; - /** * Functional interface that allows transforming an * upstream Iterator for each downstream next() call. @@ -45,10 +43,10 @@ public interface IxTransform { int STOP = 0; - + int NEXT = 1; - + int LAST = 2; - - int moveNext(Iterator it, Action1 consumer); + + int moveNext(Iterator it, IxConsumer consumer); } diff --git a/src/main/java/ix/IxTransformer.java b/src/main/java/ix/IxTransformer.java index ebce7ad..aeebe1f 100644 --- a/src/main/java/ix/IxTransformer.java +++ b/src/main/java/ix/IxTransformer.java @@ -18,13 +18,11 @@ import java.util.Iterator; -import rx.functions.Action1; - final class IxTransformer extends IxSource { final IxTransform transform; - - public IxTransformer(Iterable source, IxTransform transform) { + + IxTransformer(Iterable source, IxTransform transform) { super(source); this.transform = transform; } @@ -35,15 +33,15 @@ public Iterator iterator() { } static final class TransformerIterator extends IxSourceIterator - implements Action1 { - + implements IxConsumer { + final IxTransform transform; - public TransformerIterator(Iterator it, IxTransform transform) { + TransformerIterator(Iterator it, IxTransform transform) { super(it); this.transform = transform; } - + @Override protected boolean moveNext() { int m = transform.moveNext(it, this); @@ -61,9 +59,9 @@ protected boolean moveNext() { } return true; } - + @Override - public void call(R t) { + public void accept(R t) { if (hasValue) { throw new IllegalStateException("Value already set in this turn!"); } diff --git a/src/main/java/ix/IxUnion.java b/src/main/java/ix/IxUnion.java index 03e865b..2961f9d 100644 --- a/src/main/java/ix/IxUnion.java +++ b/src/main/java/ix/IxUnion.java @@ -22,30 +22,30 @@ final class IxUnion extends IxSource { final Iterable other; - public IxUnion(Iterable source, Iterable other) { + IxUnion(Iterable source, Iterable other) { super(source); this.other = other; } - + @Override public Iterator iterator() { return new UnionIterator(source.iterator(), other.iterator()); } static final class UnionIterator extends IxSourceIterator { - + final Iterator other; final Set set; - + boolean second; - - public UnionIterator(Iterator it, Iterator other) { + + UnionIterator(Iterator it, Iterator other) { super(it); this.other = other; this.set = new HashSet(); } - + @Override protected boolean moveNext() { Set set = this.set; @@ -60,11 +60,11 @@ protected boolean moveNext() { return true; } } - + done = true; return false; } - + Iterator it = this.it; while (it.hasNext()) { T v = it.next(); @@ -74,7 +74,7 @@ protected boolean moveNext() { return true; } } - + second = true; } } diff --git a/src/main/java/ix/IxWindow.java b/src/main/java/ix/IxWindow.java index 5a50837..c0632dc 100644 --- a/src/main/java/ix/IxWindow.java +++ b/src/main/java/ix/IxWindow.java @@ -24,7 +24,7 @@ final class IxWindow extends IxSource> { static final Object NULL = new Object(); - public IxWindow(Iterable source, int size) { + IxWindow(Iterable source, int size) { super(source); this.size = size; } @@ -33,20 +33,20 @@ public IxWindow(Iterable source, int size) { public Iterator> iterator() { return new WindowIterator(source.iterator(), size); } - + static final class WindowIterator extends IxSourceIterator> { final int size; - + int index; WindowIterable current; - - public WindowIterator(Iterator it, int size) { + + WindowIterator(Iterator it, int size) { super(it); this.size = size; } - + @Override protected boolean moveNext() { int i = index; @@ -55,9 +55,9 @@ protected boolean moveNext() { done = true; return false; } - + T v = it.next(); - + WindowIterable c; if (i++ == 0) { if (i == size) { @@ -72,24 +72,24 @@ protected boolean moveNext() { hasValue = true; return true; } - + current.iterator.queue.offer(v != null ? v : NULL); - + if (i == size) { i = 0; } } } - + boolean moveInner() { if (!it.hasNext()) { return false; } - + T v = it.next(); - + current.iterator.queue.offer(v != null ? v : NULL); - + int i = index + 1; if (i == size) { current = null; @@ -104,10 +104,10 @@ boolean moveInner() { static final class WindowIterable extends Ix { final WindowInnerIterator iterator; - + boolean once; - - public WindowIterable(WindowIterator parent, int size) { + + WindowIterable(WindowIterator parent, int size) { this.iterator = new WindowInnerIterator(parent, size); } @@ -120,21 +120,21 @@ public Iterator iterator() { throw new IllegalStateException("This Window Ix iterable can be consumed only once."); } } - + static final class WindowInnerIterator extends IxBaseIterator { - + final WindowIterator parent; - + final ArrayDeque queue; int remaining; - - public WindowInnerIterator(WindowIterator parent, int remaining) { + + WindowInnerIterator(WindowIterator parent, int remaining) { this.parent = parent; this.queue = new ArrayDeque(); this.remaining = remaining; } - + @SuppressWarnings("unchecked") @Override protected boolean moveNext() { @@ -144,7 +144,7 @@ protected boolean moveNext() { return false; } Object o = queue.poll(); - + if (o == null) { if (!parent.moveInner()) { done = true; @@ -152,12 +152,12 @@ protected boolean moveNext() { } o = queue.poll(); } - + value = o == NULL ? null : (T)o; hasValue = true; remaining = r - 1; return true; } } - + } diff --git a/src/main/java/ix/IxWindowOverlap.java b/src/main/java/ix/IxWindowOverlap.java index 83f2b5f..21ae806 100644 --- a/src/main/java/ix/IxWindowOverlap.java +++ b/src/main/java/ix/IxWindowOverlap.java @@ -21,12 +21,12 @@ final class IxWindowOverlap extends IxSource> { final int size; - + final int skip; - + static final Object NULL = new Object(); - - public IxWindowOverlap(Iterable source, int size, int skip) { + + IxWindowOverlap(Iterable source, int size, int skip) { super(source); this.size = size; this.skip = skip; @@ -36,29 +36,29 @@ public IxWindowOverlap(Iterable source, int size, int skip) { public Iterator> iterator() { return new WindowIterator(source.iterator(), size, skip); } - + static final class WindowIterator extends IxSourceIterator> { final int size; - + final int skip; - + final Queue> queue; - + final Queue> windows; - + int index; - + int headSize; - - public WindowIterator(Iterator it, int size, int skip) { + + WindowIterator(Iterator it, int size, int skip) { super(it); this.size = size; this.skip = skip; this.queue = new ArrayDeque>(); this.windows = new ArrayDeque>(); } - + @Override protected boolean moveNext() { WindowIterable w = queue.poll(); @@ -69,19 +69,19 @@ protected boolean moveNext() { } w = queue.poll(); } - + value = w; hasValue = true; return true; } - + boolean moveMain() { int i = index; for (;;) { if (!it.hasNext()) { return false; } - + T v = it.next(); for (WindowIterable c : windows) { @@ -106,28 +106,28 @@ boolean moveMain() { c.iterator.offer(v); queue.offer(c); windows.offer(c); - + return true; } - + if (i == skip) { i = 0; } } } - + boolean moveInner() { int i = index; if (!it.hasNext()) { return false; } - + T v = it.next(); for (WindowIterable c : windows) { c.iterator.offer(v); } - + int j = headSize + 1; if (j == size) { windows.poll(); @@ -142,7 +142,7 @@ boolean moveInner() { queue.offer(c); windows.offer(c); } - + if (i == skip) { index = 0; } @@ -153,10 +153,10 @@ boolean moveInner() { static final class WindowIterable extends Ix { final WindowInnerIterator iterator; - + boolean once; - - public WindowIterable(WindowIterator parent, int size) { + + WindowIterable(WindowIterator parent, int size) { this.iterator = new WindowInnerIterator(parent); } @@ -169,18 +169,18 @@ public Iterator iterator() { throw new IllegalStateException("This Window Ix iterable can be consumed only once."); } } - + static final class WindowInnerIterator extends IxBaseIterator { - + final WindowIterator parent; - + final ArrayDeque queue; - - public WindowInnerIterator(WindowIterator parent) { + + WindowInnerIterator(WindowIterator parent) { this.parent = parent; this.queue = new ArrayDeque(); } - + @SuppressWarnings("unchecked") @Override protected boolean moveNext() { @@ -197,15 +197,15 @@ protected boolean moveNext() { return false; } } - + value = o == NULL ? null : (T)o; hasValue = true; return true; } - + void offer(T v) { queue.offer(v != null ? v : NULL); } } - + } diff --git a/src/main/java/ix/IxWindowSkip.java b/src/main/java/ix/IxWindowSkip.java index f3fcf6a..6e7f8d7 100644 --- a/src/main/java/ix/IxWindowSkip.java +++ b/src/main/java/ix/IxWindowSkip.java @@ -21,12 +21,12 @@ final class IxWindowSkip extends IxSource> { final int size; - + final int skip; - + static final Object NULL = new Object(); - public IxWindowSkip(Iterable source, int size, int skip) { + IxWindowSkip(Iterable source, int size, int skip) { super(source); this.size = size; this.skip = skip; @@ -36,23 +36,23 @@ public IxWindowSkip(Iterable source, int size, int skip) { public Iterator> iterator() { return new WindowIterator(source.iterator(), size, skip); } - + static final class WindowIterator extends IxSourceIterator> { final int size; - + int index; - + final int skip; WindowIterable current; - - public WindowIterator(Iterator it, int size, int skip) { + + WindowIterator(Iterator it, int size, int skip) { super(it); this.size = size; this.skip = skip; } - + @Override protected boolean moveNext() { int i = index; @@ -61,9 +61,9 @@ protected boolean moveNext() { done = true; return false; } - + T v = it.next(); - + if (i++ == 0) { index = i; WindowIterable c = new WindowIterable(this, size); @@ -73,26 +73,26 @@ protected boolean moveNext() { hasValue = true; return true; } - + WindowInnerIterator ci = current.iterator; - + if (ci.offered < size) { ci.offer(v); } - + if (i == skip) { i = 0; } } } - + boolean moveInner() { if (!it.hasNext()) { return false; } - + T v = it.next(); - + current.iterator.offer(v); index++; @@ -103,10 +103,10 @@ boolean moveInner() { static final class WindowIterable extends Ix { final WindowInnerIterator iterator; - + boolean once; - - public WindowIterable(WindowIterator parent, int size) { + + WindowIterable(WindowIterator parent, int size) { this.iterator = new WindowInnerIterator(parent, size); } @@ -119,23 +119,23 @@ public Iterator iterator() { throw new IllegalStateException("This Window Ix iterable can be consumed only once."); } } - + static final class WindowInnerIterator extends IxBaseIterator { - + final WindowIterator parent; - + final ArrayDeque queue; int remaining; - + int offered; - - public WindowInnerIterator(WindowIterator parent, int size) { + + WindowInnerIterator(WindowIterator parent, int size) { this.parent = parent; this.queue = new ArrayDeque(); this.remaining = size; } - + @SuppressWarnings("unchecked") @Override protected boolean moveNext() { @@ -145,7 +145,7 @@ protected boolean moveNext() { return false; } Object o = queue.poll(); - + if (o == null) { if (!parent.moveInner()) { done = true; @@ -153,17 +153,17 @@ protected boolean moveNext() { } o = queue.poll(); } - + value = o == NULL ? null : (T)o; hasValue = true; remaining = r - 1; return true; } - + void offer(T t) { offered++; queue.offer(t != null ? t : NULL); } } - + } diff --git a/src/main/java/ix/IxWrapper.java b/src/main/java/ix/IxWrapper.java index e8c0fac..53ab5b2 100644 --- a/src/main/java/ix/IxWrapper.java +++ b/src/main/java/ix/IxWrapper.java @@ -20,10 +20,10 @@ final class IxWrapper extends IxSource { - public IxWrapper(Iterable source) { + IxWrapper(Iterable source) { super(source); } - + @Override public Iterator iterator() { return source.iterator(); diff --git a/src/main/java/ix/IxZip2.java b/src/main/java/ix/IxZip2.java index 3027463..a7e1e6b 100644 --- a/src/main/java/ix/IxZip2.java +++ b/src/main/java/ix/IxZip2.java @@ -18,17 +18,15 @@ import java.util.Iterator; -import rx.functions.Func2; - final class IxZip2 extends Ix { final Iterable source1; final Iterable source2; - final Func2 zipper; - - public IxZip2(Iterable source1, Iterable source2, Func2 zipper) { + final IxFunction2 zipper; + + IxZip2(Iterable source1, Iterable source2, IxFunction2 zipper) { this.source1 = source1; this.source2 = source2; this.zipper = zipper; @@ -38,21 +36,21 @@ public IxZip2(Iterable source1, Iterable source2, Func2 iterator() { return new Zip2Iterator(source1.iterator(), source2.iterator(), zipper); } - + static final class Zip2Iterator extends IxBaseIterator { final Iterator source1; final Iterator source2; - final Func2 zipper; - - public Zip2Iterator(Iterator source1, Iterator source2, Func2 zipper) { + final IxFunction2 zipper; + + Zip2Iterator(Iterator source1, Iterator source2, IxFunction2 zipper) { this.source1 = source1; this.source2 = source2; this.zipper = zipper; } - + @Override protected boolean moveNext() { if (!source1.hasNext()) { @@ -61,18 +59,18 @@ protected boolean moveNext() { } T1 t1 = source1.next(); - + if (!source2.hasNext()) { done = true; return false; } - + T2 t2 = source2.next(); - value = zipper.call(t1, t2); + value = zipper.apply(t1, t2); hasValue = true; return true; } - + } } diff --git a/src/main/java/ix/IxZip3.java b/src/main/java/ix/IxZip3.java index 99b23e4..b45c4ce 100644 --- a/src/main/java/ix/IxZip3.java +++ b/src/main/java/ix/IxZip3.java @@ -18,8 +18,6 @@ import java.util.Iterator; -import rx.functions.Func3; - final class IxZip3 extends Ix { final Iterable source1; @@ -27,10 +25,10 @@ final class IxZip3 extends Ix { final Iterable source3; - final Func3 zipper; - - public IxZip3(Iterable source1, Iterable source2, Iterable source3, - Func3 zipper) { + final IxFunction3 zipper; + + IxZip3(Iterable source1, Iterable source2, Iterable source3, + IxFunction3 zipper) { this.source1 = source1; this.source2 = source2; this.source3 = source3; @@ -39,7 +37,7 @@ public IxZip3(Iterable source1, Iterable source2, Iterable source3, @Override public Iterator iterator() { - return new Zip3Iterator(source1.iterator(), source2.iterator(), + return new Zip3Iterator(source1.iterator(), source2.iterator(), source3.iterator(), zipper); } @@ -51,16 +49,16 @@ static final class Zip3Iterator extends IxBaseIterator { final Iterator source3; - final Func3 zipper; - - public Zip3Iterator(Iterator source1, Iterator source2, Iterator source3, - Func3 zipper) { + final IxFunction3 zipper; + + Zip3Iterator(Iterator source1, Iterator source2, Iterator source3, + IxFunction3 zipper) { this.source1 = source1; this.source2 = source2; this.source3 = source3; this.zipper = zipper; } - + @Override protected boolean moveNext() { if (!source1.hasNext()) { @@ -83,11 +81,11 @@ protected boolean moveNext() { } T3 t3 = source3.next(); - - value = zipper.call(t1, t2, t3); + + value = zipper.apply(t1, t2, t3); hasValue = true; return true; } - + } } diff --git a/src/main/java/ix/IxZip4.java b/src/main/java/ix/IxZip4.java index b49d385..66929b9 100644 --- a/src/main/java/ix/IxZip4.java +++ b/src/main/java/ix/IxZip4.java @@ -18,8 +18,6 @@ import java.util.Iterator; -import rx.functions.Func4; - final class IxZip4 extends Ix { final Iterable source1; @@ -29,11 +27,11 @@ final class IxZip4 extends Ix { final Iterable source4; - final Func4 zipper; - - public IxZip4(Iterable source1, Iterable source2, + final IxFunction4 zipper; + + IxZip4(Iterable source1, Iterable source2, Iterable source3, Iterable source4, - Func4 zipper) { + IxFunction4 zipper) { this.source1 = source1; this.source2 = source2; this.source3 = source3; @@ -43,7 +41,7 @@ public IxZip4(Iterable source1, Iterable source2, @Override public Iterator iterator() { - return new Zip4Iterator(source1.iterator(), source2.iterator(), + return new Zip4Iterator(source1.iterator(), source2.iterator(), source3.iterator(), source4.iterator(), zipper); } @@ -57,18 +55,18 @@ static final class Zip4Iterator extends IxBaseIterator { final Iterator source4; - final Func4 zipper; - - public Zip4Iterator(Iterator source1, Iterator source2, Iterator source3, + final IxFunction4 zipper; + + Zip4Iterator(Iterator source1, Iterator source2, Iterator source3, Iterator source4, - Func4 zipper) { + IxFunction4 zipper) { this.source1 = source1; this.source2 = source2; this.source3 = source3; this.source4 = source4; this.zipper = zipper; } - + @Override protected boolean moveNext() { if (!source1.hasNext()) { @@ -98,11 +96,11 @@ protected boolean moveNext() { } T4 t4 = source4.next(); - - value = zipper.call(t1, t2, t3, t4); + + value = zipper.apply(t1, t2, t3, t4); hasValue = true; return true; } - + } } diff --git a/src/main/java/ix/IxZipArray.java b/src/main/java/ix/IxZipArray.java index d40bcef..22f396a 100644 --- a/src/main/java/ix/IxZipArray.java +++ b/src/main/java/ix/IxZipArray.java @@ -18,15 +18,13 @@ import java.util.Iterator; -import rx.functions.FuncN; - final class IxZipArray extends Ix { final Iterable[] sources; - - final FuncN zipper; - - public IxZipArray(Iterable[] sources, FuncN zipper) { + + final IxFunction zipper; + + IxZipArray(Iterable[] sources, IxFunction zipper) { this.sources = sources; this.zipper = zipper; } @@ -34,37 +32,37 @@ public IxZipArray(Iterable[] sources, FuncN zipper) { @SuppressWarnings("unchecked") @Override public Iterator iterator() { - + Iterable[] src = sources; - - Iterator[] itors = new Iterator[src.length]; - for (int i = 0; i < itors.length; i++) { - itors[i] = (Iterator)src[i].iterator(); + + Iterator[] iterators = new Iterator[src.length]; + for (int i = 0; i < iterators.length; i++) { + iterators[i] = (Iterator)src[i].iterator(); } - - return new ZipArrayIterator(itors, zipper); + + return new ZipArrayIterator(iterators, zipper); } - + static final class ZipArrayIterator extends IxBaseIterator { final Iterator[] sources; - final FuncN zipper; + final IxFunction zipper; - public ZipArrayIterator(Iterator[] sources, FuncN zipper) { + ZipArrayIterator(Iterator[] sources, IxFunction zipper) { this.sources = sources; this.zipper = zipper; } - + @SuppressWarnings("unchecked") @Override protected boolean moveNext() { - Iterator[] itors = sources; - int n = itors.length; + Iterator[] iterators = sources; + int n = iterators.length; T[] a = (T[])new Object[n]; - + for (int i = 0; i < n; i++) { - Iterator it = itors[i]; + Iterator it = iterators[i]; if (it.hasNext()) { a[i] = it.next(); } else { @@ -72,13 +70,13 @@ protected boolean moveNext() { return false; } } - - value = zipper.call(a); + + value = zipper.apply(a); hasValue = true; - + return true; } - + } } diff --git a/src/main/java/ix/IxZipIterable.java b/src/main/java/ix/IxZipIterable.java index f242df0..74b2681 100644 --- a/src/main/java/ix/IxZipIterable.java +++ b/src/main/java/ix/IxZipIterable.java @@ -19,15 +19,14 @@ import java.util.*; import ix.IxZipArray.ZipArrayIterator; -import rx.functions.FuncN; final class IxZipIterable extends Ix { final Iterable> sources; - - final FuncN zipper; - - public IxZipIterable(Iterable> sources, FuncN zipper) { + + final IxFunction zipper; + + IxZipIterable(Iterable> sources, IxFunction zipper) { this.sources = sources; this.zipper = zipper; } @@ -35,22 +34,22 @@ public IxZipIterable(Iterable> sources, FuncN @SuppressWarnings("unchecked") @Override public Iterator iterator() { - + Iterable[] src = new Iterable[8]; int n = 0; - + for (Iterable it : sources) { if (n == src.length) { src = Arrays.copyOf(src, n + (n >> 1)); } src[n++] = it; } - - Iterator[] itors = new Iterator[n]; + + Iterator[] iterators = new Iterator[n]; for (int i = 0; i < n; i++) { - itors[i] = (Iterator)src[i].iterator(); + iterators[i] = (Iterator)src[i].iterator(); } - - return new ZipArrayIterator(itors, zipper); + + return new ZipArrayIterator(iterators, zipper); } } diff --git a/src/main/java/ix/NumberToLongHelper.java b/src/main/java/ix/NumberToLongHelper.java index 41ee68b..92c268a 100644 --- a/src/main/java/ix/NumberToLongHelper.java +++ b/src/main/java/ix/NumberToLongHelper.java @@ -16,13 +16,11 @@ package ix; -import rx.functions.Func1; - -enum NumberToLongHelper implements Func1 { +enum NumberToLongHelper implements IxFunction { INSTANCE; - + @Override - public Long call(Number t1) { + public Long apply(Number t1) { return t1.longValue(); } } \ No newline at end of file diff --git a/src/main/java/ix/SelfComparator.java b/src/main/java/ix/SelfComparator.java index 75f3368..6e4aef0 100644 --- a/src/main/java/ix/SelfComparator.java +++ b/src/main/java/ix/SelfComparator.java @@ -22,7 +22,7 @@ enum SelfComparator implements Comparator { INSTANCE ; - + @SuppressWarnings("unchecked") @Override public int compare(Comparable o1, Comparable o2) { diff --git a/src/main/java/ix/ToListHelper.java b/src/main/java/ix/ToListHelper.java index 7c2781c..f894f51 100644 --- a/src/main/java/ix/ToListHelper.java +++ b/src/main/java/ix/ToListHelper.java @@ -18,38 +18,36 @@ import java.util.*; -import rx.functions.*; - -enum ToListHelper implements Func0>, Action2, Object>, Func1, Object[]> { +enum ToListHelper implements IxSupplier>, IxConsumer2, Object>, IxFunction, Object[]> { INSTANCE; @SuppressWarnings({ "rawtypes", "unchecked" }) - public static Func0> initialFactory() { - return (Func0)INSTANCE; + public static IxSupplier> initialFactory() { + return (IxSupplier)INSTANCE; } @SuppressWarnings({ "rawtypes", "unchecked" }) - public static Action2, T> collector() { - return (Action2)INSTANCE; + public static IxConsumer2, T> collector() { + return (IxConsumer2)INSTANCE; } @SuppressWarnings({ "rawtypes", "unchecked" }) - public static Func1, Object[]> toArray() { - return (Func1)INSTANCE; + public static IxFunction, Object[]> toArray() { + return (IxFunction)INSTANCE; } @Override - public void call(List t1, Object t2) { + public void accept(List t1, Object t2) { t1.add(t2); } @Override - public List call() { + public List get() { return new ArrayList(); } @Override - public Object[] call(List t) { + public Object[] apply(List t) { return t.toArray(); } - + } diff --git a/src/test/java/ix/AggregateTest.java b/src/test/java/ix/AggregateTest.java index 8b6d83b..6702184 100644 --- a/src/test/java/ix/AggregateTest.java +++ b/src/test/java/ix/AggregateTest.java @@ -22,25 +22,25 @@ public class AggregateTest { @Test public void normal() { - + Ix source = Ix.range(1, 10).sumInt(); - + IxTestHelper.assertValues(source, 55); } - + @Test public void just() { - + Ix source = Ix.just(1).sumInt(); - + IxTestHelper.assertValues(source, 1); } @Test public void empty() { - + Ix source = Ix.empty().sumInt(); - + IxTestHelper.assertValues(source); } diff --git a/src/test/java/ix/AnyAllTest.java b/src/test/java/ix/AnyAllTest.java index 295e26b..82fe86d 100644 --- a/src/test/java/ix/AnyAllTest.java +++ b/src/test/java/ix/AnyAllTest.java @@ -22,85 +22,85 @@ public class AnyAllTest { @Test public void anyFound() { - Ix source = Ix.range(1, 5).any(new Pred() { + Ix source = Ix.range(1, 5).any(new IxPredicate() { @Override public boolean test(Integer v) { return v == 3; } }); - + IxTestHelper.assertValues(source, true); - + IxTestHelper.assertNoRemove(source); } @Test public void anyNotFound() { - Ix source = Ix.range(1, 5).any(new Pred() { + Ix source = Ix.range(1, 5).any(new IxPredicate() { @Override public boolean test(Integer v) { return v == 0; } }); - + IxTestHelper.assertValues(source, false); - + IxTestHelper.assertNoRemove(source); } - + @Test public void anyEmpty() { - Ix source = Ix.empty().any(new Pred() { + Ix source = Ix.empty().any(new IxPredicate() { @Override public boolean test(Integer v) { return v == 3; } }); - + IxTestHelper.assertValues(source, false); - + IxTestHelper.assertNoRemove(source); } @Test public void allTrue() { - Ix source = Ix.range(1, 5).all(new Pred() { + Ix source = Ix.range(1, 5).all(new IxPredicate() { @Override public boolean test(Integer v) { return v < 6; } }); - + IxTestHelper.assertValues(source, true); - + IxTestHelper.assertNoRemove(source); } @Test public void allFalse() { - Ix source = Ix.range(1, 5).all(new Pred() { + Ix source = Ix.range(1, 5).all(new IxPredicate() { @Override public boolean test(Integer v) { return false; } }); - + IxTestHelper.assertValues(source, false); - + IxTestHelper.assertNoRemove(source); } - + @Test public void allEmpty() { - Ix source = Ix.empty().all(new Pred() { + Ix source = Ix.empty().all(new IxPredicate() { @Override public boolean test(Integer v) { return false; } }); - + IxTestHelper.assertValues(source, true); - + IxTestHelper.assertNoRemove(source); } diff --git a/src/test/java/ix/AsComposeTest.java b/src/test/java/ix/AsComposeTest.java index 4e32ebb..d903725 100644 --- a/src/test/java/ix/AsComposeTest.java +++ b/src/test/java/ix/AsComposeTest.java @@ -18,39 +18,37 @@ import org.junit.*; -import rx.functions.Func1; - public class AsComposeTest { @Test public void normal() { - Integer value = Ix.range(1, 5).as(new Func1, Integer>() { + Integer value = Ix.range(1, 5).as(new IxFunction, Integer>() { @Override - public Integer call(Ix ix) { + public Integer apply(Ix ix) { return ix.first(); } }); - + Assert.assertEquals(1, value.intValue()); } - + @Test public void compose() { - Ix source = Ix.range(1, 5).compose(new Func1, Iterable>() { + Ix source = Ix.range(1, 5).compose(new IxFunction, Iterable>() { @Override - public Iterable call(Ix ix) { + public Iterable apply(Ix ix) { final int[] index = { 1 }; - return ix.map(new Func1() { + return ix.map(new IxFunction() { @Override - public String call(Integer v) { + public String apply(Integer v) { return v + "-" + (index[0]++); } }); } }); - + IxTestHelper.assertValues(source, "1-1", "2-2", "3-3", "4-4", "5-5"); - + IxTestHelper.assertValues(source, "1-1", "2-2", "3-3", "4-4", "5-5"); } } diff --git a/src/test/java/ix/AverageTest.java b/src/test/java/ix/AverageTest.java index f8303f5..16e2c91 100644 --- a/src/test/java/ix/AverageTest.java +++ b/src/test/java/ix/AverageTest.java @@ -23,54 +23,54 @@ public class AverageTest { @Test public void normalFloat() { Ix source = Ix.range(1, 5).averageFloat(); - + IxTestHelper.assertValues(source, 3f); - + IxTestHelper.assertNoRemove(source); } @Test public void justFloat() { Ix source = Ix.just(1).averageFloat(); - + IxTestHelper.assertValues(source, 1f); - + IxTestHelper.assertNoRemove(source); } @Test public void emptyFloat() { Ix source = Ix.empty().averageFloat(); - + IxTestHelper.assertValues(source); - + IxTestHelper.assertNoRemove(source); } - + @Test public void normalDouble() { Ix source = Ix.range(1, 5).averageDouble(); - + IxTestHelper.assertValues(source, 3d); - + IxTestHelper.assertNoRemove(source); } @Test public void justDouble() { Ix source = Ix.just(1).averageDouble(); - + IxTestHelper.assertValues(source, 1d); - + IxTestHelper.assertNoRemove(source); } @Test public void emptyDouble() { Ix source = Ix.empty().averageDouble(); - + IxTestHelper.assertValues(source); - + IxTestHelper.assertNoRemove(source); } diff --git a/src/test/java/ix/BufferTest.java b/src/test/java/ix/BufferTest.java index 9a2d28d..e88723f 100644 --- a/src/test/java/ix/BufferTest.java +++ b/src/test/java/ix/BufferTest.java @@ -26,39 +26,39 @@ public class BufferTest { @Test public void normal() { Ix> source = Ix.range(1, 5).buffer(2); - + IxTestHelper.assertValues(source, Arrays.asList(1, 2), Arrays.asList(3, 4), Arrays.asList(5)); - + IxTestHelper.assertNoRemove(source); } - + @SuppressWarnings("unchecked") @Test public void normalExactLength() { Ix> source = Ix.range(1, 6).buffer(2); - + IxTestHelper.assertValues(source, Arrays.asList(1, 2), Arrays.asList(3, 4), Arrays.asList(5, 6)); - + IxTestHelper.assertNoRemove(source); } - + @SuppressWarnings("unchecked") @Test public void normalSameSkip() { Ix> source = Ix.range(1, 5).buffer(2, 2); - + IxTestHelper.assertValues(source, Arrays.asList(1, 2), Arrays.asList(3, 4), Arrays.asList(5)); - + IxTestHelper.assertNoRemove(source); } - + @SuppressWarnings("unchecked") @Test public void normalSameSkipExactLength() { Ix> source = Ix.range(1, 6).buffer(2, 2); - + IxTestHelper.assertValues(source, Arrays.asList(1, 2), Arrays.asList(3, 4), Arrays.asList(5, 6)); - + IxTestHelper.assertNoRemove(source); } @@ -66,9 +66,9 @@ public void normalSameSkipExactLength() { @Test public void normalSkip() { Ix> source = Ix.range(1, 5).buffer(2, 3); - + IxTestHelper.assertValues(source, Arrays.asList(1, 2), Arrays.asList(4, 5)); - + IxTestHelper.assertNoRemove(source); } @@ -76,9 +76,9 @@ public void normalSkip() { @Test public void normalSkipShorter() { Ix> source = Ix.range(1, 4).buffer(2, 3); - + IxTestHelper.assertValues(source, Arrays.asList(1, 2), Arrays.asList(4)); - + IxTestHelper.assertNoRemove(source); } @@ -86,9 +86,9 @@ public void normalSkipShorter() { @Test public void normalSkipShortest() { Ix> source = Ix.range(1, 3).buffer(2, 3); - + IxTestHelper.assertValues(source, Arrays.asList(1, 2)); - + IxTestHelper.assertNoRemove(source); } @@ -96,67 +96,67 @@ public void normalSkipShortest() { @Test public void normalOverlap() { Ix> source = Ix.range(1, 5).buffer(2, 1); - - IxTestHelper.assertValues(source, - Arrays.asList(1, 2), - Arrays.asList(2, 3), - Arrays.asList(3, 4), - Arrays.asList(4, 5), + + IxTestHelper.assertValues(source, + Arrays.asList(1, 2), + Arrays.asList(2, 3), + Arrays.asList(3, 4), + Arrays.asList(4, 5), Arrays.asList(5)); - + IxTestHelper.assertNoRemove(source); } - + @SuppressWarnings("unchecked") @Test public void normalOverlapLonger() { Ix> source = Ix.range(1, 10).buffer(3, 1); - - IxTestHelper.assertValues(source, - Arrays.asList(1, 2, 3), - Arrays.asList(2, 3, 4), - Arrays.asList(3, 4, 5), - Arrays.asList(4, 5, 6), - Arrays.asList(5, 6, 7), - Arrays.asList(6, 7, 8), - Arrays.asList(7, 8, 9), - Arrays.asList(8, 9, 10), - Arrays.asList(9, 10), + + IxTestHelper.assertValues(source, + Arrays.asList(1, 2, 3), + Arrays.asList(2, 3, 4), + Arrays.asList(3, 4, 5), + Arrays.asList(4, 5, 6), + Arrays.asList(5, 6, 7), + Arrays.asList(6, 7, 8), + Arrays.asList(7, 8, 9), + Arrays.asList(8, 9, 10), + Arrays.asList(9, 10), Arrays.asList(10) ); - + IxTestHelper.assertNoRemove(source); } - + @SuppressWarnings("unchecked") @Test public void normalOverlapSorter() { Ix> source = Ix.range(1, 2).buffer(3, 2); - - IxTestHelper.assertValues(source, + + IxTestHelper.assertValues(source, Arrays.asList(1, 2) ); - + IxTestHelper.assertNoRemove(source); } - + @SuppressWarnings("unchecked") @Test public void normalOverlapEmpty() { Ix> source = Ix.empty().buffer(3, 2); - + IxTestHelper.assertValues(source); - + IxTestHelper.assertNoRemove(source); } - + @SuppressWarnings("unchecked") @Test public void normalOverlapJust() { Ix> source = Ix.just(1).buffer(3, 2); - + IxTestHelper.assertValues(source, Arrays.asList(1)); - + IxTestHelper.assertNoRemove(source); } } diff --git a/src/test/java/ix/CharactersTest.java b/src/test/java/ix/CharactersTest.java index c269c50..01bbf45 100644 --- a/src/test/java/ix/CharactersTest.java +++ b/src/test/java/ix/CharactersTest.java @@ -23,63 +23,63 @@ public class CharactersTest { @Test public void normal() { Ix source = Ix.characters("Hello world!"); - + IxTestHelper.assertValues(source, - (int)'H', (int)'e', (int)'l', (int)'l', - (int)'o', (int)' ', (int)'w', (int)'o', (int)'r', (int)'l', + (int)'H', (int)'e', (int)'l', (int)'l', + (int)'o', (int)' ', (int)'w', (int)'o', (int)'r', (int)'l', (int)'d', (int)'!'); - + IxTestHelper.assertNoRemove(source); } @Test public void normalRange() { Ix source = Ix.characters("Hello world!", 2, 8); - + IxTestHelper.assertValues(source, - (int)'l', (int)'l', + (int)'l', (int)'l', (int)'o', (int)' ', (int)'w', (int)'o'); - + IxTestHelper.assertNoRemove(source); } @Test public void rangeChecks() { String s = "Hello world"; - + try { Ix.characters(s, -1, 1); Assert.fail("Failed to throw IndexOutOfBoundsException"); } catch (IndexOutOfBoundsException ex) { Assert.assertEquals("start=-1, end=1, length=11", ex.getMessage()); } - + try { Ix.characters(s, 1, -1); Assert.fail("Failed to throw IndexOutOfBoundsException"); } catch (IndexOutOfBoundsException ex) { Assert.assertEquals("start=1, end=-1, length=11", ex.getMessage()); } - + try { Ix.characters(s, 12, -1); Assert.fail("Failed to throw IndexOutOfBoundsException"); } catch (IndexOutOfBoundsException ex) { Assert.assertEquals("start=12, end=-1, length=11", ex.getMessage()); } - + try { Ix.characters(s, 1, 12); Assert.fail("Failed to throw IndexOutOfBoundsException"); } catch (IndexOutOfBoundsException ex) { Assert.assertEquals("start=1, end=12, length=11", ex.getMessage()); } - + try { Ix.characters(s, 12, 12); Assert.fail("Failed to throw IndexOutOfBoundsException"); } catch (IndexOutOfBoundsException ex) { Assert.assertEquals("start=12, end=12, length=11", ex.getMessage()); } - } + } } diff --git a/src/test/java/ix/CollectTest.java b/src/test/java/ix/CollectTest.java index 4def9d8..9e84a46 100644 --- a/src/test/java/ix/CollectTest.java +++ b/src/test/java/ix/CollectTest.java @@ -16,28 +16,26 @@ package ix; -import org.junit.Test; - -import rx.functions.*; +import static org.junit.Assert.assertEquals; -import static org.junit.Assert.*; +import org.junit.Test; public class CollectTest { @Test public void normal() { - Ix source = Ix.range(1, 10).collect(new Func0() { + Ix source = Ix.range(1, 10).collect(new IxSupplier() { @Override - public Integer[] call() { + public Integer[] get() { return new Integer[] { 0 }; } - }, new Action2() { + }, new IxConsumer2() { @Override - public void call(Integer[] a, Integer b) { + public void accept(Integer[] a, Integer b) { a[0] += b; } }); - + assertEquals(55, source.first()[0].intValue()); } } diff --git a/src/test/java/ix/ConcatArrayTest.java b/src/test/java/ix/ConcatArrayTest.java index b775fd9..0987a3f 100644 --- a/src/test/java/ix/ConcatArrayTest.java +++ b/src/test/java/ix/ConcatArrayTest.java @@ -26,8 +26,8 @@ public class ConcatArrayTest { @Test public void normal() { Ix source = Ix.concatArray(Ix.range(1, 5), Ix.range(6, 5)); - - + + IxTestHelper.assertValues(source, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10); } @@ -35,18 +35,18 @@ public void normal() { @Test public void normalViaMerge() { Ix source = Ix.mergeArray(Ix.range(1, 5), Ix.range(6, 5)); - - + + IxTestHelper.assertValues(source, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10); } - + @SuppressWarnings("unchecked") @Test public void just() { Ix source = Ix.concatArray(Ix.just(1), Ix.just(2)); - - + + IxTestHelper.assertValues(source, 1, 2); } @@ -54,28 +54,28 @@ public void just() { @Test public void empty() { Ix source = Ix.concatArray(Ix.empty(), Ix.empty()); - - + + IxTestHelper.assertValues(source); } @SuppressWarnings("unchecked") @Test public void mixed() { - Ix source = Ix.concatArray(Ix.empty(), Ix.range(1, 5), + Ix source = Ix.concatArray(Ix.empty(), Ix.range(1, 5), Ix.empty(), Ix.just(6), Ix.empty()); - - + + IxTestHelper.assertValues(source, 1, 2, 3, 4, 5, 6); } @SuppressWarnings("unchecked") @Test public void mixedTwo() { - Ix source = Ix.concatArray(Ix.range(1, 5), + Ix source = Ix.concatArray(Ix.range(1, 5), Ix.empty(), Ix.just(6)); - - + + IxTestHelper.assertValues(source, 1, 2, 3, 4, 5, 6); } @@ -83,7 +83,7 @@ public void mixedTwo() { public void emptyArray() { @SuppressWarnings("unchecked") Ix source = Ix.concatArray(); - + Assert.assertSame(source.getClass().toString(), source, Ix.empty()); } @@ -91,7 +91,7 @@ public void emptyArray() { public void justArray() { @SuppressWarnings("unchecked") Ix source = Ix.concatArray(Ix.just(1)); - + Assert.assertTrue(source.getClass().toString(), source instanceof IxScalarCallable); } @@ -99,8 +99,8 @@ public void justArray() { @Test public void concatIterable() { Ix source = Ix.concat(Arrays.asList(Ix.range(1, 5), Ix.range(6, 5))); - - + + IxTestHelper.assertValues(source, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10); } @@ -108,11 +108,11 @@ public void concatIterable() { @Test public void concatIterableViaMerge() { Ix source = Ix.merge(Arrays.asList(Ix.range(1, 5), Ix.range(6, 5))); - - + + IxTestHelper.assertValues(source, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10); } - + @Test public void startWith() { Ix source = Ix.range(1, 5).startWith(5, 4, 3, 2, 1); @@ -154,7 +154,7 @@ public void concatWithEmpty() { IxTestHelper.assertValues(source, 1, 2, 3, 4, 5); } - + @Test public void mergeWith() { Ix source = Ix.range(1, 5).mergeWith(Ix.range(6, 5)); @@ -168,25 +168,25 @@ public void mergeWithEmpty() { IxTestHelper.assertValues(source, 1, 2, 3, 4, 5); } - + @Test public void concat2() { Ix source = Ix.concat(Ix.just(1), Ix.just(2)); - + IxTestHelper.assertValues(source, 1, 2); } @Test public void concat3() { Ix source = Ix.concat(Ix.just(1), Ix.just(2), Ix.just(3)); - + IxTestHelper.assertValues(source, 1, 2, 3); } @Test public void concat4() { Ix source = Ix.concat(Ix.just(1), Ix.just(2), Ix.just(3), Ix.just(4)); - + IxTestHelper.assertValues(source, 1, 2, 3, 4); } } diff --git a/src/test/java/ix/ContainsTest.java b/src/test/java/ix/ContainsTest.java index 504520b..85f091d 100644 --- a/src/test/java/ix/ContainsTest.java +++ b/src/test/java/ix/ContainsTest.java @@ -23,63 +23,63 @@ public class ContainsTest { @Test public void normal() { Ix source = Ix.range(1, 5).contains(3); - + IxTestHelper.assertValues(source, true); - + IxTestHelper.assertNoRemove(source); } - + @Test public void normalNoReferenceEquals() { Ix source = Ix.range(1, 5).contains(new Integer(3)); - + IxTestHelper.assertValues(source, true); - + IxTestHelper.assertNoRemove(source); } - + @Test public void doesntContain() { Ix source = Ix.range(1, 5).contains(6); - + IxTestHelper.assertValues(source, false); - + IxTestHelper.assertNoRemove(source); } - + @Test public void doesntContainNull() { Ix source = Ix.range(1, 5).contains(null); - + IxTestHelper.assertValues(source, false); - + IxTestHelper.assertNoRemove(source); } - + @Test public void empty() { Ix source = Ix.empty().contains(6); - + IxTestHelper.assertValues(source, false); - + IxTestHelper.assertNoRemove(source); } - + @Test public void justNull() { Ix source = Ix.just(null).contains(6); - + IxTestHelper.assertValues(source, false); - + IxTestHelper.assertNoRemove(source); } - + @Test public void justNullContains() { Ix source = Ix.just(null).contains(null); - + IxTestHelper.assertValues(source, true); - + IxTestHelper.assertNoRemove(source); } } diff --git a/src/test/java/ix/CountTest.java b/src/test/java/ix/CountTest.java index 99935ab..c075aa9 100644 --- a/src/test/java/ix/CountTest.java +++ b/src/test/java/ix/CountTest.java @@ -23,54 +23,54 @@ public class CountTest { @Test public void normal() { Ix source = Ix.range(1, 5).count(); - + IxTestHelper.assertValues(source, 5); - + IxTestHelper.assertNoRemove(source); } @Test public void just() { Ix source = Ix.just(1).count(); - + IxTestHelper.assertValues(source, 1); - + IxTestHelper.assertNoRemove(source); } - + @Test public void empty() { Ix source = Ix.empty().count(); - + IxTestHelper.assertValues(source, 0); - + IxTestHelper.assertNoRemove(source); } @Test public void normalLong() { Ix source = Ix.range(1, 5).countLong(); - + IxTestHelper.assertValues(source, 5L); - + IxTestHelper.assertNoRemove(source); } @Test public void justLong() { Ix source = Ix.just(1).countLong(); - + IxTestHelper.assertValues(source, 1L); - + IxTestHelper.assertNoRemove(source); } - + @Test public void emptyLong() { Ix source = Ix.empty().countLong(); - + IxTestHelper.assertValues(source, 0L); - + IxTestHelper.assertNoRemove(source); } diff --git a/src/test/java/ix/DeferTest.java b/src/test/java/ix/DeferTest.java index 8592d4e..7e35ede 100644 --- a/src/test/java/ix/DeferTest.java +++ b/src/test/java/ix/DeferTest.java @@ -18,20 +18,18 @@ import org.junit.Test; -import rx.functions.Func0; - public class DeferTest { @Test public void normal() { - Ix source = Ix.defer(new Func0>() { + Ix source = Ix.defer(new IxSupplier>() { int count; @Override - public Iterable call() { + public Iterable get() { return Ix.range(++count, 2); } }); - + IxTestHelper.assertValues(source, 1, 2); IxTestHelper.assertValues(source, 2, 3); IxTestHelper.assertValues(source, 3, 4); diff --git a/src/test/java/ix/DistinctTest.java b/src/test/java/ix/DistinctTest.java index 070d9be..159858b 100644 --- a/src/test/java/ix/DistinctTest.java +++ b/src/test/java/ix/DistinctTest.java @@ -18,33 +18,31 @@ import org.junit.Test; -import rx.functions.Func1; - public class DistinctTest { @Test public void normal() { Ix source = Ix.fromArray(1, 2, 2, 1, 3, 4, 2).distinct(); - + IxTestHelper.assertValues(source, 1, 2, 3, 4); } - + @Test public void empty() { Ix source = Ix.empty().distinct(); - + IxTestHelper.assertValues(source); } - + @Test public void normalSelector() { - Ix source = Ix.fromArray(1, 2, 2, 1, 3, 4, 2).distinct(new Func1() { + Ix source = Ix.fromArray(1, 2, 2, 1, 3, 4, 2).distinct(new IxFunction() { @Override - public Object call(Integer v) { + public Object apply(Integer v) { return v & 1; } }); - + IxTestHelper.assertValues(source, 1, 2); } } diff --git a/src/test/java/ix/DistinctUntilChangedTest.java b/src/test/java/ix/DistinctUntilChangedTest.java index 324c97a..591a343 100644 --- a/src/test/java/ix/DistinctUntilChangedTest.java +++ b/src/test/java/ix/DistinctUntilChangedTest.java @@ -18,54 +18,52 @@ import org.junit.Test; -import rx.functions.Func1; - public class DistinctUntilChangedTest { @Test public void normal() { Ix source = Ix.fromArray(1, 2, 2, 1, 3, 1, 1, 4, 4).distinctUntilChanged(); - + IxTestHelper.assertValues(source, 1, 2, 1, 3, 1, 4); - + IxTestHelper.assertNoRemove(source); } - + @Test public void normalComparer() { - Ix source = Ix.fromArray(1, 2, 2, 1, 3, 1, 1, 4, 4).distinctUntilChanged(new Pred2() { + Ix source = Ix.fromArray(1, 2, 2, 1, 3, 1, 1, 4, 4).distinctUntilChanged(new IxPredicate2() { @Override public boolean test(Integer a, Integer b) { return (a & 1) == (b & 1); } }); - + IxTestHelper.assertValues(source, 1, 2, 1, 4); - + IxTestHelper.assertNoRemove(source); } - + @Test public void normalSelector() { Ix source = Ix.fromArray(1, 2, 2, 1, 3, 1, 1, 4, 4) - .distinctUntilChanged(new Func1() { + .distinctUntilChanged(new IxFunction() { @Override - public Object call(Integer v) { + public Object apply(Integer v) { return v & 1; } }); - + IxTestHelper.assertValues(source, 1, 2, 1, 4); - + IxTestHelper.assertNoRemove(source); } - + @Test public void empty() { Ix source = Ix.empty().distinctUntilChanged(); - + IxTestHelper.assertValues(source); - + IxTestHelper.assertNoRemove(source); } } diff --git a/src/test/java/ix/DoOnTest.java b/src/test/java/ix/DoOnTest.java index fc6860e..497c77b 100644 --- a/src/test/java/ix/DoOnTest.java +++ b/src/test/java/ix/DoOnTest.java @@ -20,23 +20,21 @@ import org.junit.*; -import rx.functions.*; - public class DoOnTest { @Test public void normal() { final List values = new ArrayList(); Ix source = Ix.range(1, 5) - .doOnNext(new Action1() { + .doOnNext(new IxConsumer() { @Override - public void call(Integer v) { + public void accept(Integer v) { values.add(v); } }) - .doOnCompleted(new Action0() { + .doOnCompleted(new Runnable() { @Override - public void call() { + public void run() { values.add(100); } }) @@ -44,20 +42,20 @@ public void call() { IxTestHelper.assertValues(source, 1, 2, 3, 4, 5); Assert.assertEquals(Arrays.asList(1, 2, 3, 4, 5, 100), values); } - + @Test public void empty() { final List values = new ArrayList(); Ix source = Ix.empty() - .doOnNext(new Action1() { + .doOnNext(new IxConsumer() { @Override - public void call(Integer v) { + public void accept(Integer v) { values.add(v); } }) - .doOnCompleted(new Action0() { + .doOnCompleted(new Runnable() { @Override - public void call() { + public void run() { values.add(100); } }) diff --git a/src/test/java/ix/EmptyActionTest.java b/src/test/java/ix/EmptyActionTest.java index 534350f..0f5cc50 100644 --- a/src/test/java/ix/EmptyActionTest.java +++ b/src/test/java/ix/EmptyActionTest.java @@ -16,16 +16,16 @@ package ix; -import org.junit.Test; - import static org.junit.Assert.*; +import org.junit.Test; + public class EmptyActionTest { @Test public void normal() { assertNotNull(IxEmptyAction.valueOf("INSTANCE")); - + assertEquals(1, IxEmptyAction.values().length); } } diff --git a/src/test/java/ix/EmptyTest.java b/src/test/java/ix/EmptyTest.java index 0e9d2ac..4477e3f 100644 --- a/src/test/java/ix/EmptyTest.java +++ b/src/test/java/ix/EmptyTest.java @@ -23,18 +23,18 @@ public class EmptyTest { @Test public void normal() { Ix source = Ix.empty(); - + IxTestHelper.assertValues(source); - + IxTestHelper.assertNoRemove(source); } - + @Test public void removeThrows() { Ix source = Ix.empty(); - + IxTestHelper.assertNoRemove(source); - + try { source.iterator().remove(); Assert.fail("Should have thrown UnsupportedOperationException"); diff --git a/src/test/java/ix/EqualityHelperTest.java b/src/test/java/ix/EqualityHelperTest.java index d3ae6fd..f742000 100644 --- a/src/test/java/ix/EqualityHelperTest.java +++ b/src/test/java/ix/EqualityHelperTest.java @@ -16,10 +16,10 @@ package ix; -import org.junit.Test; - -import static org.junit.Assert.*; import static ix.EqualityHelper.INSTANCE; +import static org.junit.Assert.*; + +import org.junit.Test; public class EqualityHelperTest { @@ -31,9 +31,9 @@ public void normal() { assertFalse(INSTANCE.test(null, 1)); assertFalse(INSTANCE.test(1, null)); assertFalse(INSTANCE.test(1, 2)); - + assertNotNull(EqualityHelper.valueOf("INSTANCE")); - + assertEquals(1, EqualityHelper.values().length); } } diff --git a/src/test/java/ix/ExceptTest.java b/src/test/java/ix/ExceptTest.java index f9e9f20..f166635 100644 --- a/src/test/java/ix/ExceptTest.java +++ b/src/test/java/ix/ExceptTest.java @@ -23,63 +23,63 @@ public class ExceptTest { @Test public void normal() { Ix source = Ix.range(1, 5).except(Ix.range(3, 5)); - + IxTestHelper.assertValues(source, 1, 2, 6, 7); - + IxTestHelper.assertNoRemove(source); } - + @Test public void firstEmpty() { Ix source = Ix.empty().except(Ix.range(3, 5)); - + IxTestHelper.assertValues(source, 3, 4, 5, 6, 7); - + IxTestHelper.assertNoRemove(source); } - + @Test public void secondEmpty() { Ix source = Ix.range(1, 5).except(Ix.empty()); - + IxTestHelper.assertValues(source, 1, 2, 3, 4, 5); - + IxTestHelper.assertNoRemove(source); } - + @Test public void firstInSecond() { Ix source = Ix.range(1, 5).except(Ix.range(1, 3)); - + IxTestHelper.assertValues(source, 4, 5); - + IxTestHelper.assertNoRemove(source); } @Test public void firstInFirst() { Ix source = Ix.range(1, 3).except(Ix.range(1, 5)); - + IxTestHelper.assertValues(source, 4, 5); - + IxTestHelper.assertNoRemove(source); } @Test public void distinct() { Ix source = Ix.range(1, 5).except(Ix.range(6, 5)); - + IxTestHelper.assertValues(source, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10); - + IxTestHelper.assertNoRemove(source); } - + @Test public void overlapWithDuplicates() { Ix source = Ix.fromArray(1, 2, 2, 3, 4, 5).except(Ix.range(1, 3)); - + IxTestHelper.assertValues(source, 4, 5); - + IxTestHelper.assertNoRemove(source); } } diff --git a/src/test/java/ix/FilterTest.java b/src/test/java/ix/FilterTest.java index 80c39f6..db5736d 100644 --- a/src/test/java/ix/FilterTest.java +++ b/src/test/java/ix/FilterTest.java @@ -24,51 +24,51 @@ public class FilterTest { @Test public void normal() { - Ix source = Ix.range(1, 10).filter(new Pred() { + Ix source = Ix.range(1, 10).filter(new IxPredicate() { @Override public boolean test(Integer v) { return (v & 1) != 0; } }); - + IxTestHelper.assertValues(source, 1, 3, 5, 7, 9); } - + @Test public void empty() { - Ix source = Ix.empty().filter(new Pred() { + Ix source = Ix.empty().filter(new IxPredicate() { @Override public boolean test(Integer v) { return (v & 1) != 0; } }); - + IxTestHelper.assertValues(source); } @Test public void empty2() { - Ix source = Ix.just(0).filter(new Pred() { + Ix source = Ix.just(0).filter(new IxPredicate() { @Override public boolean test(Integer v) { return (v & 1) != 0; } }); - + IxTestHelper.assertValues(source); } @Test public void removeComposes() { List list = Ix.range(1, 10).collectToList().first(); - - Ix.from(list).filter(new Pred() { + + Ix.from(list).filter(new IxPredicate() { @Override public boolean test(Integer v) { return (v & 1) != 0; } }).removeAll(); - + Assert.assertEquals(Arrays.asList(2, 4, 6, 8, 10), list); } } diff --git a/src/test/java/ix/FirstTest.java b/src/test/java/ix/FirstTest.java index e16c444..8a53b07 100644 --- a/src/test/java/ix/FirstTest.java +++ b/src/test/java/ix/FirstTest.java @@ -16,7 +16,7 @@ package ix; -import java.util.*; +import java.util.NoSuchElementException; import org.junit.*; @@ -25,42 +25,42 @@ public class FirstTest { @Test public void normal() { Ix source = Ix.range(1, 10); - + Assert.assertEquals(1, source.first().intValue()); } @Test public void just() { Ix source = Ix.just(1); - + Assert.assertEquals(1, source.first().intValue()); } @Test(expected = NoSuchElementException.class) public void empty() { Ix source = Ix.empty(); - + Assert.assertEquals(1, source.first().intValue()); } @Test public void emptyDefault() { Ix source = Ix.empty(); - + Assert.assertEquals(100, source.first(100).intValue()); } @Test public void justDefault() { Ix source = Ix.just(1); - + Assert.assertEquals(1, source.first(100).intValue()); } @Test public void rangeDefault() { Ix source = Ix.range(1, 10); - + Assert.assertEquals(1, source.first(100).intValue()); } diff --git a/src/test/java/ix/FlattenIterableTest.java b/src/test/java/ix/FlattenIterableTest.java index 0bcf696..f893498 100644 --- a/src/test/java/ix/FlattenIterableTest.java +++ b/src/test/java/ix/FlattenIterableTest.java @@ -18,81 +18,79 @@ import org.junit.Test; -import rx.functions.Func1; - public class FlattenIterableTest { @Test public void normal() { - Ix source = Ix.range(1, 5).flatMap(new Func1>() { + Ix source = Ix.range(1, 5).flatMap(new IxFunction>() { @Override - public Iterable call(Integer v) { + public Iterable apply(Integer v) { return Ix.range(v, 2); } }); - + IxTestHelper.assertValues(source, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6); - + IxTestHelper.assertNoRemove(source); } @Test public void normalViaConcatMap() { - Ix source = Ix.range(1, 5).concatMap(new Func1>() { + Ix source = Ix.range(1, 5).concatMap(new IxFunction>() { @Override - public Iterable call(Integer v) { + public Iterable apply(Integer v) { return Ix.range(v, 2); } }); - + IxTestHelper.assertValues(source, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6); } @Test public void just() { - Ix source = Ix.just(1).flatMap(new Func1>() { + Ix source = Ix.just(1).flatMap(new IxFunction>() { @Override - public Iterable call(Integer v) { + public Iterable apply(Integer v) { return Ix.range(v, 2); } }); - + IxTestHelper.assertValues(source, 1, 2); } @Test public void empty() { - Ix source = Ix.empty().flatMap(new Func1>() { + Ix source = Ix.empty().flatMap(new IxFunction>() { @Override - public Iterable call(Integer v) { + public Iterable apply(Integer v) { return Ix.range(v, 2); } }); - + IxTestHelper.assertValues(source); } @Test public void rangeJust() { - Ix source = Ix.range(1, 2).flatMap(new Func1>() { + Ix source = Ix.range(1, 2).flatMap(new IxFunction>() { @Override - public Iterable call(Integer v) { + public Iterable apply(Integer v) { return Ix.just(v); } }); - + IxTestHelper.assertValues(source, 1, 2); } - + @Test public void rangeEmpty() { - Ix source = Ix.range(1, 2).flatMap(new Func1>() { + Ix source = Ix.range(1, 2).flatMap(new IxFunction>() { @Override - public Iterable call(Integer v) { + public Iterable apply(Integer v) { return Ix.empty(); } }); - + IxTestHelper.assertValues(source); } } diff --git a/src/test/java/ix/ForeachTest.java b/src/test/java/ix/ForeachTest.java index d71dac5..7d82cf9 100644 --- a/src/test/java/ix/ForeachTest.java +++ b/src/test/java/ix/ForeachTest.java @@ -20,57 +20,55 @@ import org.junit.*; -import rx.functions.Action1; - -public class ForeachTest implements Action1, Pred { +public class ForeachTest implements IxConsumer, IxPredicate { List list; - + @Before public void before() { list = new ArrayList(); } - + @Override - public void call(Integer t) { + public void accept(Integer t) { list.add(t); } - + @Override public boolean test(Integer t) { list.add(t); return list.size() < 5; } - + @Test public void normal() { Ix source = Ix.range(1, 10); - + source.foreach(this); - + Assert.assertEquals(Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10), list); } @Test public void normalWhile() { Ix source = Ix.range(1, 10); - + source.foreachWhile(this); - + Assert.assertEquals(Arrays.asList(1, 2, 3, 4, 5), list); } @Test public void normalWhileAll() { Ix source = Ix.range(1, 5); - - source.foreachWhile(new Pred() { + + source.foreachWhile(new IxPredicate() { @Override public boolean test(Integer v) { return true; } }); - + IxTestHelper.assertValues(source, 1, 2, 3, 4, 5); } } diff --git a/src/test/java/ix/ForloopTest.java b/src/test/java/ix/ForloopTest.java index 8db6fdf..fa3d40b 100644 --- a/src/test/java/ix/ForloopTest.java +++ b/src/test/java/ix/ForloopTest.java @@ -18,55 +18,53 @@ import org.junit.Test; -import rx.functions.Func1; - public class ForloopTest { @Test public void normal() { - Ix source = Ix.forloop(1, new Pred() { + Ix source = Ix.forloop(1, new IxPredicate() { @Override public boolean test(Integer i) { return i <= 5; } - }, new Func1() { + }, new IxFunction() { @Override - public Integer call(Integer i) { + public Integer apply(Integer i) { return i + 1; } - }, new Func1() { + }, new IxFunction() { @Override - public Integer call(Integer i) { + public Integer apply(Integer i) { return i * i; } }); - + IxTestHelper.assertValues(source, 1, 4, 9, 16, 25); - + IxTestHelper.assertNoRemove(source); } - + @Test public void empty() { - Ix source = Ix.forloop(1, new Pred() { + Ix source = Ix.forloop(1, new IxPredicate() { @Override public boolean test(Integer i) { return false; } - }, new Func1() { + }, new IxFunction() { @Override - public Integer call(Integer i) { + public Integer apply(Integer i) { return i + 1; } - }, new Func1() { + }, new IxFunction() { @Override - public Integer call(Integer i) { + public Integer apply(Integer i) { return i * i; } }); - + IxTestHelper.assertValues(source); - + IxTestHelper.assertNoRemove(source); } } diff --git a/src/test/java/ix/FromArrayTest.java b/src/test/java/ix/FromArrayTest.java index 18d5944..959a440 100644 --- a/src/test/java/ix/FromArrayTest.java +++ b/src/test/java/ix/FromArrayTest.java @@ -23,30 +23,30 @@ public class FromArrayTest { @Test public void normal() { Ix source = Ix.fromArray(1, 2, 3, 4, 5, 6, 7, 8, 9, 10); - + IxTestHelper.assertValues(source, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10); - + IxTestHelper.assertNoRemove(source); } @Test public void range() { Ix source = Ix.fromArrayRange(1, 8, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10); - + IxTestHelper.assertValues(source, 2, 3, 4, 5, 6, 7, 8); } - + @Test public void empty() { Ix source = Ix.fromArray(); - + Assert.assertSame(source.getClass().toString(), source, Ix.empty()); } @Test public void just() { Ix source = Ix.fromArray(1); - + Assert.assertTrue(source.getClass().toString(), source instanceof IxScalarCallable); } @@ -58,28 +58,28 @@ public void rangeChecks() { } catch (IndexOutOfBoundsException ex) { Assert.assertEquals("start=-1, end=1, length=10", ex.getMessage()); } - + try { Ix.fromArrayRange(1, -1, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10); Assert.fail("Failed to throw IndexOutOfBoundsException"); } catch (IndexOutOfBoundsException ex) { Assert.assertEquals("start=1, end=-1, length=10", ex.getMessage()); } - + try { Ix.fromArrayRange(12, -1, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10); Assert.fail("Failed to throw IndexOutOfBoundsException"); } catch (IndexOutOfBoundsException ex) { Assert.assertEquals("start=12, end=-1, length=10", ex.getMessage()); } - + try { Ix.fromArrayRange(1, 12, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10); Assert.fail("Failed to throw IndexOutOfBoundsException"); } catch (IndexOutOfBoundsException ex) { Assert.assertEquals("start=1, end=12, length=10", ex.getMessage()); } - + try { Ix.fromArrayRange(12, 12, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10); Assert.fail("Failed to throw IndexOutOfBoundsException"); @@ -87,5 +87,5 @@ public void rangeChecks() { Assert.assertEquals("start=12, end=12, length=10", ex.getMessage()); } - } + } } diff --git a/src/test/java/ix/FromTest.java b/src/test/java/ix/FromTest.java index 82a1d3a..7b31271 100644 --- a/src/test/java/ix/FromTest.java +++ b/src/test/java/ix/FromTest.java @@ -25,18 +25,18 @@ public class FromTest { @Test public void normal() { Ix source = Ix.from(Arrays.asList(1, 2, 3, 4, 5)); - + Assert.assertTrue(source.getClass().toString(), source instanceof IxWrapper); - + IxTestHelper.assertValues(source, 1, 2, 3, 4, 5); } @Test public void noRewrapping() { Ix source = Ix.from(Ix.range(1, 5)); - + Assert.assertFalse(source.getClass().toString(), source instanceof IxWrapper); - + IxTestHelper.assertValues(source, 1, 2, 3, 4, 5); } diff --git a/src/test/java/ix/GenerateStatelessTest.java b/src/test/java/ix/GenerateStatelessTest.java index 6080d0c..70476d7 100644 --- a/src/test/java/ix/GenerateStatelessTest.java +++ b/src/test/java/ix/GenerateStatelessTest.java @@ -20,83 +20,80 @@ import org.junit.Test; -import rx.Observer; -import rx.functions.Action1; - public class GenerateStatelessTest { @Test public void normal() { - Ix source = Ix.generate(new Action1>() { + Ix source = Ix.generate(new IxConsumer>() { int count; @Override - public void call(Observer t) { + public void accept(IxEmitter t) { t.onNext(++count); if (count == 10) { - t.onCompleted(); + t.onComplete(); } } }); - + IxTestHelper.assertValues(source, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10); } - + @Test public void empty() { - Ix source = Ix.generate(new Action1>() { + Ix source = Ix.generate(new IxConsumer>() { @Override - public void call(Observer t) { - t.onCompleted(); + public void accept(IxEmitter t) { + t.onComplete(); } }); - + IxTestHelper.assertValues(source); } - + @Test(expected = IllegalStateException.class) public void never() { - Ix source = Ix.generate(new Action1>() { + Ix source = Ix.generate(new IxConsumer>() { @Override - public void call(Observer t) { + public void accept(IxEmitter t) { } }); - + IxTestHelper.assertValues(source); } @Test(expected = IllegalArgumentException.class) public void runtimeError() { - Ix source = Ix.generate(new Action1>() { + Ix source = Ix.generate(new IxConsumer>() { @Override - public void call(Observer t) { - t.onError(new IllegalArgumentException()); + public void accept(IxEmitter t) { + throw new IllegalArgumentException(); } }); - + IxTestHelper.assertValues(source); } @Test(expected = InternalError.class) public void error() { - Ix source = Ix.generate(new Action1>() { + Ix source = Ix.generate(new IxConsumer>() { @Override - public void call(Observer t) { - t.onError(new InternalError()); + public void accept(IxEmitter t) { + throw new InternalError(); } }); - + IxTestHelper.assertValues(source); } @Test(expected = RuntimeException.class) public void exceptionError() { - Ix source = Ix.generate(new Action1>() { + Ix source = Ix.generate(new IxConsumer>() { @Override - public void call(Observer t) { - t.onError(new IOException()); + public void accept(IxEmitter t) { + throw new RuntimeException(new IOException()); } }); - + IxTestHelper.assertValues(source); } diff --git a/src/test/java/ix/GenerateTest.java b/src/test/java/ix/GenerateTest.java index 09e8ab4..2f87eea 100644 --- a/src/test/java/ix/GenerateTest.java +++ b/src/test/java/ix/GenerateTest.java @@ -21,122 +21,116 @@ import org.junit.*; -import rx.Observer; -import rx.functions.*; - public class GenerateTest { - Func0 stateFactory = new Func0() { + IxSupplier stateFactory = new IxSupplier() { @Override - public Integer call() { + public Integer get() { return 0; } }; - + @Test public void normal() { - Ix source = Ix.generate(stateFactory, new Func2, Integer>() { + Ix source = Ix.generate(stateFactory, new IxFunction2, Integer>() { @Override - public Integer call(Integer s, Observer t) { + public Integer apply(Integer s, IxEmitter t) { int i = ++s; t.onNext(i); if (i == 10) { - t.onCompleted(); + t.onComplete(); } return i; } }); - + IxTestHelper.assertValues(source, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10); } - + @Test public void normalState() { final AtomicInteger value = new AtomicInteger(); - - Ix source = Ix.generate(stateFactory, new Func2, Integer>() { + + Ix source = Ix.generate(stateFactory, new IxFunction2, Integer>() { @Override - public Integer call(Integer s, Observer t) { + public Integer apply(Integer s, IxEmitter t) { int i = ++s; t.onNext(i); if (i == 10) { - t.onCompleted(); + t.onComplete(); } return i; } - }, new Action1() { + }, new IxConsumer() { @Override - public void call(Integer t) { + public void accept(Integer t) { value.set(t); } }); - + IxTestHelper.assertValues(source, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10); - + Assert.assertEquals(10, value.get()); } - + @Test public void empty() { - Ix source = Ix.generate(stateFactory, new Func2, Integer>() { + Ix source = Ix.generate(stateFactory, new IxFunction2, Integer>() { @Override - public Integer call(Integer s, Observer t) { - t.onCompleted(); + public Integer apply(Integer s, IxEmitter t) { + t.onComplete(); return s; } }); - + IxTestHelper.assertValues(source); } - + @Test(expected = IllegalStateException.class) public void never() { - Ix source = Ix.generate(stateFactory, new Func2, Integer>() { + Ix source = Ix.generate(stateFactory, new IxFunction2, Integer>() { @Override - public Integer call(Integer s, Observer t) { + public Integer apply(Integer s, IxEmitter t) { return s; } }); - + IxTestHelper.assertValues(source); } @Test(expected = IllegalArgumentException.class) public void runtimeError() { - Ix source = Ix.generate(stateFactory, new Func2, Integer>() { + Ix source = Ix.generate(stateFactory, new IxFunction2, Integer>() { @Override - public Integer call(Integer s, Observer t) { - t.onError(new IllegalArgumentException()); - return s; + public Integer apply(Integer s, IxEmitter t) { + throw new IllegalArgumentException(); } }); - + IxTestHelper.assertValues(source); } @Test(expected = InternalError.class) public void error() { - Ix source = Ix.generate(stateFactory, new Func2, Integer>() { + Ix source = Ix.generate(stateFactory, new IxFunction2, Integer>() { @Override - public Integer call(Integer s, Observer t) { - t.onError(new InternalError()); - return s; + public Integer apply(Integer s, IxEmitter t) { + throw new InternalError(); } }); - + IxTestHelper.assertValues(source); } @Test(expected = RuntimeException.class) public void exceptionError() { - Ix source = Ix.generate(stateFactory, new Func2, Integer>() { + Ix source = Ix.generate(stateFactory, new IxFunction2, Integer>() { @Override - public Integer call(Integer s, Observer t) { - t.onError(new IOException()); - return s; + public Integer apply(Integer s, IxEmitter t) { + throw new RuntimeException(new IOException()); } }); - + IxTestHelper.assertValues(source); } diff --git a/src/test/java/ix/GroupByTest.java b/src/test/java/ix/GroupByTest.java index 5e05857..dcdc8ea 100644 --- a/src/test/java/ix/GroupByTest.java +++ b/src/test/java/ix/GroupByTest.java @@ -20,109 +20,107 @@ import org.junit.*; -import rx.functions.*; - public class GroupByTest { @Test public void normal() { - Ix source = Ix.range(1, 10).groupBy(new Func1() { + Ix source = Ix.range(1, 10).groupBy(new IxFunction() { @Override - public Object call(Integer v) { + public Object apply(Integer v) { return v % 3; } - }).flatMap(new Func1, Iterable>() { + }).flatMap(new IxFunction, Iterable>() { @Override - public Iterable call(GroupedIx v) { + public Iterable apply(GroupedIx v) { return v; } }); - + IxTestHelper.assertValues(source, 1, 4, 7, 10, 2, 5, 8, 3, 6, 9); - + IxTestHelper.assertNoRemove(source); } - + @Test public void uniqueGroups() { - Ix source = Ix.range(1, 10).groupBy(new Func1() { + Ix source = Ix.range(1, 10).groupBy(new IxFunction() { @Override - public Object call(Integer v) { + public Object apply(Integer v) { return v; } }, - new Func1() { + new IxFunction() { @Override - public Integer call(Integer v) { + public Integer apply(Integer v) { return v * 10; } } - ).flatMap(new Func1, Iterable>() { + ).flatMap(new IxFunction, Iterable>() { @Override - public Iterable call(GroupedIx v) { + public Iterable apply(GroupedIx v) { return v; } }); - + IxTestHelper.assertValues(source, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100); - + IxTestHelper.assertNoRemove(source); } - + @Test public void just() { - Ix source = Ix.just(1).groupBy(new Func1() { + Ix source = Ix.just(1).groupBy(new IxFunction() { @Override - public Object call(Integer v) { + public Object apply(Integer v) { return v % 3; } - }).flatMap(new Func1, Iterable>() { + }).flatMap(new IxFunction, Iterable>() { @Override - public Iterable call(GroupedIx v) { + public Iterable apply(GroupedIx v) { return v; } }); - + IxTestHelper.assertValues(source, 1); - + IxTestHelper.assertNoRemove(source); } - + @Test public void justNull() { - Ix source = Ix.just(null).groupBy(new Func1() { + Ix source = Ix.just(null).groupBy(new IxFunction() { @Override - public Object call(Integer v) { + public Object apply(Integer v) { return 1; } - }).flatMap(new Func1, Iterable>() { + }).flatMap(new IxFunction, Iterable>() { @Override - public Iterable call(GroupedIx v) { + public Iterable apply(GroupedIx v) { return v; } }); - + IxTestHelper.assertValues(source, (Integer)null); - + IxTestHelper.assertNoRemove(source); } @Test public void empty() { - Ix source = Ix.empty().groupBy(new Func1() { + Ix source = Ix.empty().groupBy(new IxFunction() { @Override - public Object call(Integer v) { + public Object apply(Integer v) { return v % 3; } - }).flatMap(new Func1, Iterable>() { + }).flatMap(new IxFunction, Iterable>() { @Override - public Iterable call(GroupedIx v) { + public Iterable apply(GroupedIx v) { return v; } }); - + IxTestHelper.assertValues(source); - + IxTestHelper.assertNoRemove(source); } @@ -130,15 +128,15 @@ public Iterable call(GroupedIx v) { @Test public void lockstep() { final Iterator[] its = new Iterator[3]; - - Iterator main = Ix.range(1, 10).groupBy(new Func1() { + + Iterator main = Ix.range(1, 10).groupBy(new IxFunction() { @Override - public Integer call(Integer v) { + public Integer apply(Integer v) { return v % 3; } - }).doOnNext(new Action1>() { + }).doOnNext(new IxConsumer>() { @Override - public void call(GroupedIx g) { + public void accept(GroupedIx g) { its[g.key()] = g.iterator(); } }) @@ -147,49 +145,49 @@ public void call(GroupedIx g) { Assert.assertNotNull(main.next()); Assert.assertEquals(1, its[1].next().intValue()); - + Assert.assertNotNull(main.next()); Assert.assertEquals(2, its[2].next().intValue()); - + Assert.assertTrue(its[2].hasNext()); Assert.assertNotNull(main.next()); - + Assert.assertEquals(3, its[0].next().intValue()); Assert.assertEquals(4, its[1].next().intValue()); Assert.assertEquals(5, its[2].next().intValue()); Assert.assertEquals(6, its[0].next().intValue()); - + Assert.assertEquals(7, its[1].next().intValue()); Assert.assertEquals(8, its[2].next().intValue()); Assert.assertEquals(9, its[0].next().intValue()); Assert.assertEquals(10, its[1].next().intValue()); - + Assert.assertFalse(main.hasNext()); Assert.assertFalse(its[0].hasNext()); Assert.assertFalse(its[1].hasNext()); Assert.assertFalse(its[2].hasNext()); } - - + + @SuppressWarnings("unchecked") @Test public void lockstepNull() { final Iterator[] its = new Iterator[3]; - - Iterator main = Ix.range(1, 10).groupBy(new Func1() { + + Iterator main = Ix.range(1, 10).groupBy(new IxFunction() { @Override - public Integer call(Integer v) { + public Integer apply(Integer v) { return v % 3; } - }, new Func1() { + }, new IxFunction() { @Override - public Integer call(Integer v) { + public Integer apply(Integer v) { return null; } - }).doOnNext(new Action1>() { + }).doOnNext(new IxConsumer>() { @Override - public void call(GroupedIx g) { + public void accept(GroupedIx g) { its[g.key()] = g.iterator(); } }) @@ -198,24 +196,24 @@ public void call(GroupedIx g) { Assert.assertNotNull(main.next()); Assert.assertNull(its[1].next()); - + Assert.assertNotNull(main.next()); Assert.assertNull(its[2].next()); - + Assert.assertTrue(its[2].hasNext()); Assert.assertNotNull(main.next()); - + Assert.assertNull(its[0].next()); Assert.assertNull(its[1].next()); Assert.assertNull(its[2].next()); Assert.assertNull(its[0].next()); - + Assert.assertNull(its[1].next()); Assert.assertNull(its[2].next()); Assert.assertNull(its[0].next()); Assert.assertNull(its[1].next()); - + Assert.assertFalse(main.hasNext()); Assert.assertFalse(its[0].hasNext()); Assert.assertFalse(its[1].hasNext()); @@ -223,51 +221,51 @@ public void call(GroupedIx g) { } @Test public void sameGroupSubsequently() { - Ix> source = Ix.range(1, 5).groupBy(new Func1() { + Ix> source = Ix.range(1, 5).groupBy(new IxFunction() { @Override - public Integer call(Integer v) { + public Integer apply(Integer v) { return 1; } }); - + List> list = source.collectToList().first(); IxTestHelper.assertValues(Ix.concat(list), 1, 2, 3, 4, 5); } - + @Test public void sameGroupSubsequentlyNullValue() { - Ix> source = Ix.range(1, 5).groupBy(new Func1() { + Ix> source = Ix.range(1, 5).groupBy(new IxFunction() { @Override - public Integer call(Integer v) { + public Integer apply(Integer v) { return 1; } - }, new Func1() { + }, new IxFunction() { @Override - public Integer call(Integer v) { + public Integer apply(Integer v) { return null; } }); - + List> list = source.collectToList().first(); IxTestHelper.assertValues(Ix.concat(list), null, null, null, null, null); } - + @Test(expected = IllegalStateException.class) public void iteratorOnce() { - Ix> source = Ix.range(1, 5).groupBy(new Func1() { + Ix> source = Ix.range(1, 5).groupBy(new IxFunction() { @Override - public Integer call(Integer v) { + public Integer apply(Integer v) { return 1; } - }, new Func1() { + }, new IxFunction() { @Override - public Integer call(Integer v) { + public Integer apply(Integer v) { return null; } }); - + List> list = source.collectToList().first(); Assert.assertEquals("GroupedIterable[key=1, queue=5]", list.get(0).toString()); diff --git a/src/test/java/ix/HasElementsTest.java b/src/test/java/ix/HasElementsTest.java index 18afdca..fb697ea 100644 --- a/src/test/java/ix/HasElementsTest.java +++ b/src/test/java/ix/HasElementsTest.java @@ -23,14 +23,14 @@ public class HasElementsTest { @Test public void empty() { Ix source = Ix.empty().hasElements(); - + IxTestHelper.assertValues(source, false); } @Test public void nonempty() { Ix source = Ix.just(1).hasElements(); - + IxTestHelper.assertValues(source, true); } diff --git a/src/test/java/ix/HelperTest.java b/src/test/java/ix/HelperTest.java index d53fea1..1615271 100644 --- a/src/test/java/ix/HelperTest.java +++ b/src/test/java/ix/HelperTest.java @@ -26,14 +26,14 @@ public void toListHelper() { Assert.assertNotNull(ToListHelper.valueOf("INSTANCE")); } - + @Test public void identityHelper() { Assert.assertEquals(1, IdentityHelper.values().length); Assert.assertNotNull(IdentityHelper.valueOf("INSTANCE")); } - + @Test public void numberToLongHelper() { Assert.assertEquals(1, NumberToLongHelper.values().length); diff --git a/src/test/java/ix/HideTest.java b/src/test/java/ix/HideTest.java index 1e2622f..4089ac9 100644 --- a/src/test/java/ix/HideTest.java +++ b/src/test/java/ix/HideTest.java @@ -25,7 +25,7 @@ public void normal() { Ix source = Ix.just(1); Assert.assertTrue(source instanceof IxScalarCallable); - + Assert.assertFalse((source.hide()) instanceof IxScalarCallable); } } diff --git a/src/test/java/ix/IgnoreElementsTest.java b/src/test/java/ix/IgnoreElementsTest.java index 786186f..fc20800 100644 --- a/src/test/java/ix/IgnoreElementsTest.java +++ b/src/test/java/ix/IgnoreElementsTest.java @@ -23,18 +23,18 @@ public class IgnoreElementsTest { @Test public void range() { Ix source = Ix.range(1, 5).ignoreElements(); - + IxTestHelper.assertValues(source); - + IxTestHelper.assertNoRemove(source); } @Test public void empty() { Ix source = Ix.empty().ignoreElements(); - + IxTestHelper.assertValues(source); - + IxTestHelper.assertNoRemove(source); } diff --git a/src/test/java/ix/IntersectTest.java b/src/test/java/ix/IntersectTest.java index 64ade1e..48df2da 100644 --- a/src/test/java/ix/IntersectTest.java +++ b/src/test/java/ix/IntersectTest.java @@ -23,45 +23,45 @@ public class IntersectTest { @Test public void normal() { Ix source = Ix.range(1, 5).intersect(Ix.range(3, 5)); - + IxTestHelper.assertValues(source, 3, 4, 5); - + IxTestHelper.assertNoRemove(source); } - + @Test public void same() { Ix source = Ix.range(1, 5).intersect(Ix.range(1, 5)); - + IxTestHelper.assertValues(source, 1, 2, 3, 4, 5); - + IxTestHelper.assertNoRemove(source); } @Test public void distinct() { Ix source = Ix.range(1, 5).intersect(Ix.range(6, 5)); - + IxTestHelper.assertValues(source); - + IxTestHelper.assertNoRemove(source); } - + @Test public void distinctEmptyFirst() { Ix source = Ix.empty().intersect(Ix.range(6, 5)); - + IxTestHelper.assertValues(source); - + IxTestHelper.assertNoRemove(source); } @Test public void distinctEmptySecond() { Ix source = Ix.range(1, 5).intersect(Ix.empty()); - + IxTestHelper.assertValues(source); - + IxTestHelper.assertNoRemove(source); } diff --git a/src/test/java/ix/IxOperatorsArePackageFinalTest.java b/src/test/java/ix/IxOperatorsArePackageFinalTest.java new file mode 100644 index 0000000..b33f248 --- /dev/null +++ b/src/test/java/ix/IxOperatorsArePackageFinalTest.java @@ -0,0 +1,65 @@ +/* + * Copyright 2011-2016 David Karnok + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ix; + +import java.io.File; +import java.lang.reflect.Modifier; +import java.net.URL; + +import org.junit.*; + +public class IxOperatorsArePackageFinalTest { + + @Test + public void checkOperatorsFinal() throws Exception { + + URL u = IxOperatorsArePackageFinalTest.class.getResource(IxOperatorsArePackageFinalTest.class.getSimpleName() + ".class"); + + File f = new File(u.toURI()); + + File g = f.getParentFile(); + + File[] files = g.listFiles(); + + StringBuilder b = new StringBuilder(); + + if (files != null && files.length != 0) { + for (File h : files) { + if (h.getName().contains("Test") + || h.getName().contains("Perf") + || h.getName().contains("$")) { + continue; + } + + Class clazz = Class.forName("ix." + h.getName().replace(".class", "")); + + if ((clazz.getModifiers() & Modifier.FINAL) == 0 + && (clazz.getModifiers() & Modifier.ABSTRACT) == 0 + && (clazz.getModifiers() & Modifier.INTERFACE) == 0) { + b.append("java.lang.RuntimeException: " + h.getName() + " is not final\r\n") + .append(" at ").append(clazz.getName()).append(" (").append(h.getName()).append(":1)\r\n\r\n"); + } + } + } + + if (b.length() != 0) { + System.out.println(b); + + Assert.fail(b.toString()); + } + } +} diff --git a/src/test/java/ix/IxTest.java b/src/test/java/ix/IxTest.java index 3102a19..b413efd 100644 --- a/src/test/java/ix/IxTest.java +++ b/src/test/java/ix/IxTest.java @@ -25,7 +25,7 @@ public class IxTest { @Test(expected = RuntimeException.class) public void checkedCallWraps() { - + Ix.checkedCall(new Callable() { @Override public Integer call() throws Exception { @@ -33,10 +33,10 @@ public Integer call() throws Exception { } }); } - + @Test(expected = InternalError.class) public void checkedCallNoWrapsError() { - + Ix.checkedCall(new Callable() { @Override public Integer call() throws Exception { @@ -47,7 +47,7 @@ public Integer call() throws Exception { @Test(expected = IllegalArgumentException.class) public void checkedCallNoWrapping() { - + Ix.checkedCall(new Callable() { @Override public Integer call() throws Exception { @@ -55,7 +55,7 @@ public Integer call() throws Exception { } }); } - + @Test public void nullCheck() { Ix.nullCheck(1, "Should not fail"); @@ -66,24 +66,24 @@ public void nullCheck() { Assert.assertEquals("Failure", ex.getMessage()); } } - + @Test public void nonNegativeLong() { Ix.nonNegative(0L, "n"); Ix.nonNegative(1L, "n"); - + try { Ix.nonNegative(-99L, "n"); } catch (IllegalArgumentException ex) { Assert.assertEquals("n >= 0 required but it was -99", ex.getMessage()); } } - + @Test public void nonNegativeInt() { Ix.nonNegative(0, "n"); Ix.nonNegative(1, "n"); - + try { Ix.nonNegative(-99, "n"); } catch (IllegalArgumentException ex) { @@ -94,7 +94,7 @@ public void nonNegativeInt() { @Test public void positiveInt() { Ix.nonNegative(1, "n"); - + try { Ix.positive(0, "n"); } catch (IllegalArgumentException ex) { diff --git a/src/test/java/ix/IxTestHelper.java b/src/test/java/ix/IxTestHelper.java index 202c478..d0fa6f9 100644 --- a/src/test/java/ix/IxTestHelper.java +++ b/src/test/java/ix/IxTestHelper.java @@ -22,11 +22,11 @@ public enum IxTestHelper { ; - + static String classOf(Object o) { return o != null ? o.getClass().getSimpleName() : "null"; } - + /** * Asserts that the iterable produces the specified array of values and * verifies if it honors the iterator contract. @@ -37,38 +37,38 @@ static String classOf(Object o) { public static void assertValues(Iterable source, T... values) { Iterator a = source.iterator(); int i = 0; - + for (;;) { boolean b1 = a.hasNext(); boolean b2 = a.hasNext(); - + Assert.assertEquals("Inconsistent hasNext()", b1, b2); if (!b1) { break; } - + if (i == values.length) { throw new AssertionError("The source is longer than " + values.length); } - + T t = a.next(); - + if (t instanceof Object[]) { Assert.assertArrayEquals((Object[])values[i], (Object[])t); } else { - Assert.assertEquals("index=" + i + ", expected class=" - + classOf(values[i]) + Assert.assertEquals("index=" + i + ", expected class=" + + classOf(values[i]) + ", actual class=" + classOf(t), values[i], t); } i++; } - + if (i != values.length) { throw new AssertionError("The source is shorter than " + values.length + ": " + i); } - + try { a.next(); Assert.fail("The next() should have thrown a NoSuchElementException"); @@ -76,7 +76,7 @@ public static void assertValues(Iterable source, T... values) { // expected } } - + /** * Assert that calling remove() on the source's Iterator throws * an UnsupportedOperationException. @@ -84,7 +84,7 @@ public static void assertValues(Iterable source, T... values) { */ public static void assertNoRemove(Iterable source) { Iterator it = source.iterator(); - + if (it.hasNext()) { it.next(); try { @@ -95,7 +95,7 @@ public static void assertNoRemove(Iterable source) { } } } - + public static List range(int start, int count) { return Ix.range(start, count).collectToList().first(); } diff --git a/src/test/java/ix/JoinTest.java b/src/test/java/ix/JoinTest.java index aa97e0d..a94a3a7 100644 --- a/src/test/java/ix/JoinTest.java +++ b/src/test/java/ix/JoinTest.java @@ -23,54 +23,54 @@ public class JoinTest { @Test public void normal() { Ix source = Ix.range(1, 5).join(); - + IxTestHelper.assertValues(source, "1, 2, 3, 4, 5"); - + IxTestHelper.assertNoRemove(source); } @Test public void just() { Ix source = Ix.just(1).join(); - + IxTestHelper.assertValues(source, "1"); - + IxTestHelper.assertNoRemove(source); } @Test public void empty() { Ix source = Ix.empty().join(); - + IxTestHelper.assertValues(source, ""); - + IxTestHelper.assertNoRemove(source); } @Test public void normalSeparator() { Ix source = Ix.range(1, 5).join("|"); - + IxTestHelper.assertValues(source, "1|2|3|4|5"); - + IxTestHelper.assertNoRemove(source); } @Test public void justSeparator() { Ix source = Ix.just(1).join("|"); - + IxTestHelper.assertValues(source, "1"); - + IxTestHelper.assertNoRemove(source); } @Test public void emptySeparator() { Ix source = Ix.empty().join("|"); - + IxTestHelper.assertValues(source, ""); - + IxTestHelper.assertNoRemove(source); } diff --git a/src/test/java/ix/JustTest.java b/src/test/java/ix/JustTest.java index 7fe8359..d2f5a67 100644 --- a/src/test/java/ix/JustTest.java +++ b/src/test/java/ix/JustTest.java @@ -23,9 +23,9 @@ public class JustTest { @Test public void normal() { Ix source = Ix.just(1); - + IxTestHelper.assertValues(source, 1); - + IxTestHelper.assertNoRemove(source); } } diff --git a/src/test/java/ix/LastTest.java b/src/test/java/ix/LastTest.java index a921b2f..ee54abd 100644 --- a/src/test/java/ix/LastTest.java +++ b/src/test/java/ix/LastTest.java @@ -16,7 +16,7 @@ package ix; -import java.util.*; +import java.util.NoSuchElementException; import org.junit.*; @@ -25,42 +25,42 @@ public class LastTest { @Test public void normal() { Ix source = Ix.range(1, 10); - + Assert.assertEquals(10, source.last().intValue()); } @Test public void just() { Ix source = Ix.just(1); - + Assert.assertEquals(1, source.last().intValue()); } @Test(expected = NoSuchElementException.class) public void empty() { Ix source = Ix.empty(); - + Assert.assertEquals(1, source.last().intValue()); } @Test public void emptyDefault() { Ix source = Ix.empty(); - + Assert.assertEquals(100, source.last(100).intValue()); } @Test public void justDefault() { Ix source = Ix.just(1); - + Assert.assertEquals(1, source.last(100).intValue()); } @Test public void rangeDefault() { Ix source = Ix.range(1, 10); - + Assert.assertEquals(10, source.last(100).intValue()); } diff --git a/src/test/java/ix/LeavingTest.java b/src/test/java/ix/LeavingTest.java index 735af6c..1a21bc5 100644 --- a/src/test/java/ix/LeavingTest.java +++ b/src/test/java/ix/LeavingTest.java @@ -21,20 +21,17 @@ import org.junit.*; -import rx.functions.*; -import rx.observers.TestSubscriber; - public class LeavingTest { @Test public void normal() { List list = new ArrayList(); - + Ix.range(1, 5).into(list); - + Assert.assertEquals(Arrays.asList(1, 2, 3, 4, 5), list); } - + @Test public void print() throws Exception { PrintStream old = System.out; @@ -42,18 +39,18 @@ public void print() throws Exception { System.setOut(new PrintStream(bout)); try { Ix.range(1, 30).print(); - + System.out.flush(); } finally { System.setOut(old); } - + String[] s = bout.toString("UTF-8").split(System.getProperty("line.separator")); - + Assert.assertEquals(Ix.range(1, 23).join().first() + ", ", s[0]); Assert.assertEquals(Ix.range(24, 7).join().first(), s[1]); } - + @Test public void print40() throws Exception { PrintStream old = System.out; @@ -61,14 +58,14 @@ public void print40() throws Exception { System.setOut(new PrintStream(bout)); try { Ix.range(1, 30).print(",", 40); - + System.out.flush(); } finally { System.setOut(old); } - + String[] s = bout.toString("UTF-8").split(System.getProperty("line.separator")); - + Assert.assertEquals(Ix.range(1, 17).join(",").first() + ",", s[0]); Assert.assertEquals(Ix.range(18, 13).join(",").first(), s[1]); } @@ -80,14 +77,14 @@ public void println() throws Exception { System.setOut(new PrintStream(bout)); try { Ix.range(1, 3).println(); - + System.out.flush(); } finally { System.setOut(old); } - + String[] s = bout.toString("UTF-8").split(System.getProperty("line.separator")); - + Assert.assertEquals("1", s[0]); Assert.assertEquals("2", s[1]); Assert.assertEquals("3", s[2]); @@ -100,318 +97,187 @@ public void printlnPrefix() throws Exception { System.setOut(new PrintStream(bout)); try { Ix.range(1, 3).println("--"); - + System.out.flush(); } finally { System.setOut(old); } - + String[] s = bout.toString("UTF-8").split(System.getProperty("line.separator")); - + Assert.assertEquals("--1", s[0]); Assert.assertEquals("--2", s[1]); Assert.assertEquals("--3", s[2]); } - + @Test public void run() { final List list = new ArrayList(); - - Ix.range(1, 5).doOnNext(new Action1() { + + Ix.range(1, 5).doOnNext(new IxConsumer() { @Override - public void call(Integer v) { + public void accept(Integer v) { list.add(v); } }).run(); - + Assert.assertEquals(Arrays.asList(1, 2, 3, 4, 5), list); } @Test public void subscribe() { final List list = new ArrayList(); - - Ix.range(1, 5).doOnNext(new Action1() { + + Ix.range(1, 5).doOnNext(new IxConsumer() { @Override - public void call(Integer v) { + public void accept(Integer v) { list.add(v); } }).subscribe(); - + Assert.assertEquals(Arrays.asList(1, 2, 3, 4, 5), list); } @Test public void subscribeAction1() { final List list = new ArrayList(); - - Ix.range(1, 5).subscribe(new Action1() { + + Ix.range(1, 5).subscribe(new IxConsumer() { @Override - public void call(Integer v) { + public void accept(Integer v) { list.add(v); } }); - + Assert.assertEquals(Arrays.asList(1, 2, 3, 4, 5), list); } - + @Test public void subscribeAction1Action1() { final List list = new ArrayList(); - - Ix.range(1, 5).subscribe(new Action1() { + + Ix.range(1, 5).subscribe(new IxConsumer() { @Override - public void call(Integer v) { + public void accept(Integer v) { list.add(v); } - }, new Action1() { + }, new IxConsumer() { @Override - public void call(Throwable t) { - + public void accept(Throwable t) { + } }); - + Assert.assertEquals(Arrays.asList(1, 2, 3, 4, 5), list); } - + @Test public void subscribeAction1Action1Throws() { final List list = new ArrayList(); - + final Throwable[] error = { null }; - - Ix.range(1, 5).subscribe(new Action1() { + + Ix.range(1, 5).subscribe(new IxConsumer() { @Override - public void call(Integer v) { + public void accept(Integer v) { if (v == 5) { throw new IllegalStateException(); } list.add(v); } - }, new Action1() { + }, new IxConsumer() { @Override - public void call(Throwable t) { + public void accept(Throwable t) { error[0] = t; } }); - + Assert.assertEquals(Arrays.asList(1, 2, 3, 4), list); Assert.assertTrue(String.valueOf(error[0]), error[0] instanceof IllegalStateException); } - + @Test public void subscribeAction1Action1Action0() { final List list = new ArrayList(); - - Ix.range(1, 5).subscribe(new Action1() { + + Ix.range(1, 5).subscribe(new IxConsumer() { @Override - public void call(Integer v) { + public void accept(Integer v) { list.add(v); } - }, new Action1() { + }, new IxConsumer() { @Override - public void call(Throwable t) { - + public void accept(Throwable t) { + } - }, new Action0() { + }, new Runnable() { @Override - public void call() { + public void run() { list.add(100); } }); - + Assert.assertEquals(Arrays.asList(1, 2, 3, 4, 5, 100), list); } - + @Test public void subscribeAction1Action1Action0Throws() { final List list = new ArrayList(); - + final Throwable[] error = { null }; - - Ix.range(1, 5).subscribe(new Action1() { + + Ix.range(1, 5).subscribe(new IxConsumer() { @Override - public void call(Integer v) { + public void accept(Integer v) { if (v == 5) { throw new IllegalStateException(); } list.add(v); } - }, new Action1() { + }, new IxConsumer() { @Override - public void call(Throwable t) { + public void accept(Throwable t) { error[0] = t; } - }, new Action0() { + }, new Runnable() { @Override - public void call() { + public void run() { list.add(100); } }); - + Assert.assertEquals(Arrays.asList(1, 2, 3, 4), list); Assert.assertTrue(String.valueOf(error[0]), error[0] instanceof IllegalStateException); } - - @Test - public void subscribeObserver() { - TestSubscriber ts = new TestSubscriber(); - Ix.range(1, 5).subscribe((rx.Observer)ts); - - ts.assertValues(1, 2, 3, 4, 5); - ts.assertNoErrors(); - ts.assertCompleted(); - } - @Test - public void subscribeObserverThrows() { - TestSubscriber ts = new TestSubscriber(); - Ix.range(1, 5) - .doOnNext(new Action1() { - @Override - public void call(Integer v) { - if (v == 5) { - throw new IllegalStateException(); - } - } - }) - .subscribe((rx.Observer)ts); - - ts.assertValues(1, 2, 3, 4); - ts.assertError(IllegalStateException.class); - ts.assertNotCompleted(); - } - - @Test - public void subscribeSubscriber() { - TestSubscriber ts = new TestSubscriber(); - Ix.range(1, 5).subscribe(ts); - - ts.assertValues(1, 2, 3, 4, 5); - ts.assertNoErrors(); - ts.assertCompleted(); - } - - @Test - public void subscribeSubscriberTakeLess() { - TestSubscriber ts = new TestSubscriber() { - @Override - public void onNext(Integer t) { - super.onNext(t); - if (t == 4) { - unsubscribe(); - } - } - }; - Ix.range(1, 5).subscribe(ts); - - ts.assertValues(1, 2, 3, 4); - ts.assertNoErrors(); - ts.assertNotCompleted(); - } - - @Test - public void subscribeSubscriberTakeLessAndThrow() { - TestSubscriber ts = new TestSubscriber() { - @Override - public void onNext(Integer t) { - super.onNext(t); - if (t == 4) { - unsubscribe(); - throw new IllegalStateException(); - } - } - }; - Ix.range(1, 5).subscribe(ts); - - ts.assertValues(1, 2, 3, 4); - ts.assertNoErrors(); - ts.assertNotCompleted(); - } - - @Test - public void subscribeSubscriberThrow() { - TestSubscriber ts = new TestSubscriber() { - @Override - public void onNext(Integer t) { - super.onNext(t); - if (t == 4) { - throw new IllegalStateException(); - } - } - }; - Ix.range(1, 5).subscribe(ts); - - ts.assertValues(1, 2, 3, 4); - ts.assertError(IllegalStateException.class); - ts.assertNotCompleted(); - } - - @Test - public void subscribeSubscriberThrows() { - TestSubscriber ts = new TestSubscriber(); - Ix.range(1, 5) - .doOnNext(new Action1() { - @Override - public void call(Integer v) { - if (v == 5) { - throw new IllegalStateException(); - } - } - }) - .subscribe(ts); - - ts.assertValues(1, 2, 3, 4); - ts.assertError(IllegalStateException.class); - ts.assertNotCompleted(); - } - - @Test - public void subscribeSubscriberTakeExact() { - TestSubscriber ts = new TestSubscriber() { - @Override - public void onNext(Integer t) { - super.onNext(t); - if (t == 5) { - unsubscribe(); - } - } - }; - Ix.range(1, 5).subscribe(ts); - - ts.assertValues(1, 2, 3, 4, 5); - ts.assertNoErrors(); - ts.assertNotCompleted(); - } - @Test public void retainAll() { List list = Ix.range(1, 10).collectToList().first(); - - Ix.from(list).retainAll(new Pred() { + + Ix.from(list).retainAll(new IxPredicate() { @Override public boolean test(Integer v) { return (v & 1) == 0; } }); - + Assert.assertEquals(Arrays.asList(2, 4, 6, 8, 10), list); } - + @Test public void removeAll() { List list = Ix.range(1, 10).collectToList().first(); - - Ix.from(list).removeAll(new Pred() { + + Ix.from(list).removeAll(new IxPredicate() { @Override public boolean test(Integer v) { return (v & 1) == 1; } }); - + Assert.assertEquals(Arrays.asList(2, 4, 6, 8, 10), list); } - + @Test public void single() { Assert.assertEquals(1, Ix.just(1).single().intValue()); diff --git a/src/test/java/ix/LiftTest.java b/src/test/java/ix/LiftTest.java index 62e96ee..2fa3413 100644 --- a/src/test/java/ix/LiftTest.java +++ b/src/test/java/ix/LiftTest.java @@ -20,26 +20,24 @@ import org.junit.Test; -import rx.functions.Func1; - public class LiftTest { @Test public void normal() { - Ix source = Ix.just(1).lift(new Func1, Iterator>() { + Ix source = Ix.just(1).lift(new IxFunction, Iterator>() { @Override - public Iterator call(final Iterator it) { + public Iterator apply(final Iterator it) { return new Iterator() { @Override public boolean hasNext() { return it.hasNext(); } - + @Override public Integer next() { return it.next() + 10; } - + @Override public void remove() { throw new UnsupportedOperationException(); @@ -47,9 +45,9 @@ public void remove() { }; } }); - + IxTestHelper.assertValues(source, 11); - + IxTestHelper.assertNoRemove(source); } } diff --git a/src/test/java/ix/MapTest.java b/src/test/java/ix/MapTest.java index 29c67f9..189a952 100644 --- a/src/test/java/ix/MapTest.java +++ b/src/test/java/ix/MapTest.java @@ -20,33 +20,31 @@ import org.junit.*; -import rx.functions.Func1; - public class MapTest { @Test public void normal() { - Ix source = Ix.range(1, 10).map(new Func1() { + Ix source = Ix.range(1, 10).map(new IxFunction() { @Override - public Integer call(Integer v) { + public Integer apply(Integer v) { return v + 1; } }); - + IxTestHelper.assertValues(source, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11); } - + @Test public void removeComposes() { List list = Ix.range(1, 10).collectToList().first(); - - Ix.from(list).map(new Func1() { + + Ix.from(list).map(new IxFunction() { @Override - public Integer call(Integer v) { + public Integer apply(Integer v) { return v + 1; } }).removeAll(); - + Assert.assertEquals(Arrays.asList(), list); } } diff --git a/src/test/java/ix/MaxTest.java b/src/test/java/ix/MaxTest.java index 5ad0d65..22c291e 100644 --- a/src/test/java/ix/MaxTest.java +++ b/src/test/java/ix/MaxTest.java @@ -25,42 +25,42 @@ public class MaxTest { @Test public void normal() { Ix source = Ix.range(1, 10).maxInt(); - + assertEquals(10L, source.first().intValue()); } @Test public void just() { Ix source = Ix.just(1).maxInt(); - + assertEquals(1, source.first().intValue()); } @Test public void empty() { Ix source = Ix.empty().maxInt(); - + IxTestHelper.assertValues(source); } @Test public void normalLong() { Ix source = Ix.range(1, 10).toLong().maxLong(); - + assertEquals(10L, source.first().longValue()); } @Test public void justLong() { Ix source = Ix.just(1L).maxLong(); - + assertEquals(1L, source.first().longValue()); } @Test public void emptyLong() { Ix source = Ix.empty().maxLong(); - + IxTestHelper.assertValues(source); } diff --git a/src/test/java/ix/MinMaxTest.java b/src/test/java/ix/MinMaxTest.java index 741f8f3..770232e 100644 --- a/src/test/java/ix/MinMaxTest.java +++ b/src/test/java/ix/MinMaxTest.java @@ -30,10 +30,10 @@ public int compare(Integer a, Integer b) { return b.compareTo(a); } }); - + IxTestHelper.assertValues(source, 5); } - + @Test public void minComparatorEmpty() { Ix source = Ix.empty().min(new Comparator() { @@ -42,7 +42,7 @@ public int compare(Integer a, Integer b) { return b.compareTo(a); } }); - + IxTestHelper.assertValues(source); } @@ -54,7 +54,7 @@ public int compare(Integer a, Integer b) { return b.compareTo(a); } }); - + IxTestHelper.assertValues(source, 1); } @@ -66,10 +66,10 @@ public int compare(Integer a, Integer b) { return b.compareTo(a); } }); - + IxTestHelper.assertValues(source, 1); } - + @Test public void maxComparatorEmpty() { Ix source = Ix.empty().max(new Comparator() { @@ -78,7 +78,7 @@ public int compare(Integer a, Integer b) { return b.compareTo(a); } }); - + IxTestHelper.assertValues(source); } @@ -90,49 +90,49 @@ public int compare(Integer a, Integer b) { return b.compareTo(a); } }); - + IxTestHelper.assertValues(source, 1); } - + @Test public void min() { Ix source = Ix.range(1, 5).min(); - + IxTestHelper.assertValues(source, 1); } - + @Test public void minEmpty() { Ix source = Ix.empty().min(); - + IxTestHelper.assertValues(source); } @Test public void minJust() { Ix source = Ix.just(1).min(); - + IxTestHelper.assertValues(source, 1); } @Test public void max() { Ix source = Ix.range(1, 5).max(); - + IxTestHelper.assertValues(source, 5); } - + @Test public void maxEmpty() { Ix source = Ix.empty().max(); - + IxTestHelper.assertValues(source); } @Test public void maxJust() { Ix source = Ix.just(1).max(); - + IxTestHelper.assertValues(source, 1); } } diff --git a/src/test/java/ix/MinTest.java b/src/test/java/ix/MinTest.java index 49d1dd4..79c3e7b 100644 --- a/src/test/java/ix/MinTest.java +++ b/src/test/java/ix/MinTest.java @@ -25,42 +25,42 @@ public class MinTest { @Test public void normal() { Ix source = Ix.range(1, 10).minInt(); - + assertEquals(1, source.first().intValue()); } @Test public void just() { Ix source = Ix.just(1).minInt(); - + assertEquals(1, source.first().intValue()); } @Test public void empty() { Ix source = Ix.empty().minInt(); - + IxTestHelper.assertValues(source); } @Test public void normalLong() { Ix source = Ix.range(1, 10).toLong().minLong(); - + assertEquals(1, source.first().longValue()); } @Test public void justLong() { Ix source = Ix.just(1L).minLong(); - + assertEquals(1L, source.first().longValue()); } @Test public void emptyLong() { Ix source = Ix.empty().minLong(); - + IxTestHelper.assertValues(source); } diff --git a/src/test/java/ix/OrderByTest.java b/src/test/java/ix/OrderByTest.java index c3c8e67..22d4867 100644 --- a/src/test/java/ix/OrderByTest.java +++ b/src/test/java/ix/OrderByTest.java @@ -20,16 +20,14 @@ import org.junit.Test; -import rx.functions.Func1; - public class OrderByTest { @Test public void normal() { Ix source = Ix.fromArray(5, 4, 3, 2, 1).orderBy(); - + IxTestHelper.assertValues(source, 1, 2, 3, 4, 5); - + IxTestHelper.assertNoRemove(source); } @@ -41,53 +39,53 @@ public int compare(Integer a, Integer b) { return b.compareTo(a); } }); - + IxTestHelper.assertValues(source, 5, 4, 3, 2, 1); - + IxTestHelper.assertNoRemove(source); } @Test public void normalKeySelector() { - Ix source = Ix.fromArray(1, 2, 3, 4, 5).orderBy(new Func1() { + Ix source = Ix.fromArray(1, 2, 3, 4, 5).orderBy(new IxFunction() { @Override - public Integer call(Integer v) { + public Integer apply(Integer v) { return 3 - v; } }); - + IxTestHelper.assertValues(source, 5, 4, 3, 2, 1); - + IxTestHelper.assertNoRemove(source); } @Test public void empty() { Ix source = Ix.empty().orderBy(); - + IxTestHelper.assertValues(source); - + IxTestHelper.assertNoRemove(source); } @Test public void just() { Ix source = Ix.just(1).orderBy(); - + IxTestHelper.assertValues(source, 1); - + IxTestHelper.assertNoRemove(source); } @Test public void normalReverse() { Ix source = Ix.range(1, 5).orderByReverse(); - + IxTestHelper.assertValues(source, 5, 4, 3, 2, 1); - + IxTestHelper.assertNoRemove(source); } - + @Test public void normalComparatorReverse() { Ix source = Ix.fromArray(1, 2, 3, 4, 5).orderByReverse(new Comparator() { @@ -96,23 +94,23 @@ public int compare(Integer a, Integer b) { return b.compareTo(a); } }); - + IxTestHelper.assertValues(source, 1, 2, 3, 4, 5); - + IxTestHelper.assertNoRemove(source); } @Test public void normalKeySelectorReverse() { - Ix source = Ix.fromArray(1, 2, 3, 4, 5).orderByReverse(new Func1() { + Ix source = Ix.fromArray(1, 2, 3, 4, 5).orderByReverse(new IxFunction() { @Override - public Integer call(Integer v) { + public Integer apply(Integer v) { return 3 - v; } }); - + IxTestHelper.assertValues(source, 1, 2, 3, 4, 5); - + IxTestHelper.assertNoRemove(source); } } diff --git a/src/test/java/ix/PublishTest.java b/src/test/java/ix/PublishTest.java index 4431c39..c98252d 100644 --- a/src/test/java/ix/PublishTest.java +++ b/src/test/java/ix/PublishTest.java @@ -20,48 +20,46 @@ import org.junit.*; -import rx.functions.*; - public class PublishTest { @Test public void normal() { final int[] counter = { 0 }; Ix source = Ix.range(1, 5) - .doOnNext(new Action1() { + .doOnNext(new IxConsumer() { @Override - public void call(Integer v) { + public void accept(Integer v) { counter[0]++; } }) .publish(); - + Iterator it1 = source.iterator(); Iterator it2 = source.iterator(); - + Assert.assertEquals(1, it1.next().intValue()); Assert.assertEquals(2, it2.next().intValue()); Assert.assertEquals(3, it1.next().intValue()); Assert.assertEquals(4, it2.next().intValue()); Assert.assertEquals(5, it1.next().intValue()); - + Assert.assertFalse(it1.hasNext()); Assert.assertFalse(it2.hasNext()); - + Iterator it3 = source.iterator(); Assert.assertFalse(it3.hasNext()); - + Assert.assertEquals(5, counter[0]); } - + @Test public void selector() { - Ix source = Ix.range(1, 5).publish(new Func1, Iterable>() { + Ix source = Ix.range(1, 5).publish(new IxFunction, Iterable>() { @Override - public Iterable call(Ix o) { - return Ix.zip(o, o.skip(1), new Func2() { + public Iterable apply(Ix o) { + return Ix.zip(o, o.skip(1), new IxFunction2() { @Override - public Integer call(Integer t1, Integer t2) { + public Integer apply(Integer t1, Integer t2) { return t1 + t2; } }); @@ -69,25 +67,25 @@ public Integer call(Integer t1, Integer t2) { }) ; source.println(); - + IxTestHelper.assertValues(source, 4, 9); } @Test public void selector2() { - Ix source = Ix.range(1, 5).publish(new Func1, Iterable>() { + Ix source = Ix.range(1, 5).publish(new IxFunction, Iterable>() { @Override - public Iterable call(Ix o) { - return Ix.zip(o, o, new Func2() { + public Iterable apply(Ix o) { + return Ix.zip(o, o, new IxFunction2() { @Override - public Integer call(Integer t1, Integer t2) { + public Integer apply(Integer t1, Integer t2) { return t1 + t2; } }); } }) ; - + IxTestHelper.assertValues(source, 3, 7); } diff --git a/src/test/java/ix/RangeTest.java b/src/test/java/ix/RangeTest.java index 5070456..afe4168 100644 --- a/src/test/java/ix/RangeTest.java +++ b/src/test/java/ix/RangeTest.java @@ -25,33 +25,33 @@ public class RangeTest { @Test public void normal() { Ix source = Ix.range(1, 10); - + IxTestHelper.assertValues(source, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10); - + IxTestHelper.assertNoRemove(source); } - + @Test(expected = UnsupportedOperationException.class) public void cantRemove() { Iterator it = Ix.range(1, 10).iterator(); it.next(); it.remove(); } - + @Test public void empty() { Ix source = Ix.range(1, 0); - + Assert.assertSame(Ix.empty(), source); } - + @Test public void just() { Ix source = Ix.range(1, 1); - + Assert.assertTrue(source.getClass().toString(), source instanceof IxScalarCallable); } - + @Test public void negativeRange() { try { diff --git a/src/test/java/ix/ReduceTest.java b/src/test/java/ix/ReduceTest.java index 08241e3..4f6008b 100644 --- a/src/test/java/ix/ReduceTest.java +++ b/src/test/java/ix/ReduceTest.java @@ -16,52 +16,50 @@ package ix; -import org.junit.Test; - -import rx.functions.*; +import static org.junit.Assert.assertEquals; -import static org.junit.Assert.*; +import org.junit.Test; public class ReduceTest { @Test public void normal() { - Ix source = Ix.range(1, 10).reduce(new Func0() { + Ix source = Ix.range(1, 10).reduce(new IxSupplier() { @Override - public Integer call() { + public Integer get() { return 0; } - }, new Func2() { + }, new IxFunction2() { @Override - public Integer call(Integer a, Integer b) { + public Integer apply(Integer a, Integer b) { return a + b; } }); - + assertEquals(55, source.first().intValue()); } - + @Test public void aggregate() { - Ix source = Ix.range(1, 10).reduce(new Func2() { + Ix source = Ix.range(1, 10).reduce(new IxFunction2() { @Override - public Integer call(Integer a, Integer b) { + public Integer apply(Integer a, Integer b) { return a + b; } }); - + assertEquals(55, source.first().intValue()); } - + @Test public void aggregateEmpty() { - Ix source = Ix.empty().reduce(new Func2() { + Ix source = Ix.empty().reduce(new IxFunction2() { @Override - public Integer call(Integer a, Integer b) { + public Integer apply(Integer a, Integer b) { return a + b; } }); - + IxTestHelper.assertValues(source); } } diff --git a/src/test/java/ix/RemoveRetainTest.java b/src/test/java/ix/RemoveRetainTest.java index 16448fb..ad541ca 100644 --- a/src/test/java/ix/RemoveRetainTest.java +++ b/src/test/java/ix/RemoveRetainTest.java @@ -25,14 +25,14 @@ public class RemoveRetainTest { @Test public void removeNormal() { List list = IxTestHelper.range(1, 10); - - Ix source = Ix.from(list).remove(new Pred() { + + Ix source = Ix.from(list).remove(new IxPredicate() { @Override public boolean test(Integer v) { return (v & 1) != 0; } }); - + IxTestHelper.assertValues(source, 2, 4, 6, 8, 10); IxTestHelper.assertValues(list, 2, 4, 6, 8, 10); } @@ -40,29 +40,29 @@ public boolean test(Integer v) { @Test public void removeAll() { List list = IxTestHelper.range(1, 10); - - Ix source = Ix.from(list).remove(new Pred() { + + Ix source = Ix.from(list).remove(new IxPredicate() { @Override public boolean test(Integer v) { return true; } }); - + IxTestHelper.assertValues(source); IxTestHelper.assertValues(list); } - + @Test public void removeNone() { List list = IxTestHelper.range(1, 10); - - Ix source = Ix.from(list).remove(new Pred() { + + Ix source = Ix.from(list).remove(new IxPredicate() { @Override public boolean test(Integer v) { return false; } }); - + IxTestHelper.assertValues(source, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10); IxTestHelper.assertValues(list, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10); } @@ -70,14 +70,14 @@ public boolean test(Integer v) { @Test public void removeEmpty() { List list = IxTestHelper.range(1, 0); - - Ix source = Ix.from(list).remove(new Pred() { + + Ix source = Ix.from(list).remove(new IxPredicate() { @Override public boolean test(Integer v) { return true; } }); - + IxTestHelper.assertValues(source); IxTestHelper.assertValues(list); } @@ -85,14 +85,14 @@ public boolean test(Integer v) { @Test public void retainNormal() { List list = IxTestHelper.range(1, 10); - - Ix source = Ix.from(list).retain(new Pred() { + + Ix source = Ix.from(list).retain(new IxPredicate() { @Override public boolean test(Integer v) { return (v & 1) != 0; } }); - + IxTestHelper.assertValues(source, 1, 3, 5, 7, 9); IxTestHelper.assertValues(list, 1, 3, 5, 7, 9); } @@ -100,29 +100,29 @@ public boolean test(Integer v) { @Test public void retainAll() { List list = IxTestHelper.range(1, 10); - - Ix source = Ix.from(list).retain(new Pred() { + + Ix source = Ix.from(list).retain(new IxPredicate() { @Override public boolean test(Integer v) { return true; } }); - + IxTestHelper.assertValues(source, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10); IxTestHelper.assertValues(list, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10); } - + @Test public void retainNone() { List list = IxTestHelper.range(1, 10); - - Ix source = Ix.from(list).retain(new Pred() { + + Ix source = Ix.from(list).retain(new IxPredicate() { @Override public boolean test(Integer v) { return false; } }); - + IxTestHelper.assertValues(source); IxTestHelper.assertValues(list); } @@ -130,54 +130,54 @@ public boolean test(Integer v) { @Test public void retainEmpty() { List list = IxTestHelper.range(1, 0); - - Ix source = Ix.from(list).retain(new Pred() { + + Ix source = Ix.from(list).retain(new IxPredicate() { @Override public boolean test(Integer v) { return false; } }); - + IxTestHelper.assertValues(source); IxTestHelper.assertValues(list); } - + @Test public void removeAllDouble() { List list = IxTestHelper.range(1, 10); - - Ix source = Ix.from(list).remove(new Pred() { + + Ix source = Ix.from(list).remove(new IxPredicate() { @Override public boolean test(Integer v) { return (v & 1) != 0; } - }).remove(new Pred() { + }).remove(new IxPredicate() { @Override public boolean test(Integer v) { return (v & 1) == 0; } }); - + IxTestHelper.assertValues(source); IxTestHelper.assertValues(list); } - + @Test public void retainNoneDouble() { List list = IxTestHelper.range(1, 10); - - Ix source = Ix.from(list).retain(new Pred() { + + Ix source = Ix.from(list).retain(new IxPredicate() { @Override public boolean test(Integer v) { return (v & 1) != 0; } - }).retain(new Pred() { + }).retain(new IxPredicate() { @Override public boolean test(Integer v) { return (v & 1) == 0; } }); - + IxTestHelper.assertValues(source); IxTestHelper.assertValues(list); } diff --git a/src/test/java/ix/RepeatTest.java b/src/test/java/ix/RepeatTest.java index aa61b48..0f9da8a 100644 --- a/src/test/java/ix/RepeatTest.java +++ b/src/test/java/ix/RepeatTest.java @@ -23,86 +23,86 @@ public class RepeatTest { @Test public void normal() { Ix source = Ix.repeatValue(1).take(5); - + IxTestHelper.assertValues(source, 1, 1, 1, 1, 1); - + IxTestHelper.assertNoRemove(source); } @Test public void normalLimited() { Ix source = Ix.repeatValue(1, 5); - + IxTestHelper.assertValues(source, 1, 1, 1, 1, 1); - + IxTestHelper.assertNoRemove(source); } - + @Test public void neverRepeat() { Ix source = Ix.repeatValue(1, 0); - + IxTestHelper.assertValues(source); - + IxTestHelper.assertNoRemove(source); } @Test public void repeatOnce() { Ix source = Ix.repeatValue(1, 1); - + IxTestHelper.assertValues(source, 1); - + IxTestHelper.assertNoRemove(source); } @Test public void predicateLimited() { - Ix source = Ix.repeatValue(1, new Pred0() { + Ix source = Ix.repeatValue(1, new IxBooleanSupplier() { int count = 5; @Override public boolean getAsBoolean() { return count-- == 0; } }); - + IxTestHelper.assertValues(source, 1, 1, 1, 1, 1); - + IxTestHelper.assertNoRemove(source); } - + @Test public void predicateNeverRepeat() { - Ix source = Ix.repeatValue(1, new Pred0() { + Ix source = Ix.repeatValue(1, new IxBooleanSupplier() { @Override public boolean getAsBoolean() { return true; } }); - + IxTestHelper.assertValues(source); - + IxTestHelper.assertNoRemove(source); } @Test public void predicateRepeatOnce() { - Ix source = Ix.repeatValue(1, new Pred0() { + Ix source = Ix.repeatValue(1, new IxBooleanSupplier() { int count = 1; @Override public boolean getAsBoolean() { return count-- == 0; } }); - + IxTestHelper.assertValues(source, 1); - + IxTestHelper.assertNoRemove(source); } @Test public void predicateInfinite() { - Ix source = Ix.repeatValue(1, new Pred0() { + Ix source = Ix.repeatValue(1, new IxBooleanSupplier() { @Override public boolean getAsBoolean() { return false; @@ -110,108 +110,108 @@ public boolean getAsBoolean() { }).take(5); IxTestHelper.assertValues(source, 1, 1, 1, 1, 1); - + IxTestHelper.assertNoRemove(source); } - + @Test public void predicateCountedLimited() { - Ix source = Ix.repeatValue(1, 3L, new Pred0() { + Ix source = Ix.repeatValue(1, 3L, new IxBooleanSupplier() { int count = 5; @Override public boolean getAsBoolean() { return count-- == 0; } }); - + IxTestHelper.assertValues(source, 1, 1, 1); - + IxTestHelper.assertNoRemove(source); } - + @Test public void normalInstance() { Ix source = Ix.just(1).repeat().take(5); - + IxTestHelper.assertValues(source, 1, 1, 1, 1, 1); - + IxTestHelper.assertNoRemove(source); } @Test public void normalInstanceLimited() { Ix source = Ix.just(1).repeat(5); - + IxTestHelper.assertValues(source, 1, 1, 1, 1, 1); - + IxTestHelper.assertNoRemove(source); } - + @Test public void neverRepeatInstance() { Ix source = Ix.just(1).repeat(0); - + IxTestHelper.assertValues(source); - + IxTestHelper.assertNoRemove(source); } @Test public void repeatOnceInstance() { Ix source = Ix.just(1).repeat(1); - + IxTestHelper.assertValues(source, 1); - + IxTestHelper.assertNoRemove(source); } @Test public void predicateLimitedInstance() { - Ix source = Ix.just(1).repeat(new Pred0() { + Ix source = Ix.just(1).repeat(new IxBooleanSupplier() { int count = 5; @Override public boolean getAsBoolean() { return count-- == 0; } }); - + IxTestHelper.assertValues(source, 1, 1, 1, 1, 1); - + IxTestHelper.assertNoRemove(source); } - + @Test public void predicateNeverRepeatInstance() { - Ix source = Ix.just(1).repeat(new Pred0() { + Ix source = Ix.just(1).repeat(new IxBooleanSupplier() { @Override public boolean getAsBoolean() { return true; } }); - + IxTestHelper.assertValues(source); - + IxTestHelper.assertNoRemove(source); } @Test public void predicateRepeatOnceInstance() { - Ix source = Ix.just(1).repeat(new Pred0() { + Ix source = Ix.just(1).repeat(new IxBooleanSupplier() { int count = 1; @Override public boolean getAsBoolean() { return count-- == 0; } }); - + IxTestHelper.assertValues(source, 1); - + IxTestHelper.assertNoRemove(source); } @Test public void predicateInfiniteInstance() { - Ix source = Ix.just(1).repeat(new Pred0() { + Ix source = Ix.just(1).repeat(new IxBooleanSupplier() { @Override public boolean getAsBoolean() { return false; @@ -219,22 +219,22 @@ public boolean getAsBoolean() { }).take(5); IxTestHelper.assertValues(source, 1, 1, 1, 1, 1); - + IxTestHelper.assertNoRemove(source); } - + @Test public void predicateCountedLimitedInstance() { - Ix source = Ix.just(1).repeat(3L, new Pred0() { + Ix source = Ix.just(1).repeat(3L, new IxBooleanSupplier() { int count = 5; @Override public boolean getAsBoolean() { return count-- == 0; } }); - + IxTestHelper.assertValues(source, 1, 1, 1); - + IxTestHelper.assertNoRemove(source); } } diff --git a/src/test/java/ix/ReplayTest.java b/src/test/java/ix/ReplayTest.java index db0ac97..6221375 100644 --- a/src/test/java/ix/ReplayTest.java +++ b/src/test/java/ix/ReplayTest.java @@ -20,17 +20,15 @@ import org.junit.*; -import rx.functions.*; - public class ReplayTest { @Test public void normal() { final int[] counter = { 0 }; Ix source = Ix.range(1, 5) - .doOnNext(new Action1() { + .doOnNext(new IxConsumer() { @Override - public void call(Integer v) { + public void accept(Integer v) { counter[0]++; } }) @@ -39,17 +37,17 @@ public void call(Integer v) { IxTestHelper.assertValues(source, 1, 2, 3, 4, 5); IxTestHelper.assertValues(source, 1, 2, 3, 4, 5); IxTestHelper.assertValues(source, 1, 2, 3, 4, 5); - + Assert.assertEquals(5, counter[0]); } - + @Test public void lockstep() { final int[] counter = { 0 }; Ix source = Ix.range(1, 5) - .doOnNext(new Action1() { + .doOnNext(new IxConsumer() { @Override - public void call(Integer v) { + public void accept(Integer v) { counter[0]++; } }) @@ -57,7 +55,7 @@ public void call(Integer v) { Iterator it1 = source.iterator(); Iterator it2 = source.iterator(); - + Assert.assertEquals(1, it1.next().intValue()); Assert.assertEquals(1, it2.next().intValue()); @@ -77,25 +75,25 @@ public void call(Integer v) { Assert.assertFalse(it1.hasNext()); Assert.assertEquals(5, counter[0]); - + } - + @Test public void empty() { Ix source = Ix.empty().replay(); - + IxTestHelper.assertValues(source); IxTestHelper.assertValues(source); IxTestHelper.assertValues(source); } - + @Test public void replaySizeNormal() { final int[] counter = { 0 }; Ix source = Ix.range(1, 5) - .doOnNext(new Action1() { + .doOnNext(new IxConsumer() { @Override - public void call(Integer v) { + public void accept(Integer v) { counter[0]++; } }) @@ -104,7 +102,7 @@ public void call(Integer v) { IxTestHelper.assertValues(source, 1, 2, 3, 4, 5); IxTestHelper.assertValues(source, 1, 2, 3, 4, 5); IxTestHelper.assertValues(source, 1, 2, 3, 4, 5); - + Assert.assertEquals(5, counter[0]); } @@ -112,9 +110,9 @@ public void call(Integer v) { public void replaySizeLimit() { final int[] counter = { 0 }; Ix source = Ix.range(1, 5) - .doOnNext(new Action1() { + .doOnNext(new IxConsumer() { @Override - public void call(Integer v) { + public void accept(Integer v) { counter[0]++; } }) @@ -123,78 +121,78 @@ public void call(Integer v) { IxTestHelper.assertValues(source, 1, 2, 3, 4, 5); IxTestHelper.assertValues(source, 4, 5); IxTestHelper.assertValues(source, 4, 5); - + Assert.assertEquals(5, counter[0]); } @Test public void replaySelectorNormal() { - - Ix source = Ix.range(1, 5).replay(new Func1, Iterable>() { + + Ix source = Ix.range(1, 5).replay(new IxFunction, Iterable>() { @Override - public Iterable call(Ix o) { - return Ix.zip(o, o.skip(1), new Func2() { + public Iterable apply(Ix o) { + return Ix.zip(o, o.skip(1), new IxFunction2() { @Override - public Integer call(Integer t1, Integer t2) { + public Integer apply(Integer t1, Integer t2) { return t1 + t2; } }); } }); - + IxTestHelper.assertValues(source, 3, 5, 7, 9); IxTestHelper.assertValues(source, 3, 5, 7, 9); } - + @Test public void replaySizeSelectorLarge() { - - Ix source = Ix.range(1, 5).replay(10, new Func1, Iterable>() { + + Ix source = Ix.range(1, 5).replay(10, new IxFunction, Iterable>() { @Override - public Iterable call(Ix o) { - return Ix.zip(o, o.skip(1), new Func2() { + public Iterable apply(Ix o) { + return Ix.zip(o, o.skip(1), new IxFunction2() { @Override - public Integer call(Integer t1, Integer t2) { + public Integer apply(Integer t1, Integer t2) { return t1 + t2; } }); } }); - + IxTestHelper.assertValues(source, 3, 5, 7, 9); IxTestHelper.assertValues(source, 3, 5, 7, 9); } - + @Test public void replaySizeSelectorSmall() { - - Ix source = Ix.range(1, 5).replay(2, new Func1, Iterable>() { + + Ix source = Ix.range(1, 5).replay(2, new IxFunction, Iterable>() { @Override - public Iterable call(Ix o) { - return Ix.zip(o, o.skip(1), new Func2() { + public Iterable apply(Ix o) { + return Ix.zip(o, o.skip(1), new IxFunction2() { @Override - public Integer call(Integer t1, Integer t2) { + public Integer apply(Integer t1, Integer t2) { return t1 + t2; } }); } }); - + IxTestHelper.assertValues(source, 3, 5, 7, 9); IxTestHelper.assertValues(source, 3, 5, 7, 9); } - + @Test public void replaySizeSelectorInnerEffect() { - - Ix source = Ix.range(1, 5).replay(2, new Func1, Iterable>() { + + Ix source = Ix.range(1, 5).replay(2, new IxFunction, Iterable>() { @SuppressWarnings("unchecked") @Override - public Iterable call(Ix o) { + public Iterable apply(Ix o) { return Ix.concatArray(o, o); } }); - + IxTestHelper.assertValues(source, 1, 2, 3, 4, 5, 4, 5); IxTestHelper.assertValues(source, 1, 2, 3, 4, 5, 4, 5); } diff --git a/src/test/java/ix/ReverseTest.java b/src/test/java/ix/ReverseTest.java index 7e0c1c0..961d36d 100644 --- a/src/test/java/ix/ReverseTest.java +++ b/src/test/java/ix/ReverseTest.java @@ -23,18 +23,18 @@ public class ReverseTest { @Test public void normal() { Ix source = Ix.range(1, 5).reverse(); - + IxTestHelper.assertValues(source, 5, 4, 3, 2, 1); - + IxTestHelper.assertNoRemove(source); } @Test public void empty() { Ix source = Ix.empty().reverse(); - + IxTestHelper.assertValues(source); - + IxTestHelper.assertNoRemove(source); } diff --git a/src/test/java/ix/ScanTest.java b/src/test/java/ix/ScanTest.java index 3b5e3a6..14d1fc9 100644 --- a/src/test/java/ix/ScanTest.java +++ b/src/test/java/ix/ScanTest.java @@ -18,106 +18,104 @@ import org.junit.Test; -import rx.functions.*; - public class ScanTest { @Test public void normal() { - Ix source = Ix.range(1, 5).scan(new Func2() { + Ix source = Ix.range(1, 5).scan(new IxFunction2() { @Override - public Integer call(Integer t1, Integer t2) { + public Integer apply(Integer t1, Integer t2) { return t1 + t2; } }); - + IxTestHelper.assertValues(source, 1, 3, 6, 10, 15); - + IxTestHelper.assertNoRemove(source); } - + @Test public void just() { - Ix source = Ix.just(1).scan(new Func2() { + Ix source = Ix.just(1).scan(new IxFunction2() { @Override - public Integer call(Integer t1, Integer t2) { + public Integer apply(Integer t1, Integer t2) { return t1 + t2; } }); - + IxTestHelper.assertValues(source, 1); - + IxTestHelper.assertNoRemove(source); } - + @Test public void empty() { - Ix source = Ix.empty().scan(new Func2() { + Ix source = Ix.empty().scan(new IxFunction2() { @Override - public Integer call(Integer t1, Integer t2) { + public Integer apply(Integer t1, Integer t2) { return t1 + t2; } }); - + IxTestHelper.assertValues(source); - + IxTestHelper.assertNoRemove(source); } - + @Test public void normalSeed() { - Ix source = Ix.range(1, 5).scan(new Func0() { + Ix source = Ix.range(1, 5).scan(new IxSupplier() { @Override - public Integer call() { + public Integer get() { return 100; } - },new Func2() { + },new IxFunction2() { @Override - public Integer call(Integer t1, Integer t2) { + public Integer apply(Integer t1, Integer t2) { return t1 + t2; } }); - + IxTestHelper.assertValues(source, 100, 101, 103, 106, 110, 115); - + IxTestHelper.assertNoRemove(source); } - + @Test public void justSeed() { - Ix source = Ix.just(1).scan(new Func0() { + Ix source = Ix.just(1).scan(new IxSupplier() { @Override - public Integer call() { + public Integer get() { return 100; } - }, new Func2() { + }, new IxFunction2() { @Override - public Integer call(Integer t1, Integer t2) { + public Integer apply(Integer t1, Integer t2) { return t1 + t2; } }); - + IxTestHelper.assertValues(source, 100, 101); - + IxTestHelper.assertNoRemove(source); } - + @Test public void emptySeed() { - Ix source = Ix.empty().scan(new Func0() { + Ix source = Ix.empty().scan(new IxSupplier() { @Override - public Integer call() { + public Integer get() { return 100; } - }, new Func2() { + }, new IxFunction2() { @Override - public Integer call(Integer t1, Integer t2) { + public Integer apply(Integer t1, Integer t2) { return t1 + t2; } }); - + IxTestHelper.assertValues(source, 100); - + IxTestHelper.assertNoRemove(source); } } diff --git a/src/test/java/ix/SelfComparatorTest.java b/src/test/java/ix/SelfComparatorTest.java index b23c801..bbf9112 100644 --- a/src/test/java/ix/SelfComparatorTest.java +++ b/src/test/java/ix/SelfComparatorTest.java @@ -16,10 +16,10 @@ package ix; -import org.junit.Test; - -import static org.junit.Assert.*; import static ix.SelfComparator.INSTANCE; +import static org.junit.Assert.*; + +import org.junit.Test; public class SelfComparatorTest { @@ -29,11 +29,11 @@ public void normal() { assertEquals(0, INSTANCE.compare(1, new Integer(1))); assertTrue(INSTANCE.compare(1, 2) < 0); - + assertTrue(INSTANCE.compare(2, 1) > 0); assertNotNull(SelfComparator.valueOf("INSTANCE")); - + assertEquals(1, SelfComparator.values().length); } } diff --git a/src/test/java/ix/SequenceEqualTest.java b/src/test/java/ix/SequenceEqualTest.java index 37ee340..efb94df 100644 --- a/src/test/java/ix/SequenceEqualTest.java +++ b/src/test/java/ix/SequenceEqualTest.java @@ -23,48 +23,48 @@ public class SequenceEqualTest { @Test public void normal() { Ix source = Ix.range(1, 5).sequenceEqual(Ix.range(1, 5)); - + IxTestHelper.assertValues(source, true); } @Test public void firstSorter() { Ix source = Ix.range(1, 4).sequenceEqual(Ix.range(1, 5)); - + IxTestHelper.assertValues(source, false); } @Test public void secondSorter() { Ix source = Ix.range(1, 5).sequenceEqual(Ix.range(1, 4)); - + IxTestHelper.assertValues(source, false); } @Test public void firstEmpty() { Ix source = Ix.empty().sequenceEqual(Ix.range(1, 5)); - + IxTestHelper.assertValues(source, false); } @Test public void secondEmpty() { Ix source = Ix.range(1, 5).sequenceEqual(Ix.empty()); - + IxTestHelper.assertValues(source, false); } @Test public void empty() { Ix source = Ix.empty().sequenceEqual(Ix.empty()); - + IxTestHelper.assertValues(source, true); } - + @Test public void different() { Ix source = Ix.fromArray(1, 2, 3, 3, 5).sequenceEqual(Ix.range(1, 5)); - + IxTestHelper.assertValues(source, false); } } diff --git a/src/test/java/ix/SkipLastTest.java b/src/test/java/ix/SkipLastTest.java index d7e5685..732a455 100644 --- a/src/test/java/ix/SkipLastTest.java +++ b/src/test/java/ix/SkipLastTest.java @@ -23,42 +23,42 @@ public class SkipLastTest { @Test public void normal() { Ix source = Ix.range(1, 10).skipLast(5); - + IxTestHelper.assertValues(source, 1, 2, 3, 4, 5); } @Test public void normalTwo() { Ix source = Ix.range(1, 2).skipLast(1); - + IxTestHelper.assertValues(source, 1); } @Test public void normalThree() { Ix source = Ix.range(1, 16).skipLast(1); - + IxTestHelper.assertValues(source, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); } @Test public void zero() { Ix source = Ix.range(1, 10).skipLast(0); - + IxTestHelper.assertValues(source, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10); } @Test public void all() { Ix source = Ix.range(1, 10).skipLast(10); - + IxTestHelper.assertValues(source); } @Test public void more() { Ix source = Ix.range(1, 10).skipLast(15); - + IxTestHelper.assertValues(source); } @@ -66,21 +66,21 @@ public void more() { @Test public void just() { Ix source = Ix.just(1).skipLast(1); - + IxTestHelper.assertValues(source); } @Test public void empty() { Ix source = Ix.empty().skipLast(1); - + IxTestHelper.assertValues(source); } @Test public void emptyZero() { Ix source = Ix.empty().skipLast(0); - + IxTestHelper.assertValues(source); } diff --git a/src/test/java/ix/SkipTest.java b/src/test/java/ix/SkipTest.java index 137aace..f4a32f1 100644 --- a/src/test/java/ix/SkipTest.java +++ b/src/test/java/ix/SkipTest.java @@ -23,35 +23,35 @@ public class SkipTest { @Test public void normal() { Ix source = Ix.range(1, 10).skip(5); - + IxTestHelper.assertValues(source, 6, 7, 8, 9, 10); } @Test public void zero() { Ix source = Ix.range(1, 10).skip(0); - + IxTestHelper.assertValues(source, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10); } @Test public void all() { Ix source = Ix.range(1, 10).skip(10); - + IxTestHelper.assertValues(source); } @Test public void empty() { Ix source = Ix.empty().skip(10); - + IxTestHelper.assertValues(source); } @Test public void emptyZero() { Ix source = Ix.empty().skip(0); - + IxTestHelper.assertValues(source); } diff --git a/src/test/java/ix/SkipWhileTest.java b/src/test/java/ix/SkipWhileTest.java index 9dcefcf..51a616e 100644 --- a/src/test/java/ix/SkipWhileTest.java +++ b/src/test/java/ix/SkipWhileTest.java @@ -24,52 +24,52 @@ public class SkipWhileTest { @Test public void normal() { - Ix source = Ix.range(1, 10).skipWhile(new Pred() { + Ix source = Ix.range(1, 10).skipWhile(new IxPredicate() { @Override public boolean test(Integer v) { return v < 6; } }); - + IxTestHelper.assertValues(source, 6, 7, 8, 9, 10); - + IxTestHelper.assertNoRemove(source); } @Test public void skipAll() { - Ix source = Ix.range(1, 10).skipWhile(new Pred() { + Ix source = Ix.range(1, 10).skipWhile(new IxPredicate() { @Override public boolean test(Integer v) { return true; } }); - + IxTestHelper.assertValues(source); } @Test public void skipNone() { - Ix source = Ix.range(1, 10).skipWhile(new Pred() { + Ix source = Ix.range(1, 10).skipWhile(new IxPredicate() { @Override public boolean test(Integer v) { return false; } }); - + IxTestHelper.assertValues(source, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10); } @Test public void removeUnskipped() { List list = IxTestHelper.range(1, 10); - Ix.from(list).skipWhile(new Pred() { + Ix.from(list).skipWhile(new IxPredicate() { @Override public boolean test(Integer v) { return v < 6; } }).removeAll(); - + Assert.assertEquals(Arrays.asList(1, 2, 3, 4, 5), list); } diff --git a/src/test/java/ix/SourceQueuedIteratorTest.java b/src/test/java/ix/SourceQueuedIteratorTest.java index a1ab17f..551a9cc 100644 --- a/src/test/java/ix/SourceQueuedIteratorTest.java +++ b/src/test/java/ix/SourceQueuedIteratorTest.java @@ -18,12 +18,10 @@ import org.junit.*; -import rx.functions.Action2; - public class SourceQueuedIteratorTest { IxSourceQueuedIterator it; - + @Before public void before() { it = new IxSourceQueuedIterator(Ix.empty().iterator()) { @@ -34,64 +32,64 @@ protected boolean moveNext() { } }; } - + @Test public void normal() { Assert.assertTrue(it.isEmpty()); Assert.assertEquals(null, it.peek()); it.offer(1); - + Assert.assertFalse(it.isEmpty()); - + Assert.assertEquals(1, it.peek()); Assert.assertEquals(1, it.poll()); Assert.assertTrue(it.isEmpty()); Assert.assertEquals(null, it.peek()); - + Assert.assertNull(it.poll()); Assert.assertTrue(it.isEmpty()); } - + @Test(expected = NullPointerException.class) public void nullOffer() { it.offer(null); } - + @Test public void clear() { Assert.assertTrue(it.isEmpty()); it.offer(1); - + Assert.assertFalse(it.isEmpty()); - + it.clear(); - + Assert.assertNull(it.poll()); Assert.assertTrue(it.isEmpty()); } - + @Test public void nullWraps() { Assert.assertSame(IxSourceQueuedIterator.NULL, it.toObject(null)); } - + @Test public void nullUnwraps() { Assert.assertNull(it.fromObject(IxSourceQueuedIterator.NULL)); } - + @Test public void foreach() { final int[] count = { 0 }; - it.foreach(new Action2() { + it.foreach(new IxConsumer2() { @Override - public void call(Integer a, Object b) { + public void accept(Integer a, Object b) { count[0]++; } }, null); - + Assert.assertEquals(0, count[0]); } } diff --git a/src/test/java/ix/SplitTest.java b/src/test/java/ix/SplitTest.java index da1c4c5..2e75bb7 100644 --- a/src/test/java/ix/SplitTest.java +++ b/src/test/java/ix/SplitTest.java @@ -23,45 +23,45 @@ public class SplitTest { @Test public void normal() { Ix source = Ix.split("a|b|c|d", "|"); - + IxTestHelper.assertValues(source, "a", "b", "c", "d"); - + IxTestHelper.assertNoRemove(source); } - + @Test public void normal2() { Ix source = Ix.split("a|b|c|", "|"); - + IxTestHelper.assertValues(source, "a", "b", "c", ""); - + IxTestHelper.assertNoRemove(source); } - + @Test public void normal3() { Ix source = Ix.split("a1|b2|c3", "|"); - + IxTestHelper.assertValues(source, "a1", "b2", "c3"); - + IxTestHelper.assertNoRemove(source); } - + @Test public void normal4() { Ix source = Ix.split("a1| source = Ix.split("", "|"); - + IxTestHelper.assertValues(source, ""); - + IxTestHelper.assertNoRemove(source); } } diff --git a/src/test/java/ix/SumTest.java b/src/test/java/ix/SumTest.java index 3221aa4..b758f3d 100644 --- a/src/test/java/ix/SumTest.java +++ b/src/test/java/ix/SumTest.java @@ -25,42 +25,42 @@ public class SumTest { @Test public void normal() { Ix source = Ix.range(1, 10).sumInt(); - + assertEquals(55, source.first().intValue()); } @Test public void just() { Ix source = Ix.just(1).sumInt(); - + assertEquals(1, source.first().intValue()); } @Test public void empty() { Ix source = Ix.empty().sumInt(); - + IxTestHelper.assertValues(source); } @Test public void normalLong() { Ix source = Ix.range(1, 10).toLong().sumLong(); - + assertEquals(55L, source.first().longValue()); } @Test public void justLong() { Ix source = Ix.just(1L).sumLong(); - + assertEquals(1, source.first().intValue()); } @Test public void emptyLong() { Ix source = Ix.empty().sumLong(); - + IxTestHelper.assertValues(source); } diff --git a/src/test/java/ix/SwitchIfEmptyTest.java b/src/test/java/ix/SwitchIfEmptyTest.java index 72cedac..9d30a3c 100644 --- a/src/test/java/ix/SwitchIfEmptyTest.java +++ b/src/test/java/ix/SwitchIfEmptyTest.java @@ -25,55 +25,55 @@ public class SwitchIfEmptyTest { @Test public void normal() { Ix source = Ix.range(1, 10).switchIfEmpty(Ix.range(11, 10)); - + IxTestHelper.assertValues(source, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10); } @Test public void empty() { Ix source = Ix.empty().switchIfEmpty(Ix.range(11, 10)); - + IxTestHelper.assertValues(source, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20); } @Test public void emptyOther() { Ix source = Ix.empty().switchIfEmpty(Ix.empty()); - + IxTestHelper.assertValues(source); } @Test public void defaultNormal() { Ix source = Ix.range(1, 10).defaultIfEmpty(100); - + IxTestHelper.assertValues(source, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10); } @Test public void defaultEmpty() { Ix source = Ix.empty().defaultIfEmpty(100); - + IxTestHelper.assertValues(source, 100); } - + @Test public void removeNonEmpty() { List list = IxTestHelper.range(1, 10); List list2 = IxTestHelper.range(11, 10); - + Ix.from(list).switchIfEmpty(Ix.from(list2)).removeAll(); - + IxTestHelper.assertValues(list); IxTestHelper.assertValues(list2, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20); } - + @Test public void removeEmpty() { List list2 = IxTestHelper.range(11, 10); - + Ix.empty().switchIfEmpty(Ix.from(list2)).removeAll(); - + IxTestHelper.assertValues(list2); } } diff --git a/src/test/java/ix/TakeLastTest.java b/src/test/java/ix/TakeLastTest.java index 2bd7988..8f4a8ee 100644 --- a/src/test/java/ix/TakeLastTest.java +++ b/src/test/java/ix/TakeLastTest.java @@ -23,42 +23,42 @@ public class TakeLastTest { @Test public void normal() { Ix source = Ix.range(1, 10).takeLast(5); - + IxTestHelper.assertValues(source, 6, 7, 8, 9, 10); } @Test public void normalTwo() { Ix source = Ix.range(1, 2).takeLast(1); - + IxTestHelper.assertValues(source, 2); } @Test public void normalThree() { Ix source = Ix.range(1, 16).takeLast(15); - + IxTestHelper.assertValues(source, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16); } @Test public void zero() { Ix source = Ix.range(1, 10).takeLast(0); - + IxTestHelper.assertValues(source); } @Test public void all() { Ix source = Ix.range(1, 10).takeLast(10); - + IxTestHelper.assertValues(source, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10); } @Test public void more() { Ix source = Ix.range(1, 10).takeLast(15); - + IxTestHelper.assertValues(source, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10); } @@ -66,21 +66,21 @@ public void more() { @Test public void just() { Ix source = Ix.just(1).takeLast(1); - + IxTestHelper.assertValues(source, 1); } @Test public void empty() { Ix source = Ix.empty().takeLast(1); - + IxTestHelper.assertValues(source); } @Test public void emptyZero() { Ix source = Ix.empty().takeLast(0); - + IxTestHelper.assertValues(source); } diff --git a/src/test/java/ix/TakeTest.java b/src/test/java/ix/TakeTest.java index 73cd0b2..ad186bb 100644 --- a/src/test/java/ix/TakeTest.java +++ b/src/test/java/ix/TakeTest.java @@ -25,51 +25,51 @@ public class TakeTest { @Test public void normal() { Ix source = Ix.range(1, 10).take(5); - + IxTestHelper.assertValues(source, 1, 2, 3, 4, 5); } @Test public void all() { Ix source = Ix.range(1, 10).take(10); - + IxTestHelper.assertValues(source, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10); } @Test public void more() { Ix source = Ix.range(1, 10).take(15); - + IxTestHelper.assertValues(source, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10); } @Test public void none() { Ix source = Ix.range(1, 10).take(0); - + IxTestHelper.assertValues(source); } @Test public void just() { Ix source = Ix.just(1).take(5); - + IxTestHelper.assertValues(source, 1); } @Test public void empty() { Ix source = Ix.empty().take(5); - + IxTestHelper.assertValues(source); } - + @Test public void removeComposes() { List list = Ix.range(1, 10).collectToList().first(); - + Ix.from(list).take(5).removeAll(); - + Assert.assertEquals(Arrays.asList(6, 7, 8, 9, 10), list); } diff --git a/src/test/java/ix/TakeUntilTest.java b/src/test/java/ix/TakeUntilTest.java index 1da5893..1217717 100644 --- a/src/test/java/ix/TakeUntilTest.java +++ b/src/test/java/ix/TakeUntilTest.java @@ -24,52 +24,52 @@ public class TakeUntilTest { @Test public void normal() { - Ix source = Ix.range(1, 10).takeUntil(new Pred() { + Ix source = Ix.range(1, 10).takeUntil(new IxPredicate() { @Override public boolean test(Integer v) { return v == 5; } }); - + IxTestHelper.assertValues(source, 1, 2, 3, 4, 5); - + IxTestHelper.assertNoRemove(source); } @Test public void takeOne() { - Ix source = Ix.range(1, 10).takeUntil(new Pred() { + Ix source = Ix.range(1, 10).takeUntil(new IxPredicate() { @Override public boolean test(Integer v) { return true; } }); - + IxTestHelper.assertValues(source, 1); } @Test public void takeAll() { - Ix source = Ix.range(1, 10).takeUntil(new Pred() { + Ix source = Ix.range(1, 10).takeUntil(new IxPredicate() { @Override public boolean test(Integer v) { return false; } }); - + IxTestHelper.assertValues(source, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10); } @Test public void removeUnskipped() { List list = IxTestHelper.range(1, 10); - Ix.from(list).takeUntil(new Pred() { + Ix.from(list).takeUntil(new IxPredicate() { @Override public boolean test(Integer v) { return v == 5; } }).removeAll(); - + Assert.assertEquals(Arrays.asList(6, 7, 8, 9, 10), list); } diff --git a/src/test/java/ix/TakeWhileTest.java b/src/test/java/ix/TakeWhileTest.java index 3fb70c8..662eb13 100644 --- a/src/test/java/ix/TakeWhileTest.java +++ b/src/test/java/ix/TakeWhileTest.java @@ -24,52 +24,52 @@ public class TakeWhileTest { @Test public void normal() { - Ix source = Ix.range(1, 10).takeWhile(new Pred() { + Ix source = Ix.range(1, 10).takeWhile(new IxPredicate() { @Override public boolean test(Integer v) { return v < 6; } }); - + IxTestHelper.assertValues(source, 1, 2, 3, 4, 5); - + IxTestHelper.assertNoRemove(source); } @Test public void takeAll() { - Ix source = Ix.range(1, 10).takeWhile(new Pred() { + Ix source = Ix.range(1, 10).takeWhile(new IxPredicate() { @Override public boolean test(Integer v) { return true; } }); - + IxTestHelper.assertValues(source, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10); } @Test public void takeNone() { - Ix source = Ix.range(1, 10).takeWhile(new Pred() { + Ix source = Ix.range(1, 10).takeWhile(new IxPredicate() { @Override public boolean test(Integer v) { return false; } }); - + IxTestHelper.assertValues(source); } @Test public void removeUnskipped() { List list = IxTestHelper.range(1, 10); - Ix.from(list).takeWhile(new Pred() { + Ix.from(list).takeWhile(new IxPredicate() { @Override public boolean test(Integer v) { return v < 6; } }).removeAll(); - + Assert.assertEquals(Arrays.asList(6, 7, 8, 9, 10), list); } diff --git a/src/test/java/ix/ToArrayTest.java b/src/test/java/ix/ToArrayTest.java index 7737f20..ac84213 100644 --- a/src/test/java/ix/ToArrayTest.java +++ b/src/test/java/ix/ToArrayTest.java @@ -23,7 +23,7 @@ public class ToArrayTest { @Test public void normal() { Ix source = Ix.range(1, 10).collectToArray(); - + IxTestHelper.assertValues(source, new Object[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }); } } diff --git a/src/test/java/ix/ToListTest.java b/src/test/java/ix/ToListTest.java index 30366a9..be0c346 100644 --- a/src/test/java/ix/ToListTest.java +++ b/src/test/java/ix/ToListTest.java @@ -16,17 +16,18 @@ package ix; +import static org.junit.Assert.assertEquals; + import org.junit.Test; -import static org.junit.Assert.*; public class ToListTest { @Test public void normal() { Ix source = Ix.just(1); - + assertEquals(1, source.iterator().next().intValue()); - + IxTestHelper.assertValues(source, 1); } } diff --git a/src/test/java/ix/ToMapTest.java b/src/test/java/ix/ToMapTest.java index 8c68fbc..6c64850 100644 --- a/src/test/java/ix/ToMapTest.java +++ b/src/test/java/ix/ToMapTest.java @@ -20,117 +20,115 @@ import org.junit.Test; -import rx.functions.Func1; - public class ToMapTest { @SuppressWarnings("unchecked") @Test public void normal() { - Ix> source = Ix.range(1, 5).collectToMap(new Func1() { + Ix> source = Ix.range(1, 5).collectToMap(new IxFunction() { @Override - public Integer call(Integer v) { + public Integer apply(Integer v) { return v % 3; } }); - + Map map = new HashMap(); map.put(1, 4); map.put(0, 3); map.put(2, 5); - + IxTestHelper.assertValues(source, map); } - + @SuppressWarnings("unchecked") @Test public void normalValueSelector() { - Ix> source = Ix.range(1, 5).collectToMap(new Func1() { + Ix> source = Ix.range(1, 5).collectToMap(new IxFunction() { @Override - public Integer call(Integer v) { + public Integer apply(Integer v) { return v % 3; } - }, new Func1() { + }, new IxFunction() { @Override - public Integer call(Integer v) { + public Integer apply(Integer v) { return v * v; } }); - + Map map = new HashMap(); map.put(1, 16); map.put(0, 9); map.put(2, 25); - + IxTestHelper.assertValues(source, map); } @SuppressWarnings("unchecked") @Test public void empty() { - Ix> source = Ix.empty().collectToMap(new Func1() { + Ix> source = Ix.empty().collectToMap(new IxFunction() { @Override - public Integer call(Integer v) { + public Integer apply(Integer v) { return v % 3; } }); - + Map map = new HashMap(); - + IxTestHelper.assertValues(source, map); } - + @SuppressWarnings("unchecked") @Test public void multimap() { - Ix>> source = Ix.range(1, 5).collectToMultimap(new Func1() { + Ix>> source = Ix.range(1, 5).collectToMultimap(new IxFunction() { @Override - public Integer call(Integer v) { + public Integer apply(Integer v) { return v % 3; } }); - + Map> map = new HashMap>(); map.put(1, Arrays.asList(1, 4)); map.put(0, Arrays.asList(3)); map.put(2, Arrays.asList(2, 5)); - + IxTestHelper.assertValues(source, map); } - + @SuppressWarnings("unchecked") @Test public void multimapValueSelector() { - Ix>> source = Ix.range(1, 5).collectToMultimap(new Func1() { + Ix>> source = Ix.range(1, 5).collectToMultimap(new IxFunction() { @Override - public Integer call(Integer v) { + public Integer apply(Integer v) { return v % 3; } - }, new Func1() { + }, new IxFunction() { @Override - public Integer call(Integer v) { + public Integer apply(Integer v) { return v * v; } }); - + Map> map = new HashMap>(); map.put(1, Arrays.asList(1, 16)); map.put(0, Arrays.asList(9)); map.put(2, Arrays.asList(4, 25)); - + IxTestHelper.assertValues(source, map); } @SuppressWarnings("unchecked") @Test public void multimapEmpty() { - Ix>> source = Ix.empty().collectToMultimap(new Func1() { + Ix>> source = Ix.empty().collectToMultimap(new IxFunction() { @Override - public Integer call(Integer v) { + public Integer apply(Integer v) { return v % 3; } }); - + Map> map = new HashMap>(); - + IxTestHelper.assertValues(source, map); } } diff --git a/src/test/java/ix/ToSetTest.java b/src/test/java/ix/ToSetTest.java index 41ae7f5..535f4b2 100644 --- a/src/test/java/ix/ToSetTest.java +++ b/src/test/java/ix/ToSetTest.java @@ -26,9 +26,9 @@ public class ToSetTest { @Test public void normal() { Ix> source = Ix.range(1, 5).collectToSet(); - + IxTestHelper.assertValues(source, new HashSet(Arrays.asList(1, 2, 3, 4, 5))); - + IxTestHelper.assertNoRemove(source); } @@ -36,19 +36,19 @@ public void normal() { @Test public void empty() { Ix> source = Ix.empty().collectToSet(); - + IxTestHelper.assertValues(source, new HashSet()); - + IxTestHelper.assertNoRemove(source); } - + @SuppressWarnings("unchecked") @Test public void duplicates() { Ix> source = Ix.fromArray(1, 2, 2, 3, 2, 4, 5, 1, 5).collectToSet(); - + IxTestHelper.assertValues(source, new HashSet(Arrays.asList(1, 2, 3, 4, 5))); - + IxTestHelper.assertNoRemove(source); } diff --git a/src/test/java/ix/ToXTest.java b/src/test/java/ix/ToXTest.java index a31d7d5..aac4576 100644 --- a/src/test/java/ix/ToXTest.java +++ b/src/test/java/ix/ToXTest.java @@ -20,119 +20,117 @@ import org.junit.*; -import rx.functions.Func1; - public class ToXTest { @Test public void cast() { Ix source = Ix.just(1).cast(Object.class); - + IxTestHelper.assertValues(source, 1); - + IxTestHelper.assertNoRemove(source); } @Test(expected = ClassCastException.class) public void castInvalid() { Ix source = Ix.just(1).cast(String.class); - + String s = source.first(); - + Assert.assertEquals("1", s); } - + @Test public void toArray() { - + Assert.assertArrayEquals(new Object[] {1, 2, 3, 4, 5}, Ix.range(1, 5).toArray()); - + } @Test public void toArrayTemplate() { - + Assert.assertArrayEquals(new Integer[] {1, 2, 3, 4, 5}, Ix.range(1, 5).toArray(new Integer[5])); - + } - + @Test public void toList() { Assert.assertEquals(Arrays.asList(1, 2, 3, 4, 5), Ix.range(1, 5).toList()); - + } @Test public void toSet() { Assert.assertEquals(new HashSet(Arrays.asList(1, 2, 3, 4, 5)), Ix.range(1, 5).toSet()); - + } @Test public void toMap() { Map map = Ix.range(1, 5).toMap(IdentityHelper.instance()); - + Map expected = new HashMap(); expected.put(1, 1); expected.put(2, 2); expected.put(3, 3); expected.put(4, 4); expected.put(5, 5); - + Assert.assertEquals(expected, map); } @Test public void toMapCustomValues() { - Map map = Ix.range(1, 5).toMap(IdentityHelper.instance(), new Func1() { + Map map = Ix.range(1, 5).toMap(IdentityHelper.instance(), new IxFunction() { @Override - public Integer call(Integer v) { + public Integer apply(Integer v) { return v * v; } }); - + Map expected = new HashMap(); expected.put(1, 1); expected.put(2, 4); expected.put(3, 9); expected.put(4, 16); expected.put(5, 25); - + Assert.assertEquals(expected, map); } @Test public void toMultimap() { Map> map = Ix.range(1, 5).toMultimap(IdentityHelper.instance()); - + Map> expected = new HashMap>(); expected.put(1, Collections.singletonList(1)); expected.put(2, Collections.singletonList(2)); expected.put(3, Collections.singletonList(3)); expected.put(4, Collections.singletonList(4)); expected.put(5, Collections.singletonList(5)); - + Assert.assertEquals(expected, map); } @Test public void toMultimapCustomValues() { - Map> map = Ix.range(1, 5).toMultimap(IdentityHelper.instance(), new Func1() { + Map> map = Ix.range(1, 5).toMultimap(IdentityHelper.instance(), new IxFunction() { @Override - public Integer call(Integer v) { + public Integer apply(Integer v) { return v * v; } }); - + Map> expected = new HashMap>(); expected.put(1, Collections.singletonList(1)); expected.put(2, Collections.singletonList(4)); expected.put(3, Collections.singletonList(9)); expected.put(4, Collections.singletonList(16)); expected.put(5, Collections.singletonList(25)); - + Assert.assertEquals(expected, map); } } diff --git a/src/test/java/ix/TransformTest.java b/src/test/java/ix/TransformTest.java index 450d1dc..f260736 100644 --- a/src/test/java/ix/TransformTest.java +++ b/src/test/java/ix/TransformTest.java @@ -20,75 +20,73 @@ import org.junit.*; -import rx.functions.Action1; - public class TransformTest { @Test public void normal() { Ix source = Ix.just(1).transform(new IxTransform() { @Override - public int moveNext(Iterator it, Action1 out) { + public int moveNext(Iterator it, IxConsumer out) { if (it.hasNext()) { - out.call(it.next() + 10); + out.accept(it.next() + 10); return IxTransform.NEXT; } - out.call(12); + out.accept(12); return IxTransform.LAST; } }); - + IxTestHelper.assertValues(source, 11, 12); - + IxTestHelper.assertNoRemove(source); } - + @Test public void stop() { Ix source = Ix.just(1).transform(new IxTransform() { @Override - public int moveNext(Iterator it, Action1 out) { + public int moveNext(Iterator it, IxConsumer out) { return IxTransform.STOP; } }); - + IxTestHelper.assertValues(source); - + IxTestHelper.assertNoRemove(source); } - + @Test public void doubleNext() { try { Ix source = Ix.just(1).transform(new IxTransform() { @Override - public int moveNext(Iterator it, Action1 out) { - out.call(1); - out.call(2); + public int moveNext(Iterator it, IxConsumer out) { + out.accept(1); + out.accept(2); return IxTransform.NEXT; } }); - + IxTestHelper.assertValues(source); - + Assert.fail("Failed to throw IllegalStateException"); } catch (IllegalStateException ex) { Assert.assertEquals("Value already set in this turn!", ex.getMessage()); } } - + @Test public void returnNextWithoutValue() { try { Ix source = Ix.just(1).transform(new IxTransform() { @Override - public int moveNext(Iterator it, Action1 out) { + public int moveNext(Iterator it, IxConsumer out) { return IxTransform.NEXT; } }); - + IxTestHelper.assertValues(source); - + Assert.fail("Failed to throw IllegalStateException"); } catch (IllegalStateException ex) { Assert.assertEquals("No value set!", ex.getMessage()); diff --git a/src/test/java/ix/UnionTest.java b/src/test/java/ix/UnionTest.java index cbe1be9..2b94546 100644 --- a/src/test/java/ix/UnionTest.java +++ b/src/test/java/ix/UnionTest.java @@ -23,91 +23,91 @@ public class UnionTest { @Test public void distinct() { Ix source = Ix.range(1, 5).union(Ix.range(6, 5)); - + IxTestHelper.assertValues(source, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10); - + IxTestHelper.assertNoRemove(source); } @Test public void overlap() { Ix source = Ix.range(1, 5).union(Ix.range(3, 5)); - + IxTestHelper.assertValues(source, 1, 2, 3, 4, 5, 6, 7); - + IxTestHelper.assertNoRemove(source); } @Test public void overlapReverse() { Ix source = Ix.range(3, 5).union(Ix.range(1, 5)); - + IxTestHelper.assertValues(source, 3, 4, 5, 6, 7, 1, 2); - + IxTestHelper.assertNoRemove(source); } - + @Test public void same() { Ix source = Ix.range(1, 5).union(Ix.range(1, 5)); - + IxTestHelper.assertValues(source, 1, 2, 3, 4, 5); - + IxTestHelper.assertNoRemove(source); } @Test public void firstInSecond() { Ix source = Ix.range(1, 3).union(Ix.range(1, 5)); - + IxTestHelper.assertValues(source, 1, 2, 3, 4, 5); - + IxTestHelper.assertNoRemove(source); } @Test public void secondInFirst() { Ix source = Ix.range(1, 5).union(Ix.range(1, 3)); - + IxTestHelper.assertValues(source, 1, 2, 3, 4, 5); - + IxTestHelper.assertNoRemove(source); } - + @Test public void firstEmpty() { Ix source = Ix.empty().union(Ix.range(1, 5)); - + IxTestHelper.assertValues(source, 1, 2, 3, 4, 5); - + IxTestHelper.assertNoRemove(source); } @Test public void secondEmpty() { Ix source = Ix.range(1, 5).union(Ix.empty()); - + IxTestHelper.assertValues(source, 1, 2, 3, 4, 5); - + IxTestHelper.assertNoRemove(source); } @Test public void bothEmpty() { Ix source = Ix.empty().union(Ix.empty()); - + IxTestHelper.assertValues(source); - + IxTestHelper.assertNoRemove(source); } - + @Test public void duplicates() { Ix source = Ix.fromArray(1, 2, 2, 1, 4, 5).union(Ix.fromArray(2, 3, 1, 5, 4)); - + IxTestHelper.assertValues(source, 1, 2, 4, 5, 3); - + IxTestHelper.assertNoRemove(source); } } diff --git a/src/test/java/ix/WindowTest.java b/src/test/java/ix/WindowTest.java index 00c6c28..2269ad0 100644 --- a/src/test/java/ix/WindowTest.java +++ b/src/test/java/ix/WindowTest.java @@ -27,31 +27,31 @@ public void normal() { Ix> source = Ix.range(1, 5).window(2); List> list = source.collectToList().first(); - + Assert.assertEquals(3, list.size()); IxTestHelper.assertValues(list.get(0), 1, 2); IxTestHelper.assertValues(list.get(1), 3, 4); IxTestHelper.assertValues(list.get(2), 5); } - + @Test public void normalSizeSkipSame() { Ix> source = Ix.range(1, 5).window(2, 2); List> list = source.collectToList().first(); - + Assert.assertEquals(3, list.size()); IxTestHelper.assertValues(list.get(0), 1, 2); IxTestHelper.assertValues(list.get(1), 3, 4); IxTestHelper.assertValues(list.get(2), 5); } - + @Test public void normalOne() { Ix> source = Ix.range(1, 5).window(1); List> list = source.collectToList().first(); - + Assert.assertEquals(5, list.size()); IxTestHelper.assertValues(list.get(0), 1); IxTestHelper.assertValues(list.get(1), 2); @@ -65,7 +65,7 @@ public void normalAll() { Ix> source = Ix.range(1, 5).window(5); List> list = source.collectToList().first(); - + Assert.assertEquals(1, list.size()); IxTestHelper.assertValues(list.get(0), 1, 2, 3, 4, 5); } @@ -75,22 +75,22 @@ public void normalMore() { Ix> source = Ix.range(1, 5).window(10); List> list = source.collectToList().first(); - + Assert.assertEquals(1, list.size()); IxTestHelper.assertValues(list.get(0), 1, 2, 3, 4, 5); } - + @Test public void innerMovesParent() { Ix> source = Ix.range(1, 5).window(3); Iterator> it0 = source.iterator(); - + Ix inner = it0.next(); - + Iterator it1 = inner.iterator(); - + try { inner.iterator(); Assert.fail("Should have thrown IllegalStateException"); @@ -109,18 +109,18 @@ public void normalSkip() { Ix> source = Ix.range(1, 5).window(2, 3); List> list = source.collectToList().first(); - + Assert.assertEquals(2, list.size()); IxTestHelper.assertValues(list.get(0), 1, 2); IxTestHelper.assertValues(list.get(1), 4, 5); } - + @Test public void normalSkip2() { Ix> source = Ix.range(1, 5).window(1, 2); List> list = source.collectToList().first(); - + Assert.assertEquals(3, list.size()); IxTestHelper.assertValues(list.get(0), 1); IxTestHelper.assertValues(list.get(1), 3); @@ -132,7 +132,7 @@ public void normalSkip3() { Ix> source = Ix.range(1, 5).window(1, 6); List> list = source.collectToList().first(); - + Assert.assertEquals(1, list.size()); IxTestHelper.assertValues(list.get(0), 1); } @@ -142,21 +142,21 @@ public void normalAllSkip() { Ix> source = Ix.range(1, 5).window(5, 10); List> list = source.collectToList().first(); - + Assert.assertEquals(1, list.size()); IxTestHelper.assertValues(list.get(0), 1, 2, 3, 4, 5); } - + @Test public void normalMoreSkip() { Ix> source = Ix.range(1, 5).window(10, 15); List> list = source.collectToList().first(); - + Assert.assertEquals(1, list.size()); IxTestHelper.assertValues(list.get(0), 1, 2, 3, 4, 5); } - + @Test public void justSkip() { Ix> source = Ix.just(1).window(2, 3); @@ -166,7 +166,7 @@ public void justSkip() { Assert.assertEquals(1, list.size()); IxTestHelper.assertValues(list.get(0), 1); } - + @Test public void emptySkip() { Ix> source = Ix.empty().window(2, 3); @@ -175,18 +175,18 @@ public void emptySkip() { Assert.assertEquals(0, list.size()); } - + @Test public void skipInnerMovesParent() { Ix> source = Ix.range(1, 5).window(2, 3); Iterator> it0 = source.iterator(); - + Ix inner = it0.next(); - + Iterator it1 = inner.iterator(); - + try { inner.iterator(); Assert.fail("Should have thrown IllegalStateException"); @@ -196,23 +196,23 @@ public void skipInnerMovesParent() { Assert.assertEquals(1, it1.next().intValue()); Assert.assertEquals(2, it1.next().intValue()); Assert.assertFalse(it1.hasNext()); - + inner = it0.next(); it1 = inner.iterator(); - + Assert.assertEquals(4, it1.next().intValue()); Assert.assertEquals(5, it1.next().intValue()); Assert.assertFalse(it1.hasNext()); - + Assert.assertFalse(it0.hasNext()); } - + @Test public void normalOverlap() { Ix> source = Ix.range(1, 5).window(2, 1); List> list = source.collectToList().first(); - + Assert.assertEquals(5, list.size()); IxTestHelper.assertValues(list.get(0), 1, 2); IxTestHelper.assertValues(list.get(1), 2, 3); @@ -220,13 +220,13 @@ public void normalOverlap() { IxTestHelper.assertValues(list.get(3), 4, 5); IxTestHelper.assertValues(list.get(4), 5); } - + @Test public void normalOverlap2() { Ix> source = Ix.range(1, 5).window(3, 1); List> list = source.collectToList().first(); - + Assert.assertEquals(5, list.size()); IxTestHelper.assertValues(list.get(0), 1, 2, 3); IxTestHelper.assertValues(list.get(1), 2, 3, 4); @@ -234,13 +234,13 @@ public void normalOverlap2() { IxTestHelper.assertValues(list.get(3), 4, 5); IxTestHelper.assertValues(list.get(4), 5); } - + @Test public void normalOverlap3() { Ix> source = Ix.range(1, 5).window(3, 2); List> list = source.collectToList().first(); - + Assert.assertEquals(3, list.size()); IxTestHelper.assertValues(list.get(0), 1, 2, 3); IxTestHelper.assertValues(list.get(1), 3, 4, 5); @@ -252,13 +252,13 @@ public void nullExact() { Ix> source = Ix.fromArray(null, null, null, null, null).window(2); List> list = source.collectToList().first(); - + Assert.assertEquals(3, list.size()); IxTestHelper.assertValues(list.get(0), null, null); IxTestHelper.assertValues(list.get(1), null, null); IxTestHelper.assertValues(list.get(2), (Integer)null); } - + @Test public void nullExact2() { Ix> source = Ix.fromArray(null, null, null, null, null).window(6); @@ -278,18 +278,18 @@ public void nullSkip() { Ix> source = Ix.fromArray(null, null, null, null, null).window(2, 3); List> list = source.collectToList().first(); - + Assert.assertEquals(2, list.size()); IxTestHelper.assertValues(list.get(0), null, null); IxTestHelper.assertValues(list.get(1), null, null); } - + @Test public void nullOverlap() { Ix> source = Ix.fromArray(null, null, null, null, null).window(2, 1); List> list = source.collectToList().first(); - + Assert.assertEquals(5, list.size()); IxTestHelper.assertValues(list.get(0), null, null); IxTestHelper.assertValues(list.get(1), null, null); @@ -297,18 +297,18 @@ public void nullOverlap() { IxTestHelper.assertValues(list.get(3), null, null); IxTestHelper.assertValues(list.get(4), (Integer)null); } - + @Test public void overlapInnerMovesParent() { Ix> source = Ix.range(1, 5).window(2, 1); Iterator> it0 = source.iterator(); - + Ix inner = it0.next(); - + Iterator it1 = inner.iterator(); - + try { inner.iterator(); Assert.fail("Should have thrown IllegalStateException"); @@ -318,28 +318,28 @@ public void overlapInnerMovesParent() { Assert.assertEquals(1, it1.next().intValue()); Assert.assertEquals(2, it1.next().intValue()); Assert.assertFalse(it1.hasNext()); - + inner = it0.next(); it1 = inner.iterator(); - + Assert.assertEquals(2, it1.next().intValue()); Assert.assertEquals(3, it1.next().intValue()); Assert.assertFalse(it1.hasNext()); - + Assert.assertTrue(it0.hasNext()); } - + @Test public void overlapInnerMovesParent2() { Ix> source = Ix.range(1, 5).window(3, 2); Iterator> it0 = source.iterator(); - + Ix inner = it0.next(); - + Iterator it1 = inner.iterator(); - + try { inner.iterator(); Assert.fail("Should have thrown IllegalStateException"); @@ -350,10 +350,10 @@ public void overlapInnerMovesParent2() { Assert.assertEquals(2, it1.next().intValue()); Assert.assertEquals(3, it1.next().intValue()); Assert.assertFalse(it1.hasNext()); - + inner = it0.next(); it1 = inner.iterator(); - + Assert.assertEquals(3, it1.next().intValue()); Assert.assertEquals(4, it1.next().intValue()); Assert.assertEquals(5, it1.next().intValue()); @@ -368,10 +368,10 @@ public void overlapParentMoved() { Ix> source = Ix.range(1, 5).window(4, 3); Iterator> it0 = source.iterator(); - + Ix inner1 = it0.next(); Ix inner2 = it0.next(); - + Assert.assertFalse(it0.hasNext()); IxTestHelper.assertValues(inner1, 1, 2, 3, 4); diff --git a/src/test/java/ix/Zip2Test.java b/src/test/java/ix/Zip2Test.java index 1c2f629..c6c5dd6 100644 --- a/src/test/java/ix/Zip2Test.java +++ b/src/test/java/ix/Zip2Test.java @@ -18,58 +18,56 @@ import org.junit.Test; -import rx.functions.*; - public class Zip2Test { - Func2 sum = new Func2() { + IxFunction2 sum = new IxFunction2() { @Override - public Integer call(Integer a, Integer b) { + public Integer apply(Integer a, Integer b) { return a + b; } }; - + @Test public void normal() { - - Ix source = Ix.zip( + + Ix source = Ix.zip( Ix.range(1, 2), Ix.range(10, 2), sum); - + IxTestHelper.assertValues(source, 11, 13); } - + @Test public void firstShorter() { - - Ix source = Ix.zip( + + Ix source = Ix.zip( Ix.range(1, 1), Ix.range(10, 2), sum); - + IxTestHelper.assertValues(source, 11); } @Test public void secondShorter() { - - Ix source = Ix.zip( + + Ix source = Ix.zip( Ix.range(1, 3), Ix.range(10, 2), sum); - + IxTestHelper.assertValues(source, 11, 13); } @Test public void bothEmpty() { - - Ix source = Ix.zip( + + Ix source = Ix.zip( Ix.empty(), Ix.empty(), sum); - + IxTestHelper.assertValues(source); } @Test public void normalWith() { - + Ix source = Ix.range(1, 2).zipWith(Ix.range(10, 2), sum); - + IxTestHelper.assertValues(source, 11, 13); } diff --git a/src/test/java/ix/Zip3Test.java b/src/test/java/ix/Zip3Test.java index 96e4fca..32172f7 100644 --- a/src/test/java/ix/Zip3Test.java +++ b/src/test/java/ix/Zip3Test.java @@ -18,59 +18,57 @@ import org.junit.Test; -import rx.functions.*; - public class Zip3Test { - Func3 sum = new Func3() { + IxFunction3 sum = new IxFunction3() { @Override - public Integer call(Integer a, Integer b, Integer c) { + public Integer apply(Integer a, Integer b, Integer c) { return a + b + c; } }; - + @Test public void normal() { - - Ix source = Ix.zip( + + Ix source = Ix.zip( Ix.range(1, 2), Ix.range(10, 2), Ix.range(100, 2), sum); - + IxTestHelper.assertValues(source, 111, 114); } - + @Test public void firstShorter() { - - Ix source = Ix.zip( + + Ix source = Ix.zip( Ix.range(1, 1), Ix.range(10, 2), Ix.range(100, 2), sum); - + IxTestHelper.assertValues(source, 111); } @Test public void secondShorter() { - - Ix source = Ix.zip( + + Ix source = Ix.zip( Ix.range(1, 3), Ix.range(10, 2), Ix.range(100, 2), sum); - + IxTestHelper.assertValues(source, 111, 114); } @Test public void thirdShorter() { - - Ix source = Ix.zip( + + Ix source = Ix.zip( Ix.range(1, 3), Ix.range(10, 3), Ix.range(100, 2), sum); - + IxTestHelper.assertValues(source, 111, 114); } @Test public void allEmpty() { - - Ix source = Ix.zip( + + Ix source = Ix.zip( Ix.empty(), Ix.empty(), Ix.empty(), sum); - + IxTestHelper.assertValues(source); } diff --git a/src/test/java/ix/Zip4Test.java b/src/test/java/ix/Zip4Test.java index 460fc8e..e859894 100644 --- a/src/test/java/ix/Zip4Test.java +++ b/src/test/java/ix/Zip4Test.java @@ -18,68 +18,66 @@ import org.junit.Test; -import rx.functions.*; - public class Zip4Test { - Func4 sum = new Func4() { + IxFunction4 sum = new IxFunction4() { @Override - public Integer call(Integer a, Integer b, Integer c, Integer d) { + public Integer apply(Integer a, Integer b, Integer c, Integer d) { return a + b + c + d; } }; - + @Test public void normal() { - - Ix source = Ix.zip( + + Ix source = Ix.zip( Ix.range(1, 2), Ix.range(10, 2), Ix.range(100, 2), Ix.range(1000, 2), sum); - + IxTestHelper.assertValues(source, 1111, 1115); } - + @Test public void firstShorter() { - - Ix source = Ix.zip( + + Ix source = Ix.zip( Ix.range(1, 1), Ix.range(10, 2), Ix.range(100, 2), Ix.range(1000, 2), sum); - + IxTestHelper.assertValues(source, 1111); } @Test public void secondShorter() { - - Ix source = Ix.zip( + + Ix source = Ix.zip( Ix.range(1, 3), Ix.range(10, 2), Ix.range(100, 3), Ix.range(1000, 3), sum); - + IxTestHelper.assertValues(source, 1111, 1115); } @Test public void thirdShorter() { - - Ix source = Ix.zip( + + Ix source = Ix.zip( Ix.range(1, 3), Ix.range(10, 3), Ix.range(100, 2), Ix.range(1000, 3), sum); - + IxTestHelper.assertValues(source, 1111, 1115); } @Test public void fourthShorter() { - - Ix source = Ix.zip( + + Ix source = Ix.zip( Ix.range(1, 3), Ix.range(10, 3), Ix.range(100, 3), Ix.range(1000, 2), sum); - + IxTestHelper.assertValues(source, 1111, 1115); } @Test public void allEmpty() { - - Ix source = Ix.zip( + + Ix source = Ix.zip( Ix.empty(), Ix.empty(), Ix.empty(), Ix.empty(), sum); - + IxTestHelper.assertValues(source); } diff --git a/src/test/java/ix/ZipArrayTest.java b/src/test/java/ix/ZipArrayTest.java index f517c10..6b7d6fa 100644 --- a/src/test/java/ix/ZipArrayTest.java +++ b/src/test/java/ix/ZipArrayTest.java @@ -18,13 +18,11 @@ import org.junit.Test; -import rx.functions.FuncN; - public class ZipArrayTest { - FuncN zipper = new FuncN() { + IxFunction zipper = new IxFunction() { @Override - public Integer call(Object... a) { + public Integer apply(Object[] a) { return (Integer)a[0] + (Integer)a[1]; } }; @@ -32,44 +30,44 @@ public Integer call(Object... a) { @SuppressWarnings("unchecked") @Test public void normal() { - - Ix source = Ix.zip(new Iterable[] { - Ix.range(1, 2), Ix.range(10, 2) }, + + Ix source = Ix.zip(new Iterable[] { + Ix.range(1, 2), Ix.range(10, 2) }, zipper); - + IxTestHelper.assertValues(source, 11, 13); } - + @SuppressWarnings("unchecked") @Test public void firstShorter() { - - Ix source = Ix.zip(new Iterable[] { - Ix.range(1, 1), Ix.range(10, 2) }, + + Ix source = Ix.zip(new Iterable[] { + Ix.range(1, 1), Ix.range(10, 2) }, zipper); - + IxTestHelper.assertValues(source, 11); } @SuppressWarnings("unchecked") @Test public void secondShorter() { - - Ix source = Ix.zip(new Iterable[] { - Ix.range(1, 3), Ix.range(10, 2) }, + + Ix source = Ix.zip(new Iterable[] { + Ix.range(1, 3), Ix.range(10, 2) }, zipper); - + IxTestHelper.assertValues(source, 11, 13); } @SuppressWarnings("unchecked") @Test public void bothEmpty() { - - Ix source = Ix.zip(new Iterable[] { - Ix.empty(), Ix.empty() }, + + Ix source = Ix.zip(new Iterable[] { + Ix.empty(), Ix.empty() }, zipper); - + IxTestHelper.assertValues(source); } diff --git a/src/test/java/ix/ZipIterableTest.java b/src/test/java/ix/ZipIterableTest.java index 7d653d6..6220a93 100644 --- a/src/test/java/ix/ZipIterableTest.java +++ b/src/test/java/ix/ZipIterableTest.java @@ -20,13 +20,11 @@ import org.junit.Test; -import rx.functions.FuncN; - public class ZipIterableTest { - FuncN zipper = new FuncN() { + IxFunction zipper = new IxFunction() { @Override - public Integer call(Object... a) { + public Integer apply(Object[] a) { int s = 0; for (Object o : a) { s += (Integer)o; @@ -38,61 +36,61 @@ public Integer call(Object... a) { @SuppressWarnings("unchecked") @Test public void normal() { - - Ix source = Ix.zip(Arrays.asList( - Ix.range(1, 2), Ix.range(10, 2)), + + Ix source = Ix.zip(Arrays.asList( + Ix.range(1, 2), Ix.range(10, 2)), zipper); - + IxTestHelper.assertValues(source, 11, 13); } - + @SuppressWarnings("unchecked") @Test public void normalMany() { - - Ix source = Ix.zip(Arrays.asList( + + Ix source = Ix.zip(Arrays.asList( Ix.range(1, 2), Ix.range(1, 2), Ix.range(1, 2), Ix.range(1, 2), Ix.range(1, 2), Ix.range(1, 2), Ix.range(1, 2), Ix.range(1, 2), Ix.range(1, 2), Ix.range(1, 2), Ix.range(1, 2), Ix.range(1, 2) - ), + ), zipper); - + IxTestHelper.assertValues(source, 12, 24); } - + @SuppressWarnings("unchecked") @Test public void firstShorter() { - - Ix source = Ix.zip(Arrays.asList( - Ix.range(1, 1), Ix.range(10, 2) ), + + Ix source = Ix.zip(Arrays.asList( + Ix.range(1, 1), Ix.range(10, 2) ), zipper); - + IxTestHelper.assertValues(source, 11); } @SuppressWarnings("unchecked") @Test public void secondShorter() { - - Ix source = Ix.zip(Arrays.asList( - Ix.range(1, 3), Ix.range(10, 2) ), + + Ix source = Ix.zip(Arrays.asList( + Ix.range(1, 3), Ix.range(10, 2) ), zipper); - + IxTestHelper.assertValues(source, 11, 13); } @SuppressWarnings("unchecked") @Test public void bothEmpty() { - - Ix source = Ix.zip(Arrays.asList( - Ix.empty(), Ix.empty() ), + + Ix source = Ix.zip(Arrays.asList( + Ix.empty(), Ix.empty() ), zipper); - + IxTestHelper.assertValues(source); } From 86ed64a1e1d6961e84556e27f5dc35e00e3e03a5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?D=C3=A1vid=20Karnok?= Date: Wed, 14 Sep 2016 23:46:48 +0200 Subject: [PATCH 40/66] Release RC3 --- README.md | 4 ++-- gradle.properties | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index f9db33f..0085e03 100644 --- a/README.md +++ b/README.md @@ -19,7 +19,7 @@ and interactive dataflows.** ```groovy dependencies { - compile 'com.github.akarnokd:ixjava:1.0.0-RC2' + compile 'com.github.akarnokd:ixjava:1.0.0-RC3' } ``` @@ -27,7 +27,7 @@ dependencies { ```xml - + ``` diff --git a/gradle.properties b/gradle.properties index e547ca3..1920096 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1 +1 @@ -version=1.0.0-RC2 +version=1.0.0-RC3 From 871da55da2f09aa78fc5dc9b5a41a661d1d96345 Mon Sep 17 00:00:00 2001 From: nfekete Date: Sun, 18 Dec 2016 21:09:39 +0100 Subject: [PATCH 41/66] Added explicit type arguments to some method calls to work around type inference limitations in Eclipse (and thus GWT) compiler (#9) --- src/main/java/ix/Ix.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/java/ix/Ix.java b/src/main/java/ix/Ix.java index 46432ca..70c05f2 100644 --- a/src/main/java/ix/Ix.java +++ b/src/main/java/ix/Ix.java @@ -2520,7 +2520,7 @@ public final List toList() { * @since 1.0 */ public final Map toMap(IxFunction keySelector) { - return collectToMap(keySelector).first(); + return this.collectToMap(keySelector).first(); } /** @@ -2540,7 +2540,7 @@ public final Map toMap(IxFunction keySelector) * @since 1.0 */ public final Map toMap(IxFunction keySelector, IxFunction valueSelector) { - return collectToMap(keySelector, valueSelector).first(); + return this.collectToMap(keySelector, valueSelector).first(); } /** @@ -2555,7 +2555,7 @@ public final Map toMap(IxFunction keySelect * @since 1.0 */ public final Map> toMultimap(IxFunction keySelector) { - return collectToMultimap(keySelector).first(); + return this.collectToMultimap(keySelector).first(); } /** @@ -2574,7 +2574,7 @@ public final Map> toMultimap(IxFunction Map> toMultimap(IxFunction keySelector, IxFunction valueSelector) { - return collectToMultimap(keySelector, valueSelector).first(); + return this.collectToMultimap(keySelector, valueSelector).first(); } /** From 7cc0b8456b43fa15ce1961e5ac41d122acf70102 Mon Sep 17 00:00:00 2001 From: akarnokd Date: Sun, 18 Dec 2016 21:35:14 +0100 Subject: [PATCH 42/66] Release 1.0.0-RC4 --- gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index 1920096..fabe516 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1 +1 @@ -version=1.0.0-RC3 +version=1.0.0-RC4 From 10f482429ee18f047882001aae1a3322839b00b5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?N=C3=A1ndor=20El=C5=91d=20Fekete?= Date: Thu, 29 Dec 2016 17:27:30 +0100 Subject: [PATCH 43/66] fix for https://github.com/akarnokd/ixjava/issues/10 (#11) --- src/main/java/ix/Ix.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/ix/Ix.java b/src/main/java/ix/Ix.java index 70c05f2..aca9e5b 100644 --- a/src/main/java/ix/Ix.java +++ b/src/main/java/ix/Ix.java @@ -1963,7 +1963,7 @@ public final Ix takeLast(int n) { } /** - * Take elements from this sequence while the given predicate returns true + * Take elements from this sequence until the given predicate returns true * for the current element (checked after emission of that element). *

* The result's Iterator forwards calls of remove() to this' Iterator. @@ -1978,7 +1978,7 @@ public final Ix takeUntil(IxPredicate stopPredicate) { } /** - * Take elements from this sequence until the given predicate returns true + * Take elements from this sequence while the given predicate returns true * for the current element (checked before emission of that element). *

* The result's Iterator forwards calls of remove() to this' Iterator. From 0399a07fab28590eb042ed9863f061ac5669fb6b Mon Sep 17 00:00:00 2001 From: akarnokd Date: Mon, 2 Jan 2017 10:27:13 +0100 Subject: [PATCH 44/66] More operators --- README.md | 4 +- gradle.properties | 2 +- src/main/java/ix/GroupedIx.java | 11 ++ src/main/java/ix/Ix.java | 146 ++++++++++++++++++ src/main/java/ix/IxBufferSplit.java | 103 +++++++++++++ src/main/java/ix/IxBufferUntil.java | 104 +++++++++++++ src/main/java/ix/IxBufferWhile.java | 111 ++++++++++++++ src/main/java/ix/IxEvery.java | 95 ++++++++++++ src/main/java/ix/IxOrderedMergeArray.java | 142 +++++++++++++++++ src/main/java/ix/IxOrderedMergeIterable.java | 55 +++++++ src/main/java/ix/IxReadOnly.java | 90 +++++++++++ src/main/java/ix/IxRepeat.java | 35 ++--- src/main/java/ix/IxRepeatCallable.java | 54 +++++++ src/test/java/ix/BufferPredicateTest.java | 153 +++++++++++++++++++ src/test/java/ix/EveryTest.java | 62 ++++++++ src/test/java/ix/OrderedMergeTest.java | 105 +++++++++++++ src/test/java/ix/ReadOnlyTest.java | 57 +++++++ src/test/java/ix/RepeatTest.java | 17 +++ 18 files changed, 1321 insertions(+), 25 deletions(-) create mode 100644 src/main/java/ix/IxBufferSplit.java create mode 100644 src/main/java/ix/IxBufferUntil.java create mode 100644 src/main/java/ix/IxBufferWhile.java create mode 100644 src/main/java/ix/IxEvery.java create mode 100644 src/main/java/ix/IxOrderedMergeArray.java create mode 100644 src/main/java/ix/IxOrderedMergeIterable.java create mode 100644 src/main/java/ix/IxReadOnly.java create mode 100644 src/main/java/ix/IxRepeatCallable.java create mode 100644 src/test/java/ix/BufferPredicateTest.java create mode 100644 src/test/java/ix/EveryTest.java create mode 100644 src/test/java/ix/OrderedMergeTest.java create mode 100644 src/test/java/ix/ReadOnlyTest.java diff --git a/README.md b/README.md index 0085e03..9b661be 100644 --- a/README.md +++ b/README.md @@ -19,7 +19,7 @@ and interactive dataflows.** ```groovy dependencies { - compile 'com.github.akarnokd:ixjava:1.0.0-RC3' + compile 'com.github.akarnokd:ixjava:1.0.0-RC5' } ``` @@ -27,7 +27,7 @@ dependencies { ```xml - + ``` diff --git a/gradle.properties b/gradle.properties index fabe516..d4591bd 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1 +1 @@ -version=1.0.0-RC4 +version=1.0.0-RC5 diff --git a/src/main/java/ix/GroupedIx.java b/src/main/java/ix/GroupedIx.java index c6681fe..1dda83b 100644 --- a/src/main/java/ix/GroupedIx.java +++ b/src/main/java/ix/GroupedIx.java @@ -25,12 +25,23 @@ */ public abstract class GroupedIx extends Ix { + /** + * The group key. + */ protected final K key; + /** + * Constructs a GroupedIx with the given group key. + * @param key the group key + */ public GroupedIx(K key) { this.key = key; } + /** + * Returns this group's key. + * @return the key + */ public final K key() { return key; } diff --git a/src/main/java/ix/Ix.java b/src/main/java/ix/Ix.java index aca9e5b..2911710 100644 --- a/src/main/java/ix/Ix.java +++ b/src/main/java/ix/Ix.java @@ -398,6 +398,58 @@ public static Ix mergeArray(Iterable... sources) { return concatArray(sources); // concat and merge are the same in the Iterable world } + /** + * Merges self-comparable items from an Iterable sequence of Iterable sequences, picking + * the smallest item from all those inner Iterables until all sources complete. + * @param the value type + * @param sources the Iterable sequence of Iterables of self-comparable items + * @return the new Ix instance + * @since 1.0 + */ + public static > Ix orderedMerge(Iterable> sources) { + return orderedMerge(sources, SelfComparator.INSTANCE); + } + + /** + * Merges items from an Iterable sequence of Iterable sequences, picking + * the smallest item (according to a custom comparator) from all those inner + * Iterables until all sources complete. + * @param the value type + * @param sources the Iterable sequence of Iterables + * @param comparator the comparator to compare items and pick the one that returns negative will be picked + * @return the new Ix instance + * @since 1.0 + */ + public static Ix orderedMerge(Iterable> sources, Comparator comparator) { + return new IxOrderedMergeIterable(nullCheck(sources, "sources is null"), nullCheck(comparator, "comparator is null")); + } + + /** + * Merges self-comparable items from an Iterable sequence of Iterable sequences, picking + * the smallest item from all those inner Iterables until all sources complete. + * @param the value type + * @param sources the Iterable sequence of Iterables of self-comparable items + * @return the new Ix instance + * @since 1.0 + */ + public static > Ix orderedMergeArray(Iterable... sources) { + return orderedMergeArray(SelfComparator.INSTANCE, sources); + } + + /** + * Merges items from an array of Iterable sequences, picking + * the smallest item (according to a custom comparator) from all those inner + * Iterables until all sources complete. + * @param the value type + * @param sources the Iterable sequence of Iterables + * @param comparator the comparator to compare items and pick the one that returns negative will be picked + * @return the new Ix instance + * @since 1.0 + */ + public static Ix orderedMergeArray(Comparator comparator, Iterable... sources) { + return new IxOrderedMergeArray(nullCheck(sources, "sources is null"), nullCheck(comparator, "comparator is null")); + } + /** * Emits a range of incrementing integer values, starting from {@code start} and * up to {@code count} times. @@ -420,6 +472,43 @@ public static Ix range(int start, int count) { return new IxRange(start, count); } + /** + * Prevents the downstream from calling remove() and throws + * an UnsupportedOperationException instead. + * @return the new Ix instance + * @see #readOnly(boolean) + * @since 1.0 + */ + public final Ix readOnly() { + return new IxReadOnly(this, false); + } + + /** + * Prevents the downstream from calling remove() by optionally + * ignoring it or throwing an UnsupportedOperationException. + * @param silent if true, remove() calls are ignored; if false, + * remove() calls throw an UnsupportedOperationException + * @return the new Ix instance + * @since 1.0 + */ + public final Ix readOnly(boolean silent) { + return new IxReadOnly(this, silent); + } + + /** + * Repeatedly calls the given callable indefinitely and + * emits the returned value. + *

+ * The result's iterator() doesn't support remove(). + * @param the value type + * @param callable the callable to call + * @return the new Ix instance + * @since 1.0 + */ + public static Ix repeatCallable(Callable callable) { + return new IxRepeatCallable(nullCheck(callable, "callable is null")); + } + /** * Repeats the given value indefinitely. *

@@ -738,6 +827,52 @@ public final Ix> buffer(int size, int skip) { return new IxBufferOverlap(this, positive(size, "size"), positive(skip, "skip")); } + /** + * Buffer until an item is encountered for which the predicate returns true, + * triggering a new buffer. + *

Neither the previous nor the next buffer will contain the item that caused the + * split + * @param predicate the predicate called with each item and should return false + * to trigger a new buffer + * @return the new Ix instance + * @see #bufferUntil(IxPredicate) + * @see #bufferWhile(IxPredicate) + * @since 1.0 + */ + public final Ix> bufferSplit(IxPredicate predicate) { + return new IxBufferSplit(this, nullCheck(predicate, "predicate is null")); + } + + /** + * Buffer until an item is encountered after which the predicate returns true + * to start a new buffer. + *

The item will be part of the previous buffer. + * @param predicate the predicate called with each item after the item + * has been added to the current buffer and should return true to start a new buffer + * @return the new Ix instance + * @see #bufferSplit(IxPredicate) + * @see #bufferWhile(IxPredicate) + * @since 1.0 + */ + public final Ix> bufferUntil(IxPredicate predicate) { + return new IxBufferUntil(this, nullCheck(predicate, "predicate is null")); + } + + /** + * Buffer while an item is encountered before which the predicate returns false + * to start a new buffer. + *

The item will be part of the next buffer + * @param predicate the predicate called with each item after the item + * has been added to the current buffer and should return true to start a new buffer + * @return the new Ix instance + * @see #bufferSplit(IxPredicate) + * @see #bufferUntil(IxPredicate) + * @since 1.0 + */ + public final Ix> bufferWhile(IxPredicate predicate) { + return new IxBufferWhile(this, nullCheck(predicate, "predicate is null")); + } + /** * Cast the elements to the specified class. *

@@ -1095,6 +1230,17 @@ public final Ix endWith(T... values) { return concat(this, fromArray(values)); } + /** + * Emit every Nth item only from upstream. + *

Example: Ix.range(1, 5).every(2) will yield {2, 4}. + * @param nth how many items to skip + 1 + * @return the new Ix instance + * @since 1.0 + */ + public final Ix every(int nth) { + return new IxEvery(this, positive(nth, "nth")); + } + /** * Emits distinct elements from this and the other Iterable which are not * in the other sequence (i.e., (A union B) minus (A intersection B)). diff --git a/src/main/java/ix/IxBufferSplit.java b/src/main/java/ix/IxBufferSplit.java new file mode 100644 index 0000000..e354496 --- /dev/null +++ b/src/main/java/ix/IxBufferSplit.java @@ -0,0 +1,103 @@ +/* + * Copyright 2011-2016 David Karnok + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ix; + +import java.util.*; + +/** + * Split into buffers when the predicate returns true and neither + * buffer contains the item. + * + * @param the value type + */ +final class IxBufferSplit extends IxSource> { + + final IxPredicate predicate; + + IxBufferSplit(Iterable source, IxPredicate predicate) { + super(source); + this.predicate = predicate; + } + + @Override + public Iterator> iterator() { + return new BufferSplitIterator(source.iterator(), predicate); + } + + static final class BufferSplitIterator implements Iterator> { + + final Iterator source; + + final IxPredicate predicate; + + boolean done; + + List buffer; + + BufferSplitIterator(Iterator source, IxPredicate predicate) { + this.source = source; + this.predicate = predicate; + } + + @Override + public boolean hasNext() { + List b = buffer; + if (b == null) { + if (done) { + return false; + } + + b = new ArrayList(); + + Iterator src = source; + while (src.hasNext()) { + T v = src.next(); + + if (predicate.test(v)) { + buffer = b; + return true; + } + + b.add(v); + } + + if (b.isEmpty()) { + done = true; + return false; + } + + buffer = b; + } + return true; + } + + @Override + public List next() { + if (hasNext()) { + List b = buffer; + buffer = null; + return b; + } + throw new NoSuchElementException(); + } + + @Override + public void remove() { + throw new UnsupportedOperationException(); + } + } +} diff --git a/src/main/java/ix/IxBufferUntil.java b/src/main/java/ix/IxBufferUntil.java new file mode 100644 index 0000000..6a1e72c --- /dev/null +++ b/src/main/java/ix/IxBufferUntil.java @@ -0,0 +1,104 @@ +/* + * Copyright 2011-2016 David Karnok + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ix; + +import java.util.*; + +/** + * Split into buffers when the predicate returns true and neither + * buffer contains the item. + * + * @param the value type + */ +final class IxBufferUntil extends IxSource> { + + final IxPredicate predicate; + + IxBufferUntil(Iterable source, IxPredicate predicate) { + super(source); + this.predicate = predicate; + } + + @Override + public Iterator> iterator() { + return new BufferSplitIterator(source.iterator(), predicate); + } + + static final class BufferSplitIterator implements Iterator> { + + final Iterator source; + + final IxPredicate predicate; + + boolean done; + + List buffer; + + BufferSplitIterator(Iterator source, IxPredicate predicate) { + this.source = source; + this.predicate = predicate; + } + + @Override + public boolean hasNext() { + List b = buffer; + if (b == null) { + if (done) { + return false; + } + + b = new ArrayList(); + + Iterator src = source; + while (src.hasNext()) { + T v = src.next(); + + b.add(v); + + if (predicate.test(v)) { + buffer = b; + return true; + } + } + + if (b.isEmpty()) { + done = true; + return false; + } + + buffer = b; + done = true; + } + return true; + } + + @Override + public List next() { + if (hasNext()) { + List b = buffer; + buffer = null; + return b; + } + throw new NoSuchElementException(); + } + + @Override + public void remove() { + throw new UnsupportedOperationException(); + } + } +} diff --git a/src/main/java/ix/IxBufferWhile.java b/src/main/java/ix/IxBufferWhile.java new file mode 100644 index 0000000..af28b81 --- /dev/null +++ b/src/main/java/ix/IxBufferWhile.java @@ -0,0 +1,111 @@ +/* + * Copyright 2011-2016 David Karnok + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ix; + +import java.util.*; + +/** + * Buffer while the predicate returns true. + * + * @param the value type + */ +final class IxBufferWhile extends IxSource> { + + final IxPredicate predicate; + + IxBufferWhile(Iterable source, IxPredicate predicate) { + super(source); + this.predicate = predicate; + } + + @Override + public Iterator> iterator() { + return new BufferSplitIterator(source.iterator(), predicate); + } + + static final class BufferSplitIterator implements Iterator> { + + final Iterator source; + + final IxPredicate predicate; + + boolean done; + + List buffer; + + List next; + + BufferSplitIterator(Iterator source, IxPredicate predicate) { + this.source = source; + this.predicate = predicate; + } + + @Override + public boolean hasNext() { + List b = buffer; + if (b == null) { + if (done) { + return false; + } + + b = next; + if (b == null) { + b = new ArrayList(); + } + + Iterator src = source; + while (src.hasNext()) { + T v = src.next(); + + if (!predicate.test(v)) { + buffer = b; + b = new ArrayList(); + b.add(v); + next = b; + return true; + } + + b.add(v); + } + + if (b.isEmpty()) { + done = true; + return false; + } + + buffer = b; + done = true; + } + return true; + } + + @Override + public List next() { + if (hasNext()) { + List b = buffer; + buffer = null; + return b; + } + throw new NoSuchElementException(); + } + + @Override + public void remove() { + throw new UnsupportedOperationException(); + } + } +} diff --git a/src/main/java/ix/IxEvery.java b/src/main/java/ix/IxEvery.java new file mode 100644 index 0000000..7c510a2 --- /dev/null +++ b/src/main/java/ix/IxEvery.java @@ -0,0 +1,95 @@ +/* + * Copyright 2011-2016 David Karnok + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ix; + +import java.util.*; + +/** + * Emits every Nth item from upstream. + * + * @param the value type + */ +final class IxEvery extends IxSource { + + final int nth; + + IxEvery(Iterable source, int nth) { + super(source); + this.nth = nth; + } + + @Override + public Iterator iterator() { + return new EveryIterator(source.iterator(), nth); + } + + static final class EveryIterator implements Iterator { + + final Iterator source; + + final int nth; + + boolean done; + + boolean hasValue; + + EveryIterator(Iterator it, int nth) { + this.source = it; + this.nth = nth; + } + + @Override + public boolean hasNext() { + if (done) { + return false; + } + if (!hasValue) { + int i = nth - 1; + + Iterator src = source; + + while (i != 0 && src.hasNext()) { + src.next(); + i--; + } + + if (src.hasNext()) { + hasValue = true; + return true; + } + + done = true; + return false; + } + return true; + } + + @Override + public T next() { + if (hasNext()) { + hasValue = false; + return source.next(); + } + throw new NoSuchElementException(); + } + + @Override + public void remove() { + source.remove(); + } + } +} diff --git a/src/main/java/ix/IxOrderedMergeArray.java b/src/main/java/ix/IxOrderedMergeArray.java new file mode 100644 index 0000000..ce895fa --- /dev/null +++ b/src/main/java/ix/IxOrderedMergeArray.java @@ -0,0 +1,142 @@ +/* + * Copyright 2011-2016 David Karnok + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ix; + +import java.util.*; + +/** + * Merges an array of Iterable items by picking the smallest from them + * with the help of a Comparator. + * + * @param the value type + */ +final class IxOrderedMergeArray extends Ix { + + final Iterable[] sources; + + final Comparator comparator; + + IxOrderedMergeArray(Iterable[] sources, Comparator comparator) { + this.sources = sources; + this.comparator = comparator; + } + + @Override + public Iterator iterator() { + Iterable[] all = sources; + int n = all.length; + @SuppressWarnings("unchecked") + Iterator[] srcs = new Iterator[n]; + for (int i = 0; i < n; i++) { + srcs[i] = all[i].iterator(); + } + return new OrderedMergeIterator(srcs, n, comparator); + } + + static final class OrderedMergeIterator implements Iterator { + + final Iterator[] sources; + + final Comparator comparator; + + final int n; + + final Object[] latest; + + static final Object EMPTY = new Object(); + + static final Object DONE = new Object(); + + boolean done; + + int index; + + OrderedMergeIterator(Iterator[] sources, int n, Comparator comparator) { + this.sources = sources; + this.n = n; + this.latest = new Object[n]; + Arrays.fill(latest, EMPTY); + this.comparator = comparator; + this.index = -1; + } + + @SuppressWarnings("unchecked") + @Override + public boolean hasNext() { + int i = index; + if (i < 0) { + if (done) { + return false; + } + int count = n; + Object[] vs = latest; + int d = 0; + int f = -1; + T min = null; + for (int j = 0; j < count; j++) { + Object o = vs[j]; + if (o == DONE) { + d++; + continue; + } else + if (o == EMPTY) { + Iterator src = sources[j]; + if (src.hasNext()) { + o = src.next(); + vs[j] = o; + } else { + d++; + vs[j] = DONE; + continue; + } + } + + if (f < 0 || comparator.compare(min, (T)o) > 0) { + f = j; + min = (T)o; + } + } + + if (d == count) { + done = true; + return false; + } + + index = f; + } + return true; + } + + @Override + public T next() { + if (hasNext()) { + int i = index; + index = -1; + @SuppressWarnings("unchecked") + T v = (T)latest[i]; + latest[i] = EMPTY; + return v; + } + throw new NoSuchElementException(); + } + + @Override + public void remove() { + throw new UnsupportedOperationException(); + } + } +} diff --git a/src/main/java/ix/IxOrderedMergeIterable.java b/src/main/java/ix/IxOrderedMergeIterable.java new file mode 100644 index 0000000..d5af595 --- /dev/null +++ b/src/main/java/ix/IxOrderedMergeIterable.java @@ -0,0 +1,55 @@ +/* + * Copyright 2011-2016 David Karnok + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ix; + +import java.util.*; + +import ix.IxOrderedMergeArray.OrderedMergeIterator; + +/** + * Merges an array of Iterable items by picking the smallest from them + * with the help of a Comparator. + * + * @param the value type + */ +final class IxOrderedMergeIterable extends Ix { + + final Iterable> sources; + + final Comparator comparator; + + IxOrderedMergeIterable(Iterable> sources, Comparator comparator) { + this.sources = sources; + this.comparator = comparator; + } + + @Override + public Iterator iterator() { + @SuppressWarnings("unchecked") + Iterator[] srcs = new Iterator[8]; + int n = 0; + + for (Iterable iter : sources) { + if (n == srcs.length) { + srcs = Arrays.copyOf(srcs, n + (n >> 2)); + } + srcs[n++] = iter.iterator(); + } + + return new OrderedMergeIterator(srcs, n, comparator); + } +} diff --git a/src/main/java/ix/IxReadOnly.java b/src/main/java/ix/IxReadOnly.java new file mode 100644 index 0000000..6850d90 --- /dev/null +++ b/src/main/java/ix/IxReadOnly.java @@ -0,0 +1,90 @@ +/* + * Copyright 2011-2016 David Karnok + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ix; + +import java.util.Iterator; + +/** + * Suppress or throw when the remove() is called. + * + * @param the value type + */ +final class IxReadOnly extends IxSource { + + final boolean silent; + + IxReadOnly(Iterable source, boolean silent) { + super(source); + this.silent = silent; + } + + @Override + public Iterator iterator() { + if (silent) { + return new ReadOnlySilentIterator(source.iterator()); + } + return new ReadOnlyThrowingIterator(source.iterator()); + } + + static final class ReadOnlySilentIterator implements Iterator { + + final Iterator source; + + ReadOnlySilentIterator(Iterator source) { + this.source = source; + } + + @Override + public boolean hasNext() { + return source.hasNext(); + } + + @Override + public T next() { + return source.next(); + } + + @Override + public void remove() { + // deliberately ignored + } + } + + static final class ReadOnlyThrowingIterator implements Iterator { + + final Iterator source; + + ReadOnlyThrowingIterator(Iterator source) { + this.source = source; + } + + @Override + public boolean hasNext() { + return source.hasNext(); + } + + @Override + public T next() { + return source.next(); + } + + @Override + public void remove() { + throw new UnsupportedOperationException(); + } + } +} diff --git a/src/main/java/ix/IxRepeat.java b/src/main/java/ix/IxRepeat.java index c06f8f0..a30b998 100644 --- a/src/main/java/ix/IxRepeat.java +++ b/src/main/java/ix/IxRepeat.java @@ -18,7 +18,7 @@ import java.util.Iterator; -final class IxRepeat extends Ix { +final class IxRepeat extends Ix implements Iterator { final T value; @@ -28,30 +28,21 @@ final class IxRepeat extends Ix { @Override public Iterator iterator() { - return new RepeatIterator(value); + return this; } - static final class RepeatIterator implements Iterator { - - final T value; - - RepeatIterator(T value) { - this.value = value; - } - - @Override - public boolean hasNext() { - return true; - } + @Override + public boolean hasNext() { + return true; + } - @Override - public T next() { - return value; - } + @Override + public T next() { + return value; + } - @Override - public void remove() { - throw new UnsupportedOperationException(); - } + @Override + public void remove() { + throw new UnsupportedOperationException(); } } diff --git a/src/main/java/ix/IxRepeatCallable.java b/src/main/java/ix/IxRepeatCallable.java new file mode 100644 index 0000000..1587466 --- /dev/null +++ b/src/main/java/ix/IxRepeatCallable.java @@ -0,0 +1,54 @@ +/* + * Copyright 2011-2016 David Karnok + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ix; + +import java.util.Iterator; +import java.util.concurrent.Callable; + +/** + * Repeatedly call a Callable indefinitely. + * + * @param the value type + */ +final class IxRepeatCallable extends Ix implements Iterator { + + final Callable callable; + + IxRepeatCallable(Callable callable) { + this.callable = callable; + } + + @Override + public Iterator iterator() { + return this; + } + + @Override + public boolean hasNext() { + return true; + } + + @Override + public T next() { + return checkedCall(callable); + } + + @Override + public void remove() { + throw new UnsupportedOperationException(); + } +} diff --git a/src/test/java/ix/BufferPredicateTest.java b/src/test/java/ix/BufferPredicateTest.java new file mode 100644 index 0000000..c71f4dd --- /dev/null +++ b/src/test/java/ix/BufferPredicateTest.java @@ -0,0 +1,153 @@ +/* + * Copyright 2011-2016 David Karnok + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ix; + +import java.util.*; + +import org.junit.Test; + +public class BufferPredicateTest { + + @SuppressWarnings("unchecked") + @Test + public void splitNormal() { + Ix> source = Ix.fromArray(1, 2, 10, 3, 10, 4) + .bufferSplit(new IxPredicate() { + @Override + public boolean test(Integer v) { + return v == 10; + } + }); + + IxTestHelper.assertValues(source, Arrays.asList(1, 2), Arrays.asList(3), Arrays.asList(4)); + IxTestHelper.assertNoRemove(source); + } + + @SuppressWarnings("unchecked") + @Test + public void splitNormalEmpty() { + Ix> source = Ix.fromArray(1, 2, 10, 10) + .bufferSplit(new IxPredicate() { + @Override + public boolean test(Integer v) { + return v == 10; + } + }); + + IxTestHelper.assertValues(source, Arrays.asList(1, 2), Arrays.asList()); + IxTestHelper.assertNoRemove(source); + } + + @SuppressWarnings("unchecked") + @Test + public void whileNormal() { + Ix> source = Ix.fromArray(1, 2, 10, 3, 10, 4) + .bufferWhile(new IxPredicate() { + @Override + public boolean test(Integer v) { + return v != 10; + } + }); + + IxTestHelper.assertValues(source, Arrays.asList(1, 2), Arrays.asList(10, 3), Arrays.asList(10, 4)); + IxTestHelper.assertNoRemove(source); + } + + @SuppressWarnings("unchecked") + @Test + public void whileNormalEmpty() { + Ix> source = Ix.fromArray(1, 2, 10, 10) + .bufferWhile(new IxPredicate() { + @Override + public boolean test(Integer v) { + return v != 10; + } + }); + + IxTestHelper.assertValues(source, Arrays.asList(1, 2), Arrays.asList(10), Arrays.asList(10)); + IxTestHelper.assertNoRemove(source); + } + + @SuppressWarnings("unchecked") + @Test + public void untilNormal() { + Ix> source = Ix.fromArray(1, 2, 10, 3, 10, 4) + .bufferUntil(new IxPredicate() { + @Override + public boolean test(Integer v) { + return v == 10; + } + }); + + IxTestHelper.assertValues(source, Arrays.asList(1, 2, 10), Arrays.asList(3, 10), Arrays.asList(4)); + IxTestHelper.assertNoRemove(source); + } + + @SuppressWarnings("unchecked") + @Test + public void untilNormalEmpty() { + Ix> source = Ix.fromArray(1, 2, 10, 10) + .bufferUntil(new IxPredicate() { + @Override + public boolean test(Integer v) { + return v == 10; + } + }); + + IxTestHelper.assertValues(source, Arrays.asList(1, 2, 10), Arrays.asList(10)); + IxTestHelper.assertNoRemove(source); + } + + @SuppressWarnings("unchecked") + @Test + public void splitEmpty() { + Ix> source = Ix.empty().bufferSplit(new IxPredicate() { + @Override + public boolean test(Integer v) { + return v == 10; + } + }); + + IxTestHelper.assertValues(source); + } + + @SuppressWarnings("unchecked") + @Test + public void whileEmpty() { + Ix> source = Ix.empty().bufferWhile(new IxPredicate() { + @Override + public boolean test(Integer v) { + return v != 10; + } + }); + + IxTestHelper.assertValues(source); + } + + @SuppressWarnings("unchecked") + @Test + public void untilEmpty() { + Ix> source = Ix.empty().bufferUntil(new IxPredicate() { + @Override + public boolean test(Integer v) { + return v == 10; + } + }); + + IxTestHelper.assertValues(source); + } +} diff --git a/src/test/java/ix/EveryTest.java b/src/test/java/ix/EveryTest.java new file mode 100644 index 0000000..b8f2b06 --- /dev/null +++ b/src/test/java/ix/EveryTest.java @@ -0,0 +1,62 @@ +/* + * Copyright 2011-2016 David Karnok + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ix; + +import java.util.*; + +import org.junit.*; + +public class EveryTest { + + @Test + public void normal() { + Ix source = Ix.range(1, 5).every(2); + + IxTestHelper.assertValues(source, 2, 4); + IxTestHelper.assertNoRemove(source); + } + + @Test + public void normal2() { + Ix source = Ix.range(1, 5).every(1); + + IxTestHelper.assertValues(source, 1, 2, 3, 4, 5); + IxTestHelper.assertNoRemove(source); + } + + @Test + public void normal3() { + Ix source = Ix.range(1, 5).every(10); + + IxTestHelper.assertValues(source); + IxTestHelper.assertNoRemove(source); + } + + @Test + public void remove() { + List list = new ArrayList(); + list.add(1); + list.add(2); + list.add(3); + list.add(4); + list.add(5); + + Ix.from(list).every(2).removeAll(); + + Assert.assertEquals(Arrays.asList(1, 3, 5), list); + } +} diff --git a/src/test/java/ix/OrderedMergeTest.java b/src/test/java/ix/OrderedMergeTest.java new file mode 100644 index 0000000..4038293 --- /dev/null +++ b/src/test/java/ix/OrderedMergeTest.java @@ -0,0 +1,105 @@ +/* + * Copyright 2011-2016 David Karnok + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ix; + +import java.util.Comparator; + +import org.junit.Test; + +public class OrderedMergeTest { + + @Test + public void normalArray() { + @SuppressWarnings("unchecked") + Ix source = Ix.orderedMergeArray(Ix.fromArray(1, 3), Ix.fromArray(2, 4, 5)); + + IxTestHelper.assertValues(source, 1, 2, 3, 4, 5); + IxTestHelper.assertNoRemove(source); + } + + @Test + public void normalIterable() { + @SuppressWarnings("unchecked") + Ix source = Ix.orderedMerge(Ix.fromArray(Ix.fromArray(1, 3), Ix.fromArray(2, 4, 5))); + + IxTestHelper.assertValues(source, 1, 2, 3, 4, 5); + IxTestHelper.assertNoRemove(source); + } + + @Test + @SuppressWarnings("unchecked") + public void firstEmptyArray() { + Ix source = Ix.orderedMergeArray(Ix.empty(), Ix.fromArray(2, 4, 5)); + + IxTestHelper.assertValues(source, 2, 4, 5); + } + + @Test + @SuppressWarnings("unchecked") + public void secondEmptyArray() { + Ix source = Ix.orderedMergeArray(Ix.fromArray(1, 3), Ix.empty()); + + IxTestHelper.assertValues(source, 1, 3); + } + + @Test + @SuppressWarnings("unchecked") + public void bothEmptyArray() { + Ix source = Ix.orderedMergeArray(Ix.empty(), Ix.empty()); + + IxTestHelper.assertValues(source); + } + + @Test + public void comparatorArray() { + @SuppressWarnings("unchecked") + Ix source = Ix.orderedMergeArray( + new Comparator() { + @Override + public int compare(Integer o1, Integer o2) { + return o2.compareTo(o1); + } + }, + Ix.fromArray(3, 1), Ix.fromArray(5, 4, 2)); + + IxTestHelper.assertValues(source, 5, 4, 3, 2, 1); + IxTestHelper.assertNoRemove(source); + } + + @Test + public void comparatorIterable() { + @SuppressWarnings("unchecked") + Ix source = Ix.orderedMerge(Ix.fromArray(Ix.fromArray(3, 1), Ix.fromArray(5, 4, 2)), + new Comparator() { + @Override + public int compare(Integer o1, Integer o2) { + return o2.compareTo(o1); + } + } + ); + + IxTestHelper.assertValues(source, 5, 4, 3, 2, 1); + IxTestHelper.assertNoRemove(source); + } + + @Test + public void lotsOfIterables() { + Ix source = Ix.orderedMerge(Ix.repeatValue(Ix.just(1), 30)).sumInt(); + + IxTestHelper.assertValues(source, 30); + } +} diff --git a/src/test/java/ix/ReadOnlyTest.java b/src/test/java/ix/ReadOnlyTest.java new file mode 100644 index 0000000..98384ab --- /dev/null +++ b/src/test/java/ix/ReadOnlyTest.java @@ -0,0 +1,57 @@ +/* + * Copyright 2011-2016 David Karnok + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ix; + +import java.util.*; + +import org.junit.*; + +public class ReadOnlyTest { + + @Test + public void normal() { + List list = new ArrayList(); + list.add(1); + list.add(2); + list.add(3); + + Ix source = Ix.from(list).readOnly(); + + IxTestHelper.assertValues(source, 1, 2, 3); + IxTestHelper.assertNoRemove(source); + + Assert.assertEquals(3, list.size()); + } + + @Test + public void normalSilent() { + List list = new ArrayList(); + list.add(1); + list.add(2); + list.add(3); + + Ix source = Ix.from(list).readOnly(true); + + IxTestHelper.assertValues(source, 1, 2, 3); + + source.removeAll(); + + Assert.assertEquals(3, list.size()); + + IxTestHelper.assertValues(source, 1, 2, 3); + } +} diff --git a/src/test/java/ix/RepeatTest.java b/src/test/java/ix/RepeatTest.java index 0f9da8a..e3c8ee7 100644 --- a/src/test/java/ix/RepeatTest.java +++ b/src/test/java/ix/RepeatTest.java @@ -16,6 +16,8 @@ package ix; +import java.util.concurrent.Callable; + import org.junit.Test; public class RepeatTest { @@ -237,4 +239,19 @@ public boolean getAsBoolean() { IxTestHelper.assertNoRemove(source); } + + @Test + public void repeatCallable() { + Ix source = Ix.repeatCallable(new Callable() { + @Override + public Integer call() throws Exception { + return 1; + } + }) + .take(5); + + IxTestHelper.assertValues(source, 1, 1, 1, 1, 1); + + IxTestHelper.assertNoRemove(source); + } } From 710d96177cfba3a1a0c44d3179a2af40083a5b29 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?D=C3=A1vid=20Karnok?= Date: Mon, 2 Jan 2017 17:04:15 +0100 Subject: [PATCH 45/66] Ignore .idea subfolder --- .gitignore | 39 ++++++++++++++++++++------------------- 1 file changed, 20 insertions(+), 19 deletions(-) diff --git a/.gitignore b/.gitignore index e3779c2..e7611fb 100644 --- a/.gitignore +++ b/.gitignore @@ -1,21 +1,22 @@ -*.class - -# Package Files # -*.jar -*.war -*.ear -/build/ - -.gradle -.m2 +*.class + +# Package Files # +*.jar +*.war +*.ear +/build/ + +.gradle +.m2 /.nb-gradle/ /bin/ -.settings/ -.nb-gradle-properties -.classpath -.project -.settings -.metadata -.checkstyle -bin/ -!/gradle/wrapper/gradle-wrapper.jar \ No newline at end of file +.settings/ +.nb-gradle-properties +.classpath +.project +.settings +.metadata +.checkstyle +bin/ +!/gradle/wrapper/gradle-wrapper.jar +.idea \ No newline at end of file From 9f80fad10423bd5d2c639f775c215f2d00a7f28c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?D=C3=A1vid=20Karnok?= Date: Mon, 2 Jan 2017 17:05:27 +0100 Subject: [PATCH 46/66] Delete .idea folder --- .idea/compiler.xml | 27 - .idea/copyright/profiles_settings.xml | 3 - .idea/dictionaries/akarnokd.xml | 8 - .idea/gradle.xml | 17 - .idea/inspectionProfiles/Project_Default.xml | 14 - .../inspectionProfiles/profiles_settings.xml | 7 - .idea/libraries/Gradle__junit_junit_4_12.xml | 11 - ...le__net_sf_jopt_simple_jopt_simple_4_6.xml | 11 - ...__org_apache_commons_commons_math3_3_2.xml | 11 - ...Gradle__org_hamcrest_hamcrest_core_1_3.xml | 11 - .../Gradle__org_openjdk_jmh_jmh_core_1_14.xml | 11 - ...njdk_jmh_jmh_generator_annprocess_1_14.xml | 11 - .idea/misc.xml | 19 - .idea/modules.xml | 11 - .idea/modules/ixjava.iml | 12 - .idea/modules/ixjava_jmh.iml | 18 - .idea/modules/ixjava_main.iml | 13 - .idea/modules/ixjava_test.iml | 17 - .idea/workspace.xml | 1719 ----------------- 19 files changed, 1951 deletions(-) delete mode 100644 .idea/compiler.xml delete mode 100644 .idea/copyright/profiles_settings.xml delete mode 100644 .idea/dictionaries/akarnokd.xml delete mode 100644 .idea/gradle.xml delete mode 100644 .idea/inspectionProfiles/Project_Default.xml delete mode 100644 .idea/inspectionProfiles/profiles_settings.xml delete mode 100644 .idea/libraries/Gradle__junit_junit_4_12.xml delete mode 100644 .idea/libraries/Gradle__net_sf_jopt_simple_jopt_simple_4_6.xml delete mode 100644 .idea/libraries/Gradle__org_apache_commons_commons_math3_3_2.xml delete mode 100644 .idea/libraries/Gradle__org_hamcrest_hamcrest_core_1_3.xml delete mode 100644 .idea/libraries/Gradle__org_openjdk_jmh_jmh_core_1_14.xml delete mode 100644 .idea/libraries/Gradle__org_openjdk_jmh_jmh_generator_annprocess_1_14.xml delete mode 100644 .idea/misc.xml delete mode 100644 .idea/modules.xml delete mode 100644 .idea/modules/ixjava.iml delete mode 100644 .idea/modules/ixjava_jmh.iml delete mode 100644 .idea/modules/ixjava_main.iml delete mode 100644 .idea/modules/ixjava_test.iml delete mode 100644 .idea/workspace.xml diff --git a/.idea/compiler.xml b/.idea/compiler.xml deleted file mode 100644 index 8cbd3f4..0000000 --- a/.idea/compiler.xml +++ /dev/null @@ -1,27 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/copyright/profiles_settings.xml b/.idea/copyright/profiles_settings.xml deleted file mode 100644 index e7bedf3..0000000 --- a/.idea/copyright/profiles_settings.xml +++ /dev/null @@ -1,3 +0,0 @@ - - - \ No newline at end of file diff --git a/.idea/dictionaries/akarnokd.xml b/.idea/dictionaries/akarnokd.xml deleted file mode 100644 index 0e1ac72..0000000 --- a/.idea/dictionaries/akarnokd.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - forloop - karnok - - - \ No newline at end of file diff --git a/.idea/gradle.xml b/.idea/gradle.xml deleted file mode 100644 index 77e9972..0000000 --- a/.idea/gradle.xml +++ /dev/null @@ -1,17 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml deleted file mode 100644 index fd947e6..0000000 --- a/.idea/inspectionProfiles/Project_Default.xml +++ /dev/null @@ -1,14 +0,0 @@ - - - - \ No newline at end of file diff --git a/.idea/inspectionProfiles/profiles_settings.xml b/.idea/inspectionProfiles/profiles_settings.xml deleted file mode 100644 index 3b31283..0000000 --- a/.idea/inspectionProfiles/profiles_settings.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - - \ No newline at end of file diff --git a/.idea/libraries/Gradle__junit_junit_4_12.xml b/.idea/libraries/Gradle__junit_junit_4_12.xml deleted file mode 100644 index 04c10dd..0000000 --- a/.idea/libraries/Gradle__junit_junit_4_12.xml +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/libraries/Gradle__net_sf_jopt_simple_jopt_simple_4_6.xml b/.idea/libraries/Gradle__net_sf_jopt_simple_jopt_simple_4_6.xml deleted file mode 100644 index d1405f7..0000000 --- a/.idea/libraries/Gradle__net_sf_jopt_simple_jopt_simple_4_6.xml +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/libraries/Gradle__org_apache_commons_commons_math3_3_2.xml b/.idea/libraries/Gradle__org_apache_commons_commons_math3_3_2.xml deleted file mode 100644 index 75cc803..0000000 --- a/.idea/libraries/Gradle__org_apache_commons_commons_math3_3_2.xml +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/libraries/Gradle__org_hamcrest_hamcrest_core_1_3.xml b/.idea/libraries/Gradle__org_hamcrest_hamcrest_core_1_3.xml deleted file mode 100644 index 8262f72..0000000 --- a/.idea/libraries/Gradle__org_hamcrest_hamcrest_core_1_3.xml +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/libraries/Gradle__org_openjdk_jmh_jmh_core_1_14.xml b/.idea/libraries/Gradle__org_openjdk_jmh_jmh_core_1_14.xml deleted file mode 100644 index 47c0ab7..0000000 --- a/.idea/libraries/Gradle__org_openjdk_jmh_jmh_core_1_14.xml +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/libraries/Gradle__org_openjdk_jmh_jmh_generator_annprocess_1_14.xml b/.idea/libraries/Gradle__org_openjdk_jmh_jmh_generator_annprocess_1_14.xml deleted file mode 100644 index e8189c8..0000000 --- a/.idea/libraries/Gradle__org_openjdk_jmh_jmh_generator_annprocess_1_14.xml +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml deleted file mode 100644 index b29bc37..0000000 --- a/.idea/misc.xml +++ /dev/null @@ -1,19 +0,0 @@ - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml deleted file mode 100644 index 63705b8..0000000 --- a/.idea/modules.xml +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/modules/ixjava.iml b/.idea/modules/ixjava.iml deleted file mode 100644 index fac74e1..0000000 --- a/.idea/modules/ixjava.iml +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/modules/ixjava_jmh.iml b/.idea/modules/ixjava_jmh.iml deleted file mode 100644 index 30f5371..0000000 --- a/.idea/modules/ixjava_jmh.iml +++ /dev/null @@ -1,18 +0,0 @@ - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/modules/ixjava_main.iml b/.idea/modules/ixjava_main.iml deleted file mode 100644 index 29a46d3..0000000 --- a/.idea/modules/ixjava_main.iml +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/modules/ixjava_test.iml b/.idea/modules/ixjava_test.iml deleted file mode 100644 index 7ec8692..0000000 --- a/.idea/modules/ixjava_test.iml +++ /dev/null @@ -1,17 +0,0 @@ - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/workspace.xml b/.idea/workspace.xml deleted file mode 100644 index 8e90062..0000000 --- a/.idea/workspace.xml +++ /dev/null @@ -1,1719 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - true - DEFINITION_ORDER - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1473888618399 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - No facets are configured - - - - - - - - - - - - - - - 1.8 - - - - - - - - ixjava - - - - - - - - 1.8 - - - - - - - - Gradle: junit:junit:4.12 - - - - - - - - \ No newline at end of file From abc5d0d36e208d1f8b149382a18ebb968a1afd6a Mon Sep 17 00:00:00 2001 From: akarnokd Date: Thu, 19 Jan 2017 21:56:16 +0100 Subject: [PATCH 47/66] Upgrade to JMH 1.17.4 --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index e17625a..193e819 100644 --- a/build.gradle +++ b/build.gradle @@ -87,7 +87,7 @@ publishing { } jmh { - jmhVersion = '1.14' + jmhVersion = '1.17.4' humanOutputFile = null if (project.hasProperty('jmh')) { include = ".*" + project.jmh + ".*" From 667c97b5dab1f846fc64b346ded7e97460c3e70c Mon Sep 17 00:00:00 2001 From: David Karnok Date: Fri, 8 Sep 2017 23:18:23 +0200 Subject: [PATCH 48/66] Use JDK 8 --- .travis.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 815a6f7..3ac1fd3 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,7 +1,7 @@ language: java jdk: - - oraclejdk7 + - oraclejdk8 before_install: - chmod +x gradlew @@ -14,4 +14,4 @@ cache: directories: - $HOME/.m2 - $HOME/.gradle - \ No newline at end of file + From 01debe2ef72eca32f03292351a0f2c601b6dfbc6 Mon Sep 17 00:00:00 2001 From: David Karnok Date: Fri, 20 Oct 2017 10:46:22 +0200 Subject: [PATCH 49/66] Update README.md --- README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 9b661be..4d038d4 100644 --- a/README.md +++ b/README.md @@ -5,10 +5,10 @@ ixjava [![codecov.io](http://codecov.io/github/akarnokd/ixjava/coverage.svg?branch=1.x)](http://codecov.io/github/akarnokd/ixjava?branch=1.x) [![Maven Central](https://maven-badges.herokuapp.com/maven-central/com.github.akarnokd/ixjava/badge.svg)](https://maven-badges.herokuapp.com/maven-central/com.github.akarnokd/ixjava) -Iterable Extensions for Java, the dual of RxJava. Originally implemented in the Reactive4Java framework, now converted to work with RxJava. +Iterable Extensions for Java, the dual of RxJava. Originally implemented in the Reactive4Java framework, now standalone; no dependencies on any reactive library. The aim is to provide, lazily evaluated, pull-based datastream support with the same naming as in RxJava mainly for the pre-Java-8 world. The Stream API in Java 8 is not exactly the same thing because Streams can be only consumed once while `Iterable`s can be consumed many times. Google Guava features a lot of Iterable operators, plus now they have the `FluentIterable` with similar setup -but far less operators available (and as of v19, their performance is 2x worse than Ix'). +but far less operators available. **This branch starts from scratch by reimplementing `ix.Ix` and all of its operators based on the +5 year experience with reactive and interactive dataflows.** @@ -19,7 +19,7 @@ and interactive dataflows.** ```groovy dependencies { - compile 'com.github.akarnokd:ixjava:1.0.0-RC5' + compile 'com.github.akarnokd:ixjava:1.0.0' } ``` @@ -27,7 +27,7 @@ dependencies { ```xml - + ``` From add721bba550c36541faa450e40a975bb65e78d7 Mon Sep 17 00:00:00 2001 From: akarnokd Date: Fri, 20 Oct 2017 10:48:52 +0200 Subject: [PATCH 50/66] Release 1.0.0 --- build.gradle | 4 ++-- gradle.properties | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/build.gradle b/build.gradle index 193e819..3582b30 100644 --- a/build.gradle +++ b/build.gradle @@ -121,7 +121,7 @@ license { } jacoco { - toolVersion = '0.7.7.201606060606' // See http://www.eclemma.org/jacoco/. + toolVersion = '0.7.9' // See http://www.eclemma.org/jacoco/. } jacocoTestReport { @@ -171,5 +171,5 @@ build.dependsOn pmdPrint check.dependsOn pmdPrint animalsniffer { - annotation = 'rx.internal.util.SuppressAnimalSniffer' + annotation = 'ix.SuppressAnimalSniffer' } diff --git a/gradle.properties b/gradle.properties index d4591bd..aef125e 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1 +1 @@ -version=1.0.0-RC5 +version=1.0.0 From c472500bf35cbef92cd510757ed46b91c5b1e522 Mon Sep 17 00:00:00 2001 From: akarnokd Date: Thu, 21 Nov 2019 11:57:24 +0100 Subject: [PATCH 51/66] Add Javadoc pushback --- .travis.yml | 1 + README.md | 12 +++-------- push.sh | 58 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 62 insertions(+), 9 deletions(-) create mode 100644 push.sh diff --git a/.travis.yml b/.travis.yml index 3ac1fd3..a7d03e2 100644 --- a/.travis.yml +++ b/.travis.yml @@ -8,6 +8,7 @@ before_install: after_success: - bash <(curl -s https://codecov.io/bash) + - bash ./push.sh # cache between builds cache: diff --git a/README.md b/README.md index 4d038d4..796f8f0 100644 --- a/README.md +++ b/README.md @@ -15,22 +15,16 @@ and interactive dataflows.** # Releases +Javadoc: https://akarnokd.github.com/ixjava/javadoc/index.html + **gradle** ```groovy dependencies { - compile 'com.github.akarnokd:ixjava:1.0.0' + implementation 'com.github.akarnokd:ixjava:1.0.0' } ``` -**ivy** - -```xml - - - -``` - Maven search: [http://search.maven.org](http://search.maven.org/#search%7Cga%7C1%7Cg%3A%22com.github.akarnokd%22) diff --git a/push.sh b/push.sh new file mode 100644 index 0000000..22fbe24 --- /dev/null +++ b/push.sh @@ -0,0 +1,58 @@ +#!/bin/bash +# ---------------------------------------------------------- +# Automatically push back the generated JavaDocs to gh-pages +# ---------------------------------------------------------- +# based on https://gist.github.com/willprice/e07efd73fb7f13f917ea + +# specify the common address for the repository +targetRepo=github.com/akarnokd/ixjava.git +# ======================================================================= + +# only for main pushes, for now +# if [ "$TRAVIS_PULL_REQUEST" == "true" ] || [ "$TRAVIS_TAG" == "" ]; then +if [ "$TRAVIS_PULL_REQUEST" == "true" ]; then + echo -e "Pull request detected, skipping JavaDocs pushback." + exit 0 +fi + +# check if the token is actually there +if [ "$GITHUB_TOKEN" == "" ]; then + echo -e "No access to GitHub, skipping JavaDocs pushback." + exit 0 +fi + +# prepare the git information +git config --global user.email "travis@travis-ci.org" +git config --global user.name "Travis CI" + +# setup the remote +git remote add origin-pages https://${GITHUB_TOKEN}@${targetRepo} > /dev/null 2>&1 + +# stash changes due to chmod +git stash + +# get the gh-pages +git fetch --all +git branch -a +git checkout -b gh-pages origin-pages/gh-pages + +# remove old dir +rm -rf javadoc + +# copy and overwrite new doc +yes | cp -rfv ./build/docs/javadoc/ javadoc/ + +# stage all changed and new files +git add *.html +git add *.css +git add *.js +git add javadoc/package-list + +# commit all +git commit --message "Travis build: $TRAVIS_BUILD_NUMBER" + + +# push it +git push --quiet --set-upstream origin-pages gh-pages + +# we are done From 1dd57aab4bcd6fe12d97965eb9a05be2245cc23a Mon Sep 17 00:00:00 2001 From: akarnokd Date: Thu, 21 Nov 2019 11:59:52 +0100 Subject: [PATCH 52/66] Use openjdk 8 --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index a7d03e2..d6a3f1e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,7 +1,7 @@ language: java jdk: - - oraclejdk8 + - openjdk8 before_install: - chmod +x gradlew From 79a2e109d6c16ca90f2712faeae9e8323b3e8920 Mon Sep 17 00:00:00 2001 From: akarnokd Date: Thu, 21 Nov 2019 12:08:17 +0100 Subject: [PATCH 53/66] Trigger javadoc --- .travis.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index d6a3f1e..fa63c80 100644 --- a/.travis.yml +++ b/.travis.yml @@ -15,4 +15,3 @@ cache: directories: - $HOME/.m2 - $HOME/.gradle - From 1f84957ca33e553515b588ec685098e052f566df Mon Sep 17 00:00:00 2001 From: akarnokd Date: Thu, 21 Nov 2019 13:10:55 +0100 Subject: [PATCH 54/66] Try git add again --- push.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/push.sh b/push.sh index 22fbe24..10d2c1e 100644 --- a/push.sh +++ b/push.sh @@ -43,10 +43,10 @@ rm -rf javadoc yes | cp -rfv ./build/docs/javadoc/ javadoc/ # stage all changed and new files -git add *.html -git add *.css -git add *.js -git add javadoc/package-list +git add *.html --verbose +git add *.css --verbose +git add *.js --verbose +git add javadoc/package-list --verbose # commit all git commit --message "Travis build: $TRAVIS_BUILD_NUMBER" From 79a2b3de92f471770f5f7d2acebcffd1fd476a30 Mon Sep 17 00:00:00 2001 From: akarnokd Date: Thu, 21 Nov 2019 13:18:02 +0100 Subject: [PATCH 55/66] Git add all --- push.sh | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/push.sh b/push.sh index 10d2c1e..5e9bd50 100644 --- a/push.sh +++ b/push.sh @@ -43,10 +43,11 @@ rm -rf javadoc yes | cp -rfv ./build/docs/javadoc/ javadoc/ # stage all changed and new files -git add *.html --verbose -git add *.css --verbose -git add *.js --verbose -git add javadoc/package-list --verbose +git add --all --verbose +#git add *.html --verbose +#git add *.css --verbose +#git add *.js --verbose +#git add javadoc/package-list --verbose # commit all git commit --message "Travis build: $TRAVIS_BUILD_NUMBER" From 55b662eb4e810321f35c411dd60079e0e300ca2e Mon Sep 17 00:00:00 2001 From: akarnokd Date: Thu, 21 Nov 2019 13:22:32 +0100 Subject: [PATCH 56/66] Add standard java links to the javadoc --- build.gradle | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/build.gradle b/build.gradle index 3582b30..79c1fe2 100644 --- a/build.gradle +++ b/build.gradle @@ -102,6 +102,10 @@ plugins.withType(EclipsePlugin) { javadoc { failOnError = false + options.links( + "https://docs.oracle.com/javase/7/docs/api/" + ) + } test { From 223b4d584b00234676c8da90333bdc1ecd09dc20 Mon Sep 17 00:00:00 2001 From: David Karnok Date: Thu, 29 Oct 2020 08:46:08 +0100 Subject: [PATCH 57/66] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 796f8f0..0f73330 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ ixjava ================= - + [![codecov.io](http://codecov.io/github/akarnokd/ixjava/coverage.svg?branch=1.x)](http://codecov.io/github/akarnokd/ixjava?branch=1.x) [![Maven Central](https://maven-badges.herokuapp.com/maven-central/com.github.akarnokd/ixjava/badge.svg)](https://maven-badges.herokuapp.com/maven-central/com.github.akarnokd/ixjava) From e556051bc78ac9446731dd5df708f4dd63672c2a Mon Sep 17 00:00:00 2001 From: David Karnok Date: Fri, 20 Nov 2020 14:57:53 +0100 Subject: [PATCH 58/66] Create gradle.yml --- .github/workflows/gradle.yml | 41 ++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100644 .github/workflows/gradle.yml diff --git a/.github/workflows/gradle.yml b/.github/workflows/gradle.yml new file mode 100644 index 0000000..ed571a2 --- /dev/null +++ b/.github/workflows/gradle.yml @@ -0,0 +1,41 @@ +# This workflow will build a Java project with Gradle +# For more information see: https://help.github.com/actions/language-and-framework-guides/building-and-testing-java-with-gradle + +name: Java CI with Gradle + +on: + push: + branches: [ 1.x ] + pull_request: + branches: [ 1.x ] + +jobs: + build: + + runs-on: ubuntu-latest + env: + TRAVIS_PULL_REQUEST: ${{ github.event.number }} + JAVADOCS_TOKEN: ${{ secrets.JAVADOCS_TOKEN }} + TRAVIS_BUILD_NUMBER: $GITHUB_RUN_NUMBER + steps: + - uses: actions/checkout@v2 + - name: Set up JDK 1.8 + uses: actions/setup-java@v1 + with: + java-version: 1.8 + - name: Cache Gradle packages + uses: actions/cache@v2 + with: + path: ~/.gradle/caches + key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle') }} + restore-keys: ${{ runner.os }}-gradle + - name: Grant execute permission for gradlew + run: chmod +x gradlew + - name: Grant execute permission for push + run: chmod +x push.sh + - name: Build with Gradle + run: ./gradlew build --stacktrace + - name: Upload to Codecov + uses: codecov/codecov-action@v1 + - name: Push Javadocs + run: ./push.sh From 18239bef377a8a409787759f8cc5508bd9b059b7 Mon Sep 17 00:00:00 2001 From: David Karnok Date: Fri, 20 Nov 2020 14:59:03 +0100 Subject: [PATCH 59/66] Create gradle-wrapper-validation.yml --- .github/workflows/gradle-wrapper-validation.yml | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 .github/workflows/gradle-wrapper-validation.yml diff --git a/.github/workflows/gradle-wrapper-validation.yml b/.github/workflows/gradle-wrapper-validation.yml new file mode 100644 index 0000000..405a2b3 --- /dev/null +++ b/.github/workflows/gradle-wrapper-validation.yml @@ -0,0 +1,10 @@ +name: "Validate Gradle Wrapper" +on: [push, pull_request] + +jobs: + validation: + name: "Validation" + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - uses: gradle/wrapper-validation-action@v1 From 70d7bca49a8a74b54d0fdd2473859e4367dcf24c Mon Sep 17 00:00:00 2001 From: David Karnok Date: Fri, 20 Nov 2020 15:00:37 +0100 Subject: [PATCH 60/66] Update push.sh --- push.sh | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/push.sh b/push.sh index 5e9bd50..83054b4 100644 --- a/push.sh +++ b/push.sh @@ -9,24 +9,23 @@ targetRepo=github.com/akarnokd/ixjava.git # ======================================================================= # only for main pushes, for now -# if [ "$TRAVIS_PULL_REQUEST" == "true" ] || [ "$TRAVIS_TAG" == "" ]; then -if [ "$TRAVIS_PULL_REQUEST" == "true" ]; then +if [ "$CI_PULL_REQUEST" == "true" ]; then echo -e "Pull request detected, skipping JavaDocs pushback." exit 0 fi # check if the token is actually there -if [ "$GITHUB_TOKEN" == "" ]; then +if [ "$JAVADOCS_TOKEN" == "" ]; then echo -e "No access to GitHub, skipping JavaDocs pushback." exit 0 fi # prepare the git information -git config --global user.email "travis@travis-ci.org" -git config --global user.name "Travis CI" +git config --global user.email "akarnokd@gmail.com" +git config --global user.name "akarnokd" # setup the remote -git remote add origin-pages https://${GITHUB_TOKEN}@${targetRepo} > /dev/null 2>&1 +git remote add origin-pages https://${JAVADOCS_TOKEN}@${targetRepo} > /dev/null 2>&1 # stash changes due to chmod git stash @@ -50,7 +49,7 @@ git add --all --verbose #git add javadoc/package-list --verbose # commit all -git commit --message "Travis build: $TRAVIS_BUILD_NUMBER" +git commit --message "CI build: $CI_BUILD_NUMBER" # push it From 8926954033aa0cca3b0a129b22c764e06b69475e Mon Sep 17 00:00:00 2001 From: David Karnok Date: Fri, 20 Nov 2020 15:02:11 +0100 Subject: [PATCH 61/66] Update gradle.yml --- .github/workflows/gradle.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/gradle.yml b/.github/workflows/gradle.yml index ed571a2..67e77d4 100644 --- a/.github/workflows/gradle.yml +++ b/.github/workflows/gradle.yml @@ -14,9 +14,9 @@ jobs: runs-on: ubuntu-latest env: - TRAVIS_PULL_REQUEST: ${{ github.event.number }} + CI_PULL_REQUEST: ${{ github.event.number }} JAVADOCS_TOKEN: ${{ secrets.JAVADOCS_TOKEN }} - TRAVIS_BUILD_NUMBER: $GITHUB_RUN_NUMBER + CI_BUILD_NUMBER: $GITHUB_RUN_NUMBER steps: - uses: actions/checkout@v2 - name: Set up JDK 1.8 From 88e75121104cf564cf1ef8e208cf09b0d1053633 Mon Sep 17 00:00:00 2001 From: David Karnok Date: Fri, 20 Nov 2020 15:07:26 +0100 Subject: [PATCH 62/66] Update gradle.yml --- .github/workflows/gradle.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/gradle.yml b/.github/workflows/gradle.yml index 67e77d4..795e26e 100644 --- a/.github/workflows/gradle.yml +++ b/.github/workflows/gradle.yml @@ -16,7 +16,7 @@ jobs: env: CI_PULL_REQUEST: ${{ github.event.number }} JAVADOCS_TOKEN: ${{ secrets.JAVADOCS_TOKEN }} - CI_BUILD_NUMBER: $GITHUB_RUN_NUMBER + CI_BUILD_NUMBER: ${{ github.run_number }} steps: - uses: actions/checkout@v2 - name: Set up JDK 1.8 From acd688dc902624d9104263f7713d32233e145d10 Mon Sep 17 00:00:00 2001 From: David Karnok Date: Wed, 25 Nov 2020 09:10:19 +0100 Subject: [PATCH 63/66] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 0f73330..86d0d5a 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ ixjava ================= - + [![codecov.io](http://codecov.io/github/akarnokd/ixjava/coverage.svg?branch=1.x)](http://codecov.io/github/akarnokd/ixjava?branch=1.x) [![Maven Central](https://maven-badges.herokuapp.com/maven-central/com.github.akarnokd/ixjava/badge.svg)](https://maven-badges.herokuapp.com/maven-central/com.github.akarnokd/ixjava) From 90ff3f6ea46c91a2d30d474e50c340a5201a3e5a Mon Sep 17 00:00:00 2001 From: David Karnok Date: Mon, 20 Dec 2021 15:46:37 +0100 Subject: [PATCH 64/66] Update gradle-wrapper-validation.yml --- .github/workflows/gradle-wrapper-validation.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/gradle-wrapper-validation.yml b/.github/workflows/gradle-wrapper-validation.yml index 405a2b3..005bc3d 100644 --- a/.github/workflows/gradle-wrapper-validation.yml +++ b/.github/workflows/gradle-wrapper-validation.yml @@ -7,4 +7,4 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - - uses: gradle/wrapper-validation-action@v1 + - uses: gradle/wrapper-validation-action@v1.0.4 From c2c916451cbaf29eba66bfae7eb4eb99fbf35dc0 Mon Sep 17 00:00:00 2001 From: David Karnok Date: Mon, 20 Dec 2021 15:47:51 +0100 Subject: [PATCH 65/66] Update gradle.yml --- .github/workflows/gradle.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/gradle.yml b/.github/workflows/gradle.yml index 795e26e..5fdc663 100644 --- a/.github/workflows/gradle.yml +++ b/.github/workflows/gradle.yml @@ -34,7 +34,7 @@ jobs: - name: Grant execute permission for push run: chmod +x push.sh - name: Build with Gradle - run: ./gradlew build --stacktrace + run: ./gradlew build javadoc --stacktrace - name: Upload to Codecov uses: codecov/codecov-action@v1 - name: Push Javadocs From 5b4331ec04b75e5c8ff1e3d540fc9a796e7c8ca7 Mon Sep 17 00:00:00 2001 From: David Karnok Date: Mon, 20 Dec 2021 15:50:18 +0100 Subject: [PATCH 66/66] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 86d0d5a..f1f3240 100644 --- a/README.md +++ b/README.md @@ -15,7 +15,7 @@ and interactive dataflows.** # Releases -Javadoc: https://akarnokd.github.com/ixjava/javadoc/index.html +Javadoc: https://akarnokd.github.io/ixjava/javadoc/index.html **gradle**