From 4b55baf38afd43d60a4a94a01f7f38fb3e24fe95 Mon Sep 17 00:00:00 2001 From: Victor Date: Wed, 22 Feb 2017 21:22:09 +0200 Subject: [PATCH 1/6] Refactoring Move operators to separate package Added internal package --- build.gradle | 2 +- stream/build.gradle | 2 +- .../java/com/annimon/stream/DoubleStream.java | 372 +----------- .../java/com/annimon/stream/IntStream.java | 394 +------------ .../java/com/annimon/stream/LongStream.java | 392 +------------ .../java/com/annimon/stream/LsaIterator.java | 2 +- .../main/java/com/annimon/stream/Stream.java | 546 +----------------- .../annimon/stream/{ => internal}/Compat.java | 19 +- .../annimon/stream/internal/Operators.java | 60 ++ .../stream/{ => internal}/SpinedBuffer.java | 8 +- .../annimon/stream/operator/DoubleArray.java | 24 + .../annimon/stream/operator/DoubleConcat.java | 32 + .../stream/operator/DoubleDropWhile.java | 34 ++ .../annimon/stream/operator/DoubleFilter.java | 33 ++ .../stream/operator/DoubleFlatMap.java | 46 ++ .../stream/operator/DoubleGenerate.java | 23 + .../stream/operator/DoubleIterate.java | 27 + .../annimon/stream/operator/DoubleLimit.java | 27 + .../annimon/stream/operator/DoubleMap.java | 25 + .../stream/operator/DoubleMapToInt.java | 25 + .../stream/operator/DoubleMapToLong.java | 25 + .../stream/operator/DoubleMapToObj.java | 26 + .../annimon/stream/operator/DoublePeek.java | 27 + .../annimon/stream/operator/DoubleSample.java | 30 + .../annimon/stream/operator/DoubleScan.java | 30 + .../stream/operator/DoubleScanIdentity.java | 34 ++ .../stream/operator/DoubleSingleElement.java | 25 + .../annimon/stream/operator/DoubleSkip.java | 33 ++ .../annimon/stream/operator/DoubleSorted.java | 30 + .../stream/operator/DoubleTakeUntil.java | 24 + .../stream/operator/DoubleTakeWhile.java | 22 + .../com/annimon/stream/operator/IntArray.java | 24 + .../annimon/stream/operator/IntConcat.java | 32 + .../annimon/stream/operator/IntDropWhile.java | 34 ++ .../annimon/stream/operator/IntFilter.java | 33 ++ .../annimon/stream/operator/IntFlatMap.java | 46 ++ .../annimon/stream/operator/IntGenerate.java | 23 + .../annimon/stream/operator/IntIterate.java | 27 + .../com/annimon/stream/operator/IntLimit.java | 27 + .../com/annimon/stream/operator/IntMap.java | 25 + .../stream/operator/IntMapToDouble.java | 25 + .../annimon/stream/operator/IntMapToLong.java | 25 + .../annimon/stream/operator/IntMapToObj.java | 26 + .../com/annimon/stream/operator/IntPeek.java | 27 + .../stream/operator/IntRangeClosed.java | 30 + .../annimon/stream/operator/IntSample.java | 30 + .../com/annimon/stream/operator/IntScan.java | 29 + .../stream/operator/IntScanIdentity.java | 33 ++ .../stream/operator/IntSingleElement.java | 25 + .../com/annimon/stream/operator/IntSkip.java | 34 ++ .../annimon/stream/operator/IntSorted.java | 30 + .../annimon/stream/operator/IntTakeUntil.java | 24 + .../annimon/stream/operator/IntTakeWhile.java | 22 + .../annimon/stream/operator/LongArray.java | 24 + .../annimon/stream/operator/LongConcat.java | 32 + .../stream/operator/LongDropWhile.java | 34 ++ .../annimon/stream/operator/LongFilter.java | 33 ++ .../annimon/stream/operator/LongFlatMap.java | 46 ++ .../annimon/stream/operator/LongGenerate.java | 23 + .../annimon/stream/operator/LongIterate.java | 27 + .../annimon/stream/operator/LongLimit.java | 27 + .../com/annimon/stream/operator/LongMap.java | 25 + .../stream/operator/LongMapToDouble.java | 25 + .../annimon/stream/operator/LongMapToInt.java | 25 + .../annimon/stream/operator/LongMapToObj.java | 26 + .../com/annimon/stream/operator/LongPeek.java | 27 + .../stream/operator/LongRangeClosed.java | 30 + .../annimon/stream/operator/LongSample.java | 30 + .../com/annimon/stream/operator/LongScan.java | 30 + .../stream/operator/LongScanIdentity.java | 33 ++ .../stream/operator/LongSingleElement.java | 25 + .../com/annimon/stream/operator/LongSkip.java | 33 ++ .../annimon/stream/operator/LongSorted.java | 30 + .../stream/operator/LongTakeUntil.java | 24 + .../stream/operator/LongTakeWhile.java | 22 + .../com/annimon/stream/operator/ObjArray.java | 24 + .../annimon/stream/operator/ObjChunkBy.java | 51 ++ .../annimon/stream/operator/ObjConcat.java | 30 + .../annimon/stream/operator/ObjDistinct.java | 28 + .../annimon/stream/operator/ObjDropWhile.java | 34 ++ .../annimon/stream/operator/ObjFilter.java | 55 ++ .../annimon/stream/operator/ObjFlatMap.java | 43 ++ .../stream/operator/ObjFlatMapToDouble.java | 44 ++ .../stream/operator/ObjFlatMapToInt.java | 43 ++ .../stream/operator/ObjFlatMapToLong.java | 44 ++ .../annimon/stream/operator/ObjGenerate.java | 23 + .../annimon/stream/operator/ObjIterate.java | 27 + .../com/annimon/stream/operator/ObjLimit.java | 28 + .../com/annimon/stream/operator/ObjMap.java | 26 + .../stream/operator/ObjMapToDouble.java | 26 + .../annimon/stream/operator/ObjMapToInt.java | 26 + .../annimon/stream/operator/ObjMapToLong.java | 26 + .../com/annimon/stream/operator/ObjPeek.java | 28 + .../com/annimon/stream/operator/ObjScan.java | 29 + .../stream/operator/ObjScanIdentity.java | 34 ++ .../com/annimon/stream/operator/ObjSkip.java | 34 ++ .../stream/operator/ObjSlidingWindow.java | 53 ++ .../annimon/stream/operator/ObjSorted.java | 33 ++ .../annimon/stream/operator/ObjTakeUntil.java | 24 + .../annimon/stream/operator/ObjTakeWhile.java | 22 + .../com/annimon/stream/operator/ObjZip.java | 29 + .../java/com/annimon/stream/StreamTest.java | 22 - .../annimon/stream/internal/CompatTest.java | 28 + .../stream/internal/OperatorsTest.java | 16 + .../{ => internal}/SpinedBufferTest.java | 9 +- 105 files changed, 2971 insertions(+), 1629 deletions(-) rename stream/src/main/java/com/annimon/stream/{ => internal}/Compat.java (60%) create mode 100644 stream/src/main/java/com/annimon/stream/internal/Operators.java rename stream/src/main/java/com/annimon/stream/{ => internal}/SpinedBuffer.java (98%) create mode 100644 stream/src/main/java/com/annimon/stream/operator/DoubleArray.java create mode 100644 stream/src/main/java/com/annimon/stream/operator/DoubleConcat.java create mode 100644 stream/src/main/java/com/annimon/stream/operator/DoubleDropWhile.java create mode 100644 stream/src/main/java/com/annimon/stream/operator/DoubleFilter.java create mode 100644 stream/src/main/java/com/annimon/stream/operator/DoubleFlatMap.java create mode 100644 stream/src/main/java/com/annimon/stream/operator/DoubleGenerate.java create mode 100644 stream/src/main/java/com/annimon/stream/operator/DoubleIterate.java create mode 100644 stream/src/main/java/com/annimon/stream/operator/DoubleLimit.java create mode 100644 stream/src/main/java/com/annimon/stream/operator/DoubleMap.java create mode 100644 stream/src/main/java/com/annimon/stream/operator/DoubleMapToInt.java create mode 100644 stream/src/main/java/com/annimon/stream/operator/DoubleMapToLong.java create mode 100644 stream/src/main/java/com/annimon/stream/operator/DoubleMapToObj.java create mode 100644 stream/src/main/java/com/annimon/stream/operator/DoublePeek.java create mode 100644 stream/src/main/java/com/annimon/stream/operator/DoubleSample.java create mode 100644 stream/src/main/java/com/annimon/stream/operator/DoubleScan.java create mode 100644 stream/src/main/java/com/annimon/stream/operator/DoubleScanIdentity.java create mode 100644 stream/src/main/java/com/annimon/stream/operator/DoubleSingleElement.java create mode 100644 stream/src/main/java/com/annimon/stream/operator/DoubleSkip.java create mode 100644 stream/src/main/java/com/annimon/stream/operator/DoubleSorted.java create mode 100644 stream/src/main/java/com/annimon/stream/operator/DoubleTakeUntil.java create mode 100644 stream/src/main/java/com/annimon/stream/operator/DoubleTakeWhile.java create mode 100644 stream/src/main/java/com/annimon/stream/operator/IntArray.java create mode 100644 stream/src/main/java/com/annimon/stream/operator/IntConcat.java create mode 100644 stream/src/main/java/com/annimon/stream/operator/IntDropWhile.java create mode 100644 stream/src/main/java/com/annimon/stream/operator/IntFilter.java create mode 100644 stream/src/main/java/com/annimon/stream/operator/IntFlatMap.java create mode 100644 stream/src/main/java/com/annimon/stream/operator/IntGenerate.java create mode 100644 stream/src/main/java/com/annimon/stream/operator/IntIterate.java create mode 100644 stream/src/main/java/com/annimon/stream/operator/IntLimit.java create mode 100644 stream/src/main/java/com/annimon/stream/operator/IntMap.java create mode 100644 stream/src/main/java/com/annimon/stream/operator/IntMapToDouble.java create mode 100644 stream/src/main/java/com/annimon/stream/operator/IntMapToLong.java create mode 100644 stream/src/main/java/com/annimon/stream/operator/IntMapToObj.java create mode 100644 stream/src/main/java/com/annimon/stream/operator/IntPeek.java create mode 100644 stream/src/main/java/com/annimon/stream/operator/IntRangeClosed.java create mode 100644 stream/src/main/java/com/annimon/stream/operator/IntSample.java create mode 100644 stream/src/main/java/com/annimon/stream/operator/IntScan.java create mode 100644 stream/src/main/java/com/annimon/stream/operator/IntScanIdentity.java create mode 100644 stream/src/main/java/com/annimon/stream/operator/IntSingleElement.java create mode 100644 stream/src/main/java/com/annimon/stream/operator/IntSkip.java create mode 100644 stream/src/main/java/com/annimon/stream/operator/IntSorted.java create mode 100644 stream/src/main/java/com/annimon/stream/operator/IntTakeUntil.java create mode 100644 stream/src/main/java/com/annimon/stream/operator/IntTakeWhile.java create mode 100644 stream/src/main/java/com/annimon/stream/operator/LongArray.java create mode 100644 stream/src/main/java/com/annimon/stream/operator/LongConcat.java create mode 100644 stream/src/main/java/com/annimon/stream/operator/LongDropWhile.java create mode 100644 stream/src/main/java/com/annimon/stream/operator/LongFilter.java create mode 100644 stream/src/main/java/com/annimon/stream/operator/LongFlatMap.java create mode 100644 stream/src/main/java/com/annimon/stream/operator/LongGenerate.java create mode 100644 stream/src/main/java/com/annimon/stream/operator/LongIterate.java create mode 100644 stream/src/main/java/com/annimon/stream/operator/LongLimit.java create mode 100644 stream/src/main/java/com/annimon/stream/operator/LongMap.java create mode 100644 stream/src/main/java/com/annimon/stream/operator/LongMapToDouble.java create mode 100644 stream/src/main/java/com/annimon/stream/operator/LongMapToInt.java create mode 100644 stream/src/main/java/com/annimon/stream/operator/LongMapToObj.java create mode 100644 stream/src/main/java/com/annimon/stream/operator/LongPeek.java create mode 100644 stream/src/main/java/com/annimon/stream/operator/LongRangeClosed.java create mode 100644 stream/src/main/java/com/annimon/stream/operator/LongSample.java create mode 100644 stream/src/main/java/com/annimon/stream/operator/LongScan.java create mode 100644 stream/src/main/java/com/annimon/stream/operator/LongScanIdentity.java create mode 100644 stream/src/main/java/com/annimon/stream/operator/LongSingleElement.java create mode 100644 stream/src/main/java/com/annimon/stream/operator/LongSkip.java create mode 100644 stream/src/main/java/com/annimon/stream/operator/LongSorted.java create mode 100644 stream/src/main/java/com/annimon/stream/operator/LongTakeUntil.java create mode 100644 stream/src/main/java/com/annimon/stream/operator/LongTakeWhile.java create mode 100644 stream/src/main/java/com/annimon/stream/operator/ObjArray.java create mode 100644 stream/src/main/java/com/annimon/stream/operator/ObjChunkBy.java create mode 100644 stream/src/main/java/com/annimon/stream/operator/ObjConcat.java create mode 100644 stream/src/main/java/com/annimon/stream/operator/ObjDistinct.java create mode 100644 stream/src/main/java/com/annimon/stream/operator/ObjDropWhile.java create mode 100644 stream/src/main/java/com/annimon/stream/operator/ObjFilter.java create mode 100644 stream/src/main/java/com/annimon/stream/operator/ObjFlatMap.java create mode 100644 stream/src/main/java/com/annimon/stream/operator/ObjFlatMapToDouble.java create mode 100644 stream/src/main/java/com/annimon/stream/operator/ObjFlatMapToInt.java create mode 100644 stream/src/main/java/com/annimon/stream/operator/ObjFlatMapToLong.java create mode 100644 stream/src/main/java/com/annimon/stream/operator/ObjGenerate.java create mode 100644 stream/src/main/java/com/annimon/stream/operator/ObjIterate.java create mode 100644 stream/src/main/java/com/annimon/stream/operator/ObjLimit.java create mode 100644 stream/src/main/java/com/annimon/stream/operator/ObjMap.java create mode 100644 stream/src/main/java/com/annimon/stream/operator/ObjMapToDouble.java create mode 100644 stream/src/main/java/com/annimon/stream/operator/ObjMapToInt.java create mode 100644 stream/src/main/java/com/annimon/stream/operator/ObjMapToLong.java create mode 100644 stream/src/main/java/com/annimon/stream/operator/ObjPeek.java create mode 100644 stream/src/main/java/com/annimon/stream/operator/ObjScan.java create mode 100644 stream/src/main/java/com/annimon/stream/operator/ObjScanIdentity.java create mode 100644 stream/src/main/java/com/annimon/stream/operator/ObjSkip.java create mode 100644 stream/src/main/java/com/annimon/stream/operator/ObjSlidingWindow.java create mode 100644 stream/src/main/java/com/annimon/stream/operator/ObjSorted.java create mode 100644 stream/src/main/java/com/annimon/stream/operator/ObjTakeUntil.java create mode 100644 stream/src/main/java/com/annimon/stream/operator/ObjTakeWhile.java create mode 100644 stream/src/main/java/com/annimon/stream/operator/ObjZip.java create mode 100644 stream/src/test/java/com/annimon/stream/internal/CompatTest.java create mode 100644 stream/src/test/java/com/annimon/stream/internal/OperatorsTest.java rename stream/src/test/java/com/annimon/stream/{ => internal}/SpinedBufferTest.java (98%) diff --git a/build.gradle b/build.gradle index 1e66c296..b6b17e38 100644 --- a/build.gradle +++ b/build.gradle @@ -28,7 +28,7 @@ subprojects { cobertura { coverageFormats = ['html', 'xml'] - coverageExcludes = ['.*com\\.annimon\\.stream\\.Compat.*', '.*com\\.annimon\\.stream\\.test\\.hamcrest\\.CommonMatcher.*'] + coverageExcludes = ['.*com\\.annimon\\.stream\\.internal\\.Compat.*', '.*com\\.annimon\\.stream\\.test\\.hamcrest\\.CommonMatcher.*'] coverageReportDatafile = file("build/cobertura/cobertura.ser") coverageReportDir = file("build/reports/coverage") coverageSourceDirs = subprojects.sourceSets.main.allSource.srcDirs.flatten() diff --git a/stream/build.gradle b/stream/build.gradle index 7be34925..47fe8d15 100644 --- a/stream/build.gradle +++ b/stream/build.gradle @@ -24,7 +24,7 @@ dependencies { } cobertura { - coverageExcludes = ['.*com\\.annimon\\.stream\\.Compat.*'] + coverageExcludes = ['.*com\\.annimon\\.stream\\.internal\\.Compat.*'] } // maven signing diff --git a/stream/src/main/java/com/annimon/stream/DoubleStream.java b/stream/src/main/java/com/annimon/stream/DoubleStream.java index bd11681d..b6826490 100644 --- a/stream/src/main/java/com/annimon/stream/DoubleStream.java +++ b/stream/src/main/java/com/annimon/stream/DoubleStream.java @@ -1,18 +1,8 @@ package com.annimon.stream; -import com.annimon.stream.function.DoubleBinaryOperator; -import com.annimon.stream.function.DoubleConsumer; -import com.annimon.stream.function.DoubleFunction; -import com.annimon.stream.function.DoublePredicate; -import com.annimon.stream.function.DoubleSupplier; -import com.annimon.stream.function.DoubleToIntFunction; -import com.annimon.stream.function.DoubleToLongFunction; -import com.annimon.stream.function.DoubleUnaryOperator; -import com.annimon.stream.function.Function; -import com.annimon.stream.function.ObjDoubleConsumer; -import com.annimon.stream.function.Supplier; -import com.annimon.stream.function.ToDoubleFunction; -import java.util.Arrays; +import com.annimon.stream.operator.*; +import com.annimon.stream.function.*; +import com.annimon.stream.internal.Operators; import java.util.Comparator; import java.util.NoSuchElementException; @@ -71,20 +61,7 @@ public static DoubleStream of(PrimitiveIterator.OfDouble iterator) { */ public static DoubleStream of(final double... values) { Objects.requireNonNull(values); - return new DoubleStream(new PrimitiveIterator.OfDouble() { - - private int index = 0; - - @Override - public boolean hasNext() { - return index < values.length; - } - - @Override - public double nextDouble() { - return values[index++]; - } - }); + return new DoubleStream(new DoubleArray(values)); } /** @@ -94,21 +71,7 @@ public double nextDouble() { * @return the new stream */ public static DoubleStream of(final double t) { - return new DoubleStream(new PrimitiveIterator.OfDouble() { - - private int index = 0; - - @Override - public boolean hasNext() { - return index == 0; - } - - @Override - public double nextDouble() { - index++; - return t; - } - }); + return new DoubleStream(new DoubleSingleElement(t)); } /** @@ -120,18 +83,7 @@ public double nextDouble() { */ public static DoubleStream generate(final DoubleSupplier s) { Objects.requireNonNull(s); - return new DoubleStream(new PrimitiveIterator.OfDouble() { - - @Override - public boolean hasNext() { - return true; - } - - @Override - public double nextDouble() { - return s.getAsDouble(); - } - }); + return new DoubleStream(new DoubleGenerate(s)); } /** @@ -158,22 +110,7 @@ public double nextDouble() { */ public static DoubleStream iterate(final double seed, final DoubleUnaryOperator f) { Objects.requireNonNull(f); - return new DoubleStream(new PrimitiveIterator.OfDouble() { - - private double current = seed; - - @Override - public boolean hasNext() { - return true; - } - - @Override - public double nextDouble() { - final double old = current; - current = f.applyAsDouble(current); - return old; - } - }); + return new DoubleStream(new DoubleIterate(seed, f)); } /** @@ -219,28 +156,7 @@ public static DoubleStream iterate(final double seed, public static DoubleStream concat(final DoubleStream a, final DoubleStream b) { Objects.requireNonNull(a); Objects.requireNonNull(b); - final PrimitiveIterator.OfDouble it1 = a.iterator; - final PrimitiveIterator.OfDouble it2 = b.iterator; - return new DoubleStream(new PrimitiveIterator.OfDouble() { - - private boolean firstStreamIsCurrent = true; - - @Override - public boolean hasNext() { - if (firstStreamIsCurrent) { - if (it1.hasNext()) - return true; - - firstStreamIsCurrent = false; - } - return it2.hasNext(); - } - - @Override - public double nextDouble() { - return firstStreamIsCurrent ? it1.nextDouble() : it2.nextDouble(); - } - }); + return new DoubleStream(new DoubleConcat(a.iterator, b.iterator)); } @@ -369,26 +285,7 @@ public Stream boxed() { * @return the new stream */ public DoubleStream filter(final DoublePredicate predicate) { - return new DoubleStream(new PrimitiveIterator.OfDouble() { - - private double next; - - @Override - public boolean hasNext() { - while (iterator.hasNext()) { - next = iterator.next(); - if (predicate.test(next)) { - return true; - } - } - return false; - } - - @Override - public double nextDouble() { - return next; - } - }); + return new DoubleStream(new DoubleFilter(iterator, predicate)); } /** @@ -421,18 +318,7 @@ public DoubleStream filterNot(final DoublePredicate predicate) { * @see Stream#map(com.annimon.stream.function.Function) */ public DoubleStream map(final DoubleUnaryOperator mapper) { - return new DoubleStream(new PrimitiveIterator.OfDouble() { - - @Override - public boolean hasNext() { - return iterator.hasNext(); - } - - @Override - public double nextDouble() { - return mapper.applyAsDouble(iterator.nextDouble()); - } - }); + return new DoubleStream(new DoubleMap(iterator, mapper)); } /** @@ -446,18 +332,7 @@ public double nextDouble() { * @return the new {@code Stream} */ public Stream mapToObj(final DoubleFunction mapper) { - return Stream.of(new LsaIterator() { - - @Override - public boolean hasNext() { - return iterator.hasNext(); - } - - @Override - public R nextIteration() { - return mapper.apply(iterator.nextDouble()); - } - }); + return Stream.of(new DoubleMapToObj(iterator, mapper)); } /** @@ -470,18 +345,7 @@ public R nextIteration() { * @return the new {@code IntStream} */ public IntStream mapToInt(final DoubleToIntFunction mapper) { - return IntStream.of(new PrimitiveIterator.OfInt() { - - @Override - public boolean hasNext() { - return iterator.hasNext(); - } - - @Override - public int nextInt() { - return mapper.applyAsInt(iterator.nextDouble()); - } - }); + return IntStream.of(new DoubleMapToInt(iterator, mapper)); } /** @@ -494,18 +358,7 @@ public int nextInt() { * @return the new {@code LongStream} */ public LongStream mapToLong(final DoubleToLongFunction mapper) { - return LongStream.of(new PrimitiveIterator.OfLong() { - - @Override - public boolean hasNext() { - return iterator.hasNext(); - } - - @Override - public long nextLong() { - return mapper.applyAsLong(iterator.nextDouble()); - } - }); + return LongStream.of(new DoubleMapToLong(iterator, mapper)); } /** @@ -527,37 +380,7 @@ public long nextLong() { * @see Stream#flatMap(com.annimon.stream.function.Function) */ public DoubleStream flatMap(final DoubleFunction mapper) { - return new DoubleStream(new PrimitiveIterator.OfDouble() { - - private PrimitiveIterator.OfDouble inner; - - @Override - public boolean hasNext() { - if (inner != null && inner.hasNext()) { - return true; - } - while (iterator.hasNext()) { - final double arg = iterator.next(); - final DoubleStream result = mapper.apply(arg); - if (result == null) { - continue; - } - if (result.iterator.hasNext()) { - inner = result.iterator; - return true; - } - } - return false; - } - - @Override - public double nextDouble() { - if (inner == null) { - throw new NoSuchElementException(); - } - return inner.nextDouble(); - } - }); + return new DoubleStream(new DoubleFlatMap(iterator, mapper)); } /** @@ -591,23 +414,7 @@ public DoubleStream distinct() { * @return the new stream */ public DoubleStream sorted() { - return new DoubleStream(new PrimitiveExtIterator.OfDouble() { - - private int index = 0; - private double[] array; - - @Override - protected void nextIteration() { - if (!isInit) { - array = toArray(); - Arrays.sort(array); - } - hasNext = index < array.length; - if (hasNext) { - next = array[index++]; - } - } - }); + return new DoubleStream(new DoubleSorted(iterator)); } /** @@ -650,24 +457,7 @@ public DoubleStream sorted(Comparator comparator) { public DoubleStream sample(final int stepWidth) { if (stepWidth <= 0) throw new IllegalArgumentException("stepWidth cannot be zero or negative"); if (stepWidth == 1) return this; - return new DoubleStream(new PrimitiveIterator.OfDouble() { - - @Override - public boolean hasNext() { - return iterator.hasNext(); - } - - @Override - public double nextDouble() { - final double result = iterator.nextDouble(); - int skip = 1; - while (skip < stepWidth && iterator.hasNext()) { - iterator.nextDouble(); - skip++; - } - return result; - } - }); + return new DoubleStream(new DoubleSample(iterator, stepWidth)); } /** @@ -679,20 +469,7 @@ public double nextDouble() { * @return the new stream */ public DoubleStream peek(final DoubleConsumer action) { - return new DoubleStream(new PrimitiveIterator.OfDouble() { - - @Override - public boolean hasNext() { - return iterator.hasNext(); - } - - @Override - public double nextDouble() { - double value = iterator.nextDouble(); - action.accept(value); - return value; - } - }); + return new DoubleStream(new DoublePeek(iterator, action)); } /** @@ -717,21 +494,7 @@ public double nextDouble() { */ public DoubleStream scan(final DoubleBinaryOperator accumulator) { Objects.requireNonNull(accumulator); - return new DoubleStream(new PrimitiveExtIterator.OfDouble() { - - @Override - protected void nextIteration() { - hasNext = iterator.hasNext(); - if (hasNext) { - final double current = iterator.next(); - if (isInit) { - next = accumulator.applyAsDouble(next, current); - } else { - next = current; - } - } - } - }); + return new DoubleStream(new DoubleScan(iterator, accumulator)); } /** @@ -758,23 +521,7 @@ protected void nextIteration() { */ public DoubleStream scan(final double identity, final DoubleBinaryOperator accumulator) { Objects.requireNonNull(accumulator); - return new DoubleStream(new PrimitiveExtIterator.OfDouble() { - - @Override - protected void nextIteration() { - if (!isInit) { - // Return identity - hasNext = true; - next = identity; - return; - } - hasNext = iterator.hasNext(); - if (hasNext) { - final double current = iterator.next(); - next = accumulator.applyAsDouble(next, current); - } - } - }); + return new DoubleStream(new DoubleScanIdentity(iterator, identity, accumulator)); } /** @@ -793,14 +540,7 @@ protected void nextIteration() { * @return the new {@code DoubleStream} */ public DoubleStream takeWhile(final DoublePredicate predicate) { - return new DoubleStream(new PrimitiveExtIterator.OfDouble() { - - @Override - protected void nextIteration() { - hasNext = iterator.hasNext() - && predicate.test(next = iterator.next()); - } - }); + return new DoubleStream(new DoubleTakeWhile(iterator, predicate)); } /** @@ -822,16 +562,7 @@ protected void nextIteration() { * @since 1.1.6 */ public DoubleStream takeUntil(final DoublePredicate stopPredicate) { - return new DoubleStream(new PrimitiveExtIterator.OfDouble() { - - @Override - protected void nextIteration() { - hasNext = iterator.hasNext() && !(isInit && stopPredicate.test(next)); - if (hasNext) { - next = iterator.next(); - } - } - }); + return new DoubleStream(new DoubleTakeUntil(iterator, stopPredicate)); } /** @@ -850,26 +581,7 @@ protected void nextIteration() { * @return the new {@code DoubleStream} */ public DoubleStream dropWhile(final DoublePredicate predicate) { - return new DoubleStream(new PrimitiveExtIterator.OfDouble() { - - @Override - protected void nextIteration() { - if (!isInit) { - // Skip first time - while (hasNext = iterator.hasNext()) { - next = iterator.next(); - if (!predicate.test(next)) { - return; - } - } - } - - hasNext = hasNext && iterator.hasNext(); - if (!hasNext) return; - - next = iterator.next(); - } - }); + return new DoubleStream(new DoubleDropWhile(iterator, predicate)); } /** @@ -896,21 +608,7 @@ protected void nextIteration() { public DoubleStream limit(final long maxSize) { if (maxSize < 0) throw new IllegalArgumentException("maxSize cannot be negative"); if (maxSize == 0) return DoubleStream.empty(); - return new DoubleStream(new PrimitiveIterator.OfDouble() { - - private long index = 0; - - @Override - public boolean hasNext() { - return (index < maxSize) && iterator.hasNext(); - } - - @Override - public double nextDouble() { - index++; - return iterator.nextDouble(); - } - }); + return new DoubleStream(new DoubleLimit(iterator, maxSize)); } /** @@ -938,25 +636,7 @@ public double nextDouble() { public DoubleStream skip(final long n) { if (n < 0) throw new IllegalArgumentException("n cannot be negative"); if (n == 0) return this; - return new DoubleStream(new PrimitiveIterator.OfDouble() { - - private long skippedCount = 0; - - @Override - public boolean hasNext() { - while (iterator.hasNext()) { - if (skippedCount == n) break; - iterator.nextDouble(); - skippedCount++; - } - return iterator.hasNext(); - } - - @Override - public double nextDouble() { - return iterator.nextDouble(); - } - }); + return new DoubleStream(new DoubleSkip(iterator, n)); } /** @@ -1044,9 +724,7 @@ public OptionalDouble reduce(DoubleBinaryOperator accumulator) { * @return an array containing the elements of this stream */ public double[] toArray() { - SpinedBuffer.OfDouble b = new SpinedBuffer.OfDouble(); - forEach(b); - return b.asPrimitiveArray(); + return Operators.toDoubleArray(iterator); } /** diff --git a/stream/src/main/java/com/annimon/stream/IntStream.java b/stream/src/main/java/com/annimon/stream/IntStream.java index 15955798..e4cb77de 100644 --- a/stream/src/main/java/com/annimon/stream/IntStream.java +++ b/stream/src/main/java/com/annimon/stream/IntStream.java @@ -1,7 +1,8 @@ package com.annimon.stream; +import com.annimon.stream.operator.*; import com.annimon.stream.function.*; -import java.util.Arrays; +import com.annimon.stream.internal.Operators; import java.util.Comparator; import java.util.NoSuchElementException; @@ -57,44 +58,17 @@ public static IntStream of(PrimitiveIterator.OfInt iterator) { */ public static IntStream of(final int... values) { Objects.requireNonNull(values); - return new IntStream(new PrimitiveIterator.OfInt() { - - private int index = 0; - - @Override - public int nextInt() { - return values[index++]; - } - - @Override - public boolean hasNext() { - return index < values.length; - } - }); + return new IntStream(new IntArray(values)); } /** - * Returns stream which contains single element passed as param + * Returns stream which contains single element passed as parameter. * * @param t element of the stream * @return the new stream */ public static IntStream of(final int t) { - return new IntStream(new PrimitiveIterator.OfInt() { - - private int index = 0; - - @Override - public int nextInt() { - index++; - return t; - } - - @Override - public boolean hasNext() { - return index == 0; - } - }); + return new IntStream(new IntSingleElement(t)); } /** @@ -129,25 +103,9 @@ public static IntStream rangeClosed(final int startInclusive, final int endInclu return empty(); } else if (startInclusive == endInclusive) { return of(startInclusive); - } else return new IntStream(new PrimitiveIterator.OfInt() { - - private int current = startInclusive; - private boolean hasNext = current <= endInclusive; - - @Override - public boolean hasNext() { - return hasNext; - } - - @Override - public int nextInt() { - if (current >= endInclusive) { - hasNext = false; - return endInclusive; - } - return current++; - } - }); + } else { + return new IntStream(new IntRangeClosed(startInclusive, endInclusive)); + } } /** @@ -161,17 +119,7 @@ public int nextInt() { */ public static IntStream generate(final IntSupplier s) { Objects.requireNonNull(s); - return new IntStream(new PrimitiveIterator.OfInt() { - @Override - public int nextInt() { - return s.getAsInt(); - } - - @Override - public boolean hasNext() { - return true; - } - }); + return new IntStream(new IntGenerate(s)); } /** @@ -200,24 +148,7 @@ public boolean hasNext() { */ public static IntStream iterate(final int seed, final IntUnaryOperator f) { Objects.requireNonNull(f); - return new IntStream(new PrimitiveIterator.OfInt() { - - private int current = seed; - - @Override - public int nextInt() { - - int old = current; - current = f.applyAsInt(current); - - return old; - } - - @Override - public boolean hasNext() { - return true; - } - }); + return new IntStream(new IntIterate(seed, f)); } /** @@ -265,28 +196,7 @@ public static IntStream iterate(final int seed, public static IntStream concat(final IntStream a, final IntStream b) { Objects.requireNonNull(a); Objects.requireNonNull(b); - - return new IntStream(new PrimitiveIterator.OfInt() { - - private boolean firstStreamIsCurrent = true; - - @Override - public int nextInt() { - return firstStreamIsCurrent ? a.iterator.nextInt() : b.iterator.nextInt(); - } - - @Override - public boolean hasNext() { - if(firstStreamIsCurrent) { - if(a.iterator.hasNext()) - return true; - - firstStreamIsCurrent = false; - } - - return b.iterator.hasNext(); - } - }); + return new IntStream(new IntConcat(a.iterator, b.iterator)); } private final PrimitiveIterator.OfInt iterator; @@ -406,27 +316,7 @@ public Stream boxed() { * @return the new stream */ public IntStream filter(final IntPredicate predicate) { - return new IntStream(new PrimitiveIterator.OfInt() { - - private int next; - - @Override - public int nextInt() { - return next; - } - - @Override - public boolean hasNext() { - while(iterator.hasNext()) { - next = iterator.next(); - if(predicate.test(next)) { - return true; - } - } - - return false; - } - }); + return new IntStream(new IntFilter(iterator, predicate)); } /** @@ -461,17 +351,7 @@ public IntStream filterNot(final IntPredicate predicate) { * @return the new {@code IntStream} */ public IntStream map(final IntUnaryOperator mapper) { - return new IntStream(new PrimitiveIterator.OfInt() { - @Override - public int nextInt() { - return mapper.applyAsInt(iterator.nextInt()); - } - - @Override - public boolean hasNext() { - return iterator.hasNext(); - } - }); + return new IntStream(new IntMap(iterator, mapper)); } /** @@ -485,18 +365,7 @@ public boolean hasNext() { * @return the new {@code Stream} */ public Stream mapToObj(final IntFunction mapper) { - return Stream.of(new LsaIterator() { - - @Override - public boolean hasNext() { - return iterator.hasNext(); - } - - @Override - public R nextIteration() { - return mapper.apply(iterator.nextInt()); - } - }); + return Stream.of(new IntMapToObj(iterator, mapper)); } /** @@ -511,18 +380,7 @@ public R nextIteration() { * @see #flatMap(com.annimon.stream.function.IntFunction) */ public LongStream mapToLong(final IntToLongFunction mapper) { - return LongStream.of(new PrimitiveIterator.OfLong() { - - @Override - public boolean hasNext() { - return iterator.hasNext(); - } - - @Override - public long nextLong() { - return mapper.applyAsLong(iterator.nextInt()); - } - }); + return LongStream.of(new IntMapToLong(iterator, mapper)); } /** @@ -537,18 +395,7 @@ public long nextLong() { * @see #flatMap(com.annimon.stream.function.IntFunction) */ public DoubleStream mapToDouble(final IntToDoubleFunction mapper) { - return DoubleStream.of(new PrimitiveIterator.OfDouble() { - - @Override - public boolean hasNext() { - return iterator.hasNext(); - } - - @Override - public double nextDouble() { - return mapper.applyAsDouble(iterator.nextInt()); - } - }); + return DoubleStream.of(new IntMapToDouble(iterator, mapper)); } /** @@ -571,37 +418,7 @@ public double nextDouble() { * @see Stream#flatMap(Function) */ public IntStream flatMap(final IntFunction mapper) { - return new IntStream(new PrimitiveIterator.OfInt() { - - private PrimitiveIterator.OfInt inner; - - @Override - public int nextInt() { - if (inner == null) { - throw new NoSuchElementException(); - } - return inner.nextInt(); - } - - @Override - public boolean hasNext() { - if (inner != null && inner.hasNext()) { - return true; - } - while (iterator.hasNext()) { - final int arg = iterator.next(); - final IntStream result = mapper.apply(arg); - if (result == null) { - continue; - } - if (result.iterator.hasNext()) { - inner = result.iterator; - return true; - } - } - return false; - } - }); + return new IntStream(new IntFlatMap(iterator, mapper)); } /** @@ -638,23 +455,7 @@ public IntStream distinct() { * @return the new stream */ public IntStream sorted() { - return new IntStream(new PrimitiveExtIterator.OfInt() { - - private int index = 0; - private int[] array; - - @Override - protected void nextIteration() { - if (!isInit) { - array = toArray(); - Arrays.sort(array); - } - hasNext = index < array.length; - if (hasNext) { - next = array[index++]; - } - } - }); + return new IntStream(new IntSorted(iterator)); } /** @@ -696,24 +497,7 @@ public IntStream sorted(Comparator comparator) { public IntStream sample(final int stepWidth) { if (stepWidth <= 0) throw new IllegalArgumentException("stepWidth cannot be zero or negative"); if (stepWidth == 1) return this; - return new IntStream(new PrimitiveIterator.OfInt() { - - @Override - public boolean hasNext() { - return iterator.hasNext(); - } - - @Override - public int nextInt() { - final int result = iterator.nextInt(); - int skip = 1; - while (skip < stepWidth && iterator.hasNext()) { - iterator.nextInt(); - skip++; - } - return result; - } - }); + return new IntStream(new IntSample(iterator, stepWidth)); } /** @@ -727,19 +511,7 @@ public int nextInt() { * @return the new stream */ public IntStream peek(final IntConsumer action) { - return new IntStream(new PrimitiveIterator.OfInt() { - @Override - public int nextInt() { - int value = iterator.nextInt(); - action.accept(value); - return value; - } - - @Override - public boolean hasNext() { - return iterator.hasNext(); - } - }); + return new IntStream(new IntPeek(iterator, action)); } /** @@ -764,21 +536,7 @@ public boolean hasNext() { */ public IntStream scan(final IntBinaryOperator accumulator) { Objects.requireNonNull(accumulator); - return new IntStream(new PrimitiveExtIterator.OfInt() { - - @Override - protected void nextIteration() { - hasNext = iterator.hasNext(); - if (hasNext) { - final int current = iterator.next(); - if (isInit) { - next = accumulator.applyAsInt(next, current); - } else { - next = current; - } - } - } - }); + return new IntStream(new IntScan(iterator, accumulator)); } /** @@ -805,23 +563,7 @@ protected void nextIteration() { */ public IntStream scan(final int identity, final IntBinaryOperator accumulator) { Objects.requireNonNull(accumulator); - return new IntStream(new PrimitiveExtIterator.OfInt() { - - @Override - protected void nextIteration() { - if (!isInit) { - // Return identity - hasNext = true; - next = identity; - return; - } - hasNext = iterator.hasNext(); - if (hasNext) { - final int current = iterator.next(); - next = accumulator.applyAsInt(next, current); - } - } - }); + return new IntStream(new IntScanIdentity(iterator, identity, accumulator)); } /** @@ -840,13 +582,7 @@ protected void nextIteration() { * @return the new {@code IntStream} */ public IntStream takeWhile(final IntPredicate predicate) { - return new IntStream(new PrimitiveExtIterator.OfInt() { - - @Override - protected void nextIteration() { - hasNext = iterator.hasNext() && predicate.test(next = iterator.next()); - } - }); + return new IntStream(new IntTakeWhile(iterator, predicate)); } /** @@ -868,16 +604,7 @@ protected void nextIteration() { * @since 1.1.6 */ public IntStream takeUntil(final IntPredicate stopPredicate) { - return new IntStream(new PrimitiveExtIterator.OfInt() { - - @Override - protected void nextIteration() { - hasNext = iterator.hasNext() && !(isInit && stopPredicate.test(next)); - if (hasNext) { - next = iterator.next(); - } - } - }); + return new IntStream(new IntTakeUntil(iterator, stopPredicate)); } /** @@ -896,26 +623,7 @@ protected void nextIteration() { * @return the new {@code IntStream} */ public IntStream dropWhile(final IntPredicate predicate) { - return new IntStream(new PrimitiveExtIterator.OfInt() { - - @Override - protected void nextIteration() { - if (!isInit) { - // Skip first time - while (hasNext = iterator.hasNext()) { - next = iterator.next(); - if (!predicate.test(next)) { - return; - } - } - } - - hasNext = hasNext && iterator.hasNext(); - if (!hasNext) return; - - next = iterator.next(); - } - }); + return new IntStream(new IntDropWhile(iterator, predicate)); } /** @@ -946,21 +654,7 @@ public IntStream limit(final long maxSize) { if (maxSize == 0) { return IntStream.empty(); } - return new IntStream(new PrimitiveIterator.OfInt() { - - private long index = 0; - - @Override - public int nextInt() { - index++; - return iterator.nextInt(); - } - - @Override - public boolean hasNext() { - return (index < maxSize) && iterator.hasNext(); - } - }); + return new IntStream(new IntLimit(iterator, maxSize)); } /** @@ -987,33 +681,13 @@ public boolean hasNext() { * @throws IllegalArgumentException if {@code n} is negative */ public IntStream skip(final long n) { - if(n < 0) + if (n < 0) { throw new IllegalArgumentException("n cannot be negative"); - - if(n == 0) + } else if (n == 0) { return this; - else - return new IntStream(new PrimitiveIterator.OfInt() { - long skipped = 0; - @Override - public int nextInt() { - return iterator.nextInt(); - } - - @Override - public boolean hasNext() { - - while(iterator.hasNext()) { - - if(skipped == n) break; - - skipped++; - iterator.nextInt(); - } - - return iterator.hasNext(); - } - }); + } else { + return new IntStream(new IntSkip(iterator, n)); + } } /** @@ -1104,11 +778,7 @@ public OptionalInt reduce(IntBinaryOperator op) { * @return an array containing the elements of this stream */ public int[] toArray() { - SpinedBuffer.OfInt b = new SpinedBuffer.OfInt(); - - forEach(b); - - return b.asPrimitiveArray(); + return Operators.toIntArray(iterator); } /** diff --git a/stream/src/main/java/com/annimon/stream/LongStream.java b/stream/src/main/java/com/annimon/stream/LongStream.java index 992db982..123bd61a 100644 --- a/stream/src/main/java/com/annimon/stream/LongStream.java +++ b/stream/src/main/java/com/annimon/stream/LongStream.java @@ -1,18 +1,8 @@ package com.annimon.stream; -import com.annimon.stream.function.Function; -import com.annimon.stream.function.LongBinaryOperator; -import com.annimon.stream.function.LongConsumer; -import com.annimon.stream.function.LongFunction; -import com.annimon.stream.function.LongPredicate; -import com.annimon.stream.function.LongSupplier; -import com.annimon.stream.function.LongToDoubleFunction; -import com.annimon.stream.function.LongToIntFunction; -import com.annimon.stream.function.LongUnaryOperator; -import com.annimon.stream.function.ObjLongConsumer; -import com.annimon.stream.function.Supplier; -import com.annimon.stream.function.ToLongFunction; -import java.util.Arrays; +import com.annimon.stream.operator.*; +import com.annimon.stream.function.*; +import com.annimon.stream.internal.Operators; import java.util.Comparator; import java.util.NoSuchElementException; @@ -71,20 +61,7 @@ public static LongStream of(PrimitiveIterator.OfLong iterator) { */ public static LongStream of(final long... values) { Objects.requireNonNull(values); - return new LongStream(new PrimitiveIterator.OfLong() { - - private int index = 0; - - @Override - public boolean hasNext() { - return index < values.length; - } - - @Override - public long nextLong() { - return values[index++]; - } - }); + return new LongStream(new LongArray(values)); } /** @@ -94,21 +71,7 @@ public long nextLong() { * @return the new stream */ public static LongStream of(final long t) { - return new LongStream(new PrimitiveIterator.OfLong() { - - private int index = 0; - - @Override - public boolean hasNext() { - return index == 0; - } - - @Override - public long nextLong() { - index++; - return t; - } - }); + return new LongStream(new LongSingleElement(t)); } /** @@ -143,25 +106,7 @@ public static LongStream rangeClosed(final long startInclusive, final long endIn return empty(); } else if (startInclusive == endInclusive) { return of(startInclusive); - } else return new LongStream(new PrimitiveIterator.OfLong() { - - private long current = startInclusive; - private boolean hasNext = current <= endInclusive; - - @Override - public boolean hasNext() { - return hasNext; - } - - @Override - public long nextLong() { - if (current >= endInclusive) { - hasNext = false; - return endInclusive; - } - return current++; - } - }); + } else return new LongStream(new LongRangeClosed(startInclusive, endInclusive)); } /** @@ -173,18 +118,7 @@ public long nextLong() { */ public static LongStream generate(final LongSupplier s) { Objects.requireNonNull(s); - return new LongStream(new PrimitiveIterator.OfLong() { - - @Override - public boolean hasNext() { - return true; - } - - @Override - public long nextLong() { - return s.getAsLong(); - } - }); + return new LongStream(new LongGenerate(s)); } /** @@ -211,22 +145,7 @@ public long nextLong() { */ public static LongStream iterate(final long seed, final LongUnaryOperator f) { Objects.requireNonNull(f); - return new LongStream(new PrimitiveIterator.OfLong() { - - private long current = seed; - - @Override - public boolean hasNext() { - return true; - } - - @Override - public long nextLong() { - final long old = current; - current = f.applyAsLong(current); - return old; - } - }); + return new LongStream(new LongIterate(seed, f)); } /** @@ -272,28 +191,7 @@ public static LongStream iterate(final long seed, public static LongStream concat(final LongStream a, final LongStream b) { Objects.requireNonNull(a); Objects.requireNonNull(b); - final PrimitiveIterator.OfLong it1 = a.iterator; - final PrimitiveIterator.OfLong it2 = b.iterator; - return new LongStream(new PrimitiveIterator.OfLong() { - - private boolean firstStreamIsCurrent = true; - - @Override - public boolean hasNext() { - if (firstStreamIsCurrent) { - if (it1.hasNext()) - return true; - - firstStreamIsCurrent = false; - } - return it2.hasNext(); - } - - @Override - public long nextLong() { - return firstStreamIsCurrent ? it1.nextLong() : it2.nextLong(); - } - }); + return new LongStream(new LongConcat(a.iterator, b.iterator)); } @@ -421,26 +319,7 @@ public Stream boxed() { * @return the new stream */ public LongStream filter(final LongPredicate predicate) { - return new LongStream(new PrimitiveIterator.OfLong() { - - private long next; - - @Override - public boolean hasNext() { - while (iterator.hasNext()) { - next = iterator.next(); - if (predicate.test(next)) { - return true; - } - } - return false; - } - - @Override - public long nextLong() { - return next; - } - }); + return new LongStream(new LongFilter(iterator, predicate)); } /** @@ -473,18 +352,7 @@ public LongStream filterNot(final LongPredicate predicate) { * @see Stream#map(com.annimon.stream.function.Function) */ public LongStream map(final LongUnaryOperator mapper) { - return new LongStream(new PrimitiveIterator.OfLong() { - - @Override - public boolean hasNext() { - return iterator.hasNext(); - } - - @Override - public long nextLong() { - return mapper.applyAsLong(iterator.nextLong()); - } - }); + return new LongStream(new LongMap(iterator, mapper)); } /** @@ -498,18 +366,7 @@ public long nextLong() { * @return the new {@code Stream} */ public Stream mapToObj(final LongFunction mapper) { - return Stream.of(new LsaIterator() { - - @Override - public boolean hasNext() { - return iterator.hasNext(); - } - - @Override - public R nextIteration() { - return mapper.apply(iterator.nextLong()); - } - }); + return Stream.of(new LongMapToObj(iterator, mapper)); } /** @@ -522,18 +379,7 @@ public R nextIteration() { * @return the new {@code IntStream} */ public IntStream mapToInt(final LongToIntFunction mapper) { - return IntStream.of(new PrimitiveIterator.OfInt() { - - @Override - public boolean hasNext() { - return iterator.hasNext(); - } - - @Override - public int nextInt() { - return mapper.applyAsInt(iterator.nextLong()); - } - }); + return IntStream.of(new LongMapToInt(iterator, mapper)); } /** @@ -546,18 +392,7 @@ public int nextInt() { * @return the new {@code DoubleStream} */ public DoubleStream mapToDouble(final LongToDoubleFunction mapper) { - return DoubleStream.of(new PrimitiveIterator.OfDouble() { - - @Override - public boolean hasNext() { - return iterator.hasNext(); - } - - @Override - public double nextDouble() { - return mapper.applyAsDouble(iterator.nextLong()); - } - }); + return DoubleStream.of(new LongMapToDouble(iterator, mapper)); } /** @@ -579,37 +414,7 @@ public double nextDouble() { * @see Stream#flatMap(com.annimon.stream.function.Function) */ public LongStream flatMap(final LongFunction mapper) { - return new LongStream(new PrimitiveIterator.OfLong() { - - private PrimitiveIterator.OfLong inner; - - @Override - public boolean hasNext() { - if (inner != null && inner.hasNext()) { - return true; - } - while (iterator.hasNext()) { - final long arg = iterator.next(); - final LongStream result = mapper.apply(arg); - if (result == null) { - continue; - } - if (result.iterator.hasNext()) { - inner = result.iterator; - return true; - } - } - return false; - } - - @Override - public long nextLong() { - if (inner == null) { - throw new NoSuchElementException(); - } - return inner.nextLong(); - } - }); + return new LongStream(new LongFlatMap(iterator, mapper)); } /** @@ -643,23 +448,7 @@ public LongStream distinct() { * @return the new stream */ public LongStream sorted() { - return new LongStream(new PrimitiveExtIterator.OfLong() { - - private int index = 0; - private long[] array; - - @Override - protected void nextIteration() { - if (!isInit) { - array = toArray(); - Arrays.sort(array); - } - hasNext = index < array.length; - if (hasNext) { - next = array[index++]; - } - } - }); + return new LongStream(new LongSorted(iterator)); } /** @@ -702,24 +491,7 @@ public LongStream sorted(Comparator comparator) { public LongStream sample(final int stepWidth) { if (stepWidth <= 0) throw new IllegalArgumentException("stepWidth cannot be zero or negative"); if (stepWidth == 1) return this; - return new LongStream(new PrimitiveIterator.OfLong() { - - @Override - public boolean hasNext() { - return iterator.hasNext(); - } - - @Override - public long nextLong() { - final long result = iterator.nextLong(); - int skip = 1; - while (skip < stepWidth && iterator.hasNext()) { - iterator.nextLong(); - skip++; - } - return result; - } - }); + return new LongStream(new LongSample(iterator, stepWidth)); } /** @@ -731,20 +503,7 @@ public long nextLong() { * @return the new stream */ public LongStream peek(final LongConsumer action) { - return new LongStream(new PrimitiveIterator.OfLong() { - - @Override - public boolean hasNext() { - return iterator.hasNext(); - } - - @Override - public long nextLong() { - long value = iterator.nextLong(); - action.accept(value); - return value; - } - }); + return new LongStream(new LongPeek(iterator, action)); } /** @@ -769,21 +528,7 @@ public long nextLong() { */ public LongStream scan(final LongBinaryOperator accumulator) { Objects.requireNonNull(accumulator); - return new LongStream(new PrimitiveExtIterator.OfLong() { - - @Override - protected void nextIteration() { - hasNext = iterator.hasNext(); - if (hasNext) { - final long current = iterator.next(); - if (isInit) { - next = accumulator.applyAsLong(next, current); - } else { - next = current; - } - } - } - }); + return new LongStream(new LongScan(iterator, accumulator)); } /** @@ -810,23 +555,7 @@ protected void nextIteration() { */ public LongStream scan(final long identity, final LongBinaryOperator accumulator) { Objects.requireNonNull(accumulator); - return new LongStream(new PrimitiveExtIterator.OfLong() { - - @Override - protected void nextIteration() { - if (!isInit) { - // Return identity - hasNext = true; - next = identity; - return; - } - hasNext = iterator.hasNext(); - if (hasNext) { - final long current = iterator.next(); - next = accumulator.applyAsLong(next, current); - } - } - }); + return new LongStream(new LongScanIdentity(iterator, identity, accumulator)); } /** @@ -845,14 +574,7 @@ protected void nextIteration() { * @return the new {@code LongStream} */ public LongStream takeWhile(final LongPredicate predicate) { - return new LongStream(new PrimitiveExtIterator.OfLong() { - - @Override - protected void nextIteration() { - hasNext = iterator.hasNext() - && predicate.test(next = iterator.next()); - } - }); + return new LongStream(new LongTakeWhile(iterator, predicate)); } /** @@ -874,16 +596,7 @@ protected void nextIteration() { * @since 1.1.6 */ public LongStream takeUntil(final LongPredicate stopPredicate) { - return new LongStream(new PrimitiveExtIterator.OfLong() { - - @Override - protected void nextIteration() { - hasNext = iterator.hasNext() && !(isInit && stopPredicate.test(next)); - if (hasNext) { - next = iterator.next(); - } - } - }); + return new LongStream(new LongTakeUntil(iterator, stopPredicate)); } /** @@ -902,26 +615,7 @@ protected void nextIteration() { * @return the new {@code LongStream} */ public LongStream dropWhile(final LongPredicate predicate) { - return new LongStream(new PrimitiveExtIterator.OfLong() { - - @Override - protected void nextIteration() { - if (!isInit) { - // Skip first time - while (hasNext = iterator.hasNext()) { - next = iterator.next(); - if (!predicate.test(next)) { - return; - } - } - } - - hasNext = hasNext && iterator.hasNext(); - if (!hasNext) return; - - next = iterator.next(); - } - }); + return new LongStream(new LongDropWhile(iterator, predicate)); } /** @@ -948,21 +642,7 @@ protected void nextIteration() { public LongStream limit(final long maxSize) { if (maxSize < 0) throw new IllegalArgumentException("maxSize cannot be negative"); if (maxSize == 0) return LongStream.empty(); - return new LongStream(new PrimitiveIterator.OfLong() { - - private long index = 0; - - @Override - public boolean hasNext() { - return (index < maxSize) && iterator.hasNext(); - } - - @Override - public long nextLong() { - index++; - return iterator.nextLong(); - } - }); + return new LongStream(new LongLimit(iterator, maxSize)); } /** @@ -990,25 +670,7 @@ public long nextLong() { public LongStream skip(final long n) { if (n < 0) throw new IllegalArgumentException("n cannot be negative"); if (n == 0) return this; - return new LongStream(new PrimitiveIterator.OfLong() { - - private long skippedCount = 0; - - @Override - public boolean hasNext() { - while (iterator.hasNext()) { - if (skippedCount == n) break; - iterator.nextLong(); - skippedCount++; - } - return iterator.hasNext(); - } - - @Override - public long nextLong() { - return iterator.nextLong(); - } - }); + return new LongStream(new LongSkip(iterator, n)); } /** @@ -1096,9 +758,7 @@ public OptionalLong reduce(LongBinaryOperator accumulator) { * @return an array containing the elements of this stream */ public long[] toArray() { - SpinedBuffer.OfLong b = new SpinedBuffer.OfLong(); - forEach(b); - return b.asPrimitiveArray(); + return Operators.toLongArray(iterator); } /** diff --git a/stream/src/main/java/com/annimon/stream/LsaIterator.java b/stream/src/main/java/com/annimon/stream/LsaIterator.java index e7c8c0d5..c959f2a9 100644 --- a/stream/src/main/java/com/annimon/stream/LsaIterator.java +++ b/stream/src/main/java/com/annimon/stream/LsaIterator.java @@ -6,7 +6,7 @@ /** * Abstract iterator with implemented {@code remove} method. */ -abstract class LsaIterator implements Iterator { +public abstract class LsaIterator implements Iterator { @Override public void remove() { diff --git a/stream/src/main/java/com/annimon/stream/Stream.java b/stream/src/main/java/com/annimon/stream/Stream.java index bd06a965..d5ff4177 100644 --- a/stream/src/main/java/com/annimon/stream/Stream.java +++ b/stream/src/main/java/com/annimon/stream/Stream.java @@ -1,16 +1,15 @@ package com.annimon.stream; import com.annimon.stream.function.*; +import com.annimon.stream.internal.Operators; +import com.annimon.stream.operator.*; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; -import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.NoSuchElementException; -import java.util.Queue; -import java.util.Set; /** * A sequence of elements supporting aggregate operations. @@ -79,20 +78,7 @@ public static Stream of(Iterable iterable) { */ public static Stream of(final T... elements) { Objects.requireNonNull(elements); - return new Stream(new LsaIterator() { - - private int index = 0; - - @Override - public boolean hasNext() { - return index < elements.length; - } - - @Override - public T nextIteration() { - return elements[index++]; - } - }); + return new Stream(new ObjArray(elements)); } /** @@ -237,18 +223,7 @@ public static Stream ofRangeClosed(final long from, final long to) { */ public static Stream generate(final Supplier supplier) { Objects.requireNonNull(supplier); - return new Stream(new LsaIterator() { - - @Override - public boolean hasNext() { - return true; - } - - @Override - public T nextIteration() { - return supplier.get(); - } - }); + return new Stream(new ObjGenerate(supplier)); } /** @@ -271,27 +246,7 @@ public T nextIteration() { */ public static Stream iterate(final T seed, final UnaryOperator op) { Objects.requireNonNull(op); - return new Stream(new LsaIterator() { - - private boolean firstRun = true; - private T t; - - @Override - public boolean hasNext() { - return true; - } - - @Override - public T nextIteration() { - if (firstRun) { - firstRun = false; - t = seed; - } else { - t = op.apply(t); - } - return t; - } - }); + return new Stream(new ObjIterate(seed, op)); } /** @@ -339,25 +294,7 @@ public static Stream iterate(final T seed, public static Stream concat(Stream stream1, Stream stream2) { Objects.requireNonNull(stream1); Objects.requireNonNull(stream2); - final Iterator it1 = stream1.iterator; - final Iterator it2 = stream2.iterator; - return new Stream(new LsaExtIterator() { - - @Override - protected void nextIteration() { - if (it1.hasNext()) { - next = it1.next(); - hasNext = true; - return; - } - if (it2.hasNext()) { - next = it2.next(); - hasNext = true; - return; - } - hasNext = false; - } - }); + return new Stream(new ObjConcat(stream1.iterator, stream2.iterator)); } /** @@ -384,7 +321,7 @@ public static Stream zip(Stream stream1, Stream combiner) { Objects.requireNonNull(stream1); Objects.requireNonNull(stream2); - return zip(stream1.iterator, stream2.iterator, combiner); + return Stream.zip(stream1.iterator, stream2.iterator, combiner); } /** @@ -413,24 +350,11 @@ public static Stream zip(final Iterator iterator1, final BiFunction combiner) { Objects.requireNonNull(iterator1); Objects.requireNonNull(iterator2); - return new Stream(new LsaIterator() { - @Override - public boolean hasNext() { - return iterator1.hasNext() && iterator2.hasNext(); - } - - @Override - public R nextIteration() { - return combiner.apply(iterator1.next(), iterator2.next()); - } - }); + return new Stream(new ObjZip(iterator1, iterator2, combiner)); } // - static final long MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8; - static final String BAD_SIZE = "Stream size exceeds max array size"; - private final Iterator iterator; private Stream(Iterator iterator) { @@ -538,48 +462,7 @@ public R custom(Function, R> function) { * @return the new stream */ public Stream filter(final Predicate predicate) { - return new Stream(new Iterator() { - - private boolean hasNext, hasNextEvaluated; - private T next; - - @Override - public boolean hasNext() { - if (!hasNextEvaluated) { - nextIteration(); - hasNextEvaluated = true; - } - return hasNext; - } - - @Override - public T next() { - if (!hasNextEvaluated) { - hasNext = hasNext(); - } - if (!hasNext) { - throw new NoSuchElementException(); - } - hasNextEvaluated = false; - return next; - } - - private void nextIteration() { - while (iterator.hasNext()) { - next = iterator.next(); - if (predicate.test(next)) { - hasNext = true; - return; - } - } - hasNext = false; - } - - @Override - public void remove() { - throw new UnsupportedOperationException("remove not supported"); - } - }); + return new Stream(new ObjFilter(iterator, predicate)); } /** @@ -653,18 +536,7 @@ public boolean test(T value) { * @return the new stream */ public Stream map(final Function mapper) { - return new Stream(new LsaIterator() { - - @Override - public boolean hasNext() { - return iterator.hasNext(); - } - - @Override - public R nextIteration() { - return mapper.apply(iterator.next()); - } - }); + return new Stream(new ObjMap(iterator, mapper)); } /** @@ -677,18 +549,7 @@ public R nextIteration() { * @see #map(com.annimon.stream.function.Function) */ public IntStream mapToInt(final ToIntFunction mapper) { - return IntStream.of(new PrimitiveIterator.OfInt() { - - @Override - public boolean hasNext() { - return iterator.hasNext(); - } - - @Override - public int nextInt() { - return mapper.applyAsInt(iterator.next()); - } - }); + return IntStream.of(new ObjMapToInt(iterator, mapper)); } /** @@ -702,18 +563,7 @@ public int nextInt() { * @see #map(com.annimon.stream.function.Function) */ public LongStream mapToLong(final ToLongFunction mapper) { - return LongStream.of(new PrimitiveIterator.OfLong() { - - @Override - public boolean hasNext() { - return iterator.hasNext(); - } - - @Override - public long nextLong() { - return mapper.applyAsLong(iterator.next()); - } - }); + return LongStream.of(new ObjMapToLong(iterator, mapper)); } /** @@ -727,18 +577,7 @@ public long nextLong() { * @see #map(com.annimon.stream.function.Function) */ public DoubleStream mapToDouble(final ToDoubleFunction mapper) { - return DoubleStream.of(new PrimitiveIterator.OfDouble() { - - @Override - public boolean hasNext() { - return iterator.hasNext(); - } - - @Override - public double nextDouble() { - return mapper.applyAsDouble(iterator.next()); - } - }); + return DoubleStream.of(new ObjMapToDouble(iterator, mapper)); } /** @@ -760,34 +599,7 @@ public double nextDouble() { * @return the new stream */ public Stream flatMap(final Function> mapper) { - return new Stream(new LsaExtIterator() { - - private Iterator inner; - - @Override - protected void nextIteration() { - if ((inner != null) && inner.hasNext()) { - next = inner.next(); - hasNext = true; - return; - } - while (iterator.hasNext()) { - if (inner == null || !inner.hasNext()) { - final T arg = iterator.next(); - final Stream result = mapper.apply(arg); - if (result != null) { - inner = result.iterator; - } - } - if ((inner != null) && inner.hasNext()) { - next = inner.next(); - hasNext = true; - return; - } - } - hasNext = false; - } - }); + return new Stream(new ObjFlatMap(iterator, mapper)); } /** @@ -802,34 +614,7 @@ protected void nextIteration() { * @see #flatMap(com.annimon.stream.function.Function) */ public IntStream flatMapToInt(final Function mapper) { - return IntStream.of(new PrimitiveExtIterator.OfInt() { - - private PrimitiveIterator.OfInt inner; - - @Override - protected void nextIteration() { - if ((inner != null) && inner.hasNext()) { - next = inner.next(); - hasNext = true; - return; - } - while (iterator.hasNext()) { - if (inner == null || !inner.hasNext()) { - final T arg = iterator.next(); - final IntStream result = mapper.apply(arg); - if (result != null) { - inner = result.iterator(); - } - } - if ((inner != null) && inner.hasNext()) { - next = inner.next(); - hasNext = true; - return; - } - } - hasNext = false; - } - }); + return IntStream.of(new ObjFlatMapToInt(iterator, mapper)); } /** @@ -844,34 +629,7 @@ protected void nextIteration() { * @see #flatMap(com.annimon.stream.function.Function) */ public LongStream flatMapToLong(final Function mapper) { - return LongStream.of(new PrimitiveExtIterator.OfLong() { - - private PrimitiveIterator.OfLong inner; - - @Override - protected void nextIteration() { - if ((inner != null) && inner.hasNext()) { - next = inner.next(); - hasNext = true; - return; - } - while (iterator.hasNext()) { - if (inner == null || !inner.hasNext()) { - final T arg = iterator.next(); - final LongStream result = mapper.apply(arg); - if (result != null) { - inner = result.iterator(); - } - } - if ((inner != null) && inner.hasNext()) { - next = inner.next(); - hasNext = true; - return; - } - } - hasNext = false; - } - }); + return LongStream.of(new ObjFlatMapToLong(iterator, mapper)); } /** @@ -886,34 +644,7 @@ protected void nextIteration() { * @see #flatMap(com.annimon.stream.function.Function) */ public DoubleStream flatMapToDouble(final Function mapper) { - return DoubleStream.of(new PrimitiveExtIterator.OfDouble() { - - private PrimitiveIterator.OfDouble inner; - - @Override - protected void nextIteration() { - if ((inner != null) && inner.hasNext()) { - next = inner.next(); - hasNext = true; - return; - } - while (iterator.hasNext()) { - if (inner == null || !inner.hasNext()) { - final T arg = iterator.next(); - final DoubleStream result = mapper.apply(arg); - if (result != null) { - inner = result.iterator(); - } - } - if ((inner != null) && inner.hasNext()) { - next = inner.next(); - hasNext = true; - return; - } - } - hasNext = false; - } - }); + return DoubleStream.of(new ObjFlatMapToDouble(iterator, mapper)); } /** @@ -978,21 +709,7 @@ public IntPair apply(T value) { * @return the new stream */ public Stream distinct() { - return new Stream(new LsaExtIterator() { - - private final Set set = new HashSet(); - - @Override - protected void nextIteration() { - while (hasNext = iterator.hasNext()) { - next = iterator.next(); - if (!set.contains(next)) { - set.add(next); - return; - } - } - } - }); + return new Stream(new ObjDistinct(iterator)); } /** @@ -1039,23 +756,7 @@ public int compare(T o1, T o2) { * @return the new stream */ public Stream sorted(final Comparator comparator) { - return new Stream(new LsaExtIterator() { - - private Iterator sortedIterator; - - @Override - protected void nextIteration() { - if (!isInit) { - final List list = toList(); - Collections.sort(list, comparator); - sortedIterator = list.iterator(); - } - hasNext = sortedIterator.hasNext(); - if (hasNext) { - next = sortedIterator.next(); - } - } - }); + return new Stream(new ObjSorted(iterator, comparator)); } /** @@ -1120,42 +821,7 @@ public Stream>> groupBy(final Function Stream> chunkBy(final Function classifier) { - return new Stream>(new LsaIterator>() { - private T next; - private boolean peekedNext; - - @Override - public boolean hasNext() { - return peekedNext || iterator.hasNext(); - } - - @Override - public List nextIteration() { - K key = classifier.apply(peek()); - - List list = new ArrayList(); - do { - list.add(takeNext()); - } - while (iterator.hasNext() && key.equals(classifier.apply(peek()))); - - return list; - } - - private T takeNext() { - T element = peek(); - peekedNext = false; - return element; - } - - private T peek() { - if (!peekedNext) { - next = iterator.next(); - peekedNext = true; - } - return next; - } - }); + return new Stream>(new ObjChunkBy(iterator, classifier)); } /** @@ -1240,39 +906,7 @@ public Stream> slidingWindow(final int windowSize) { public Stream> slidingWindow(final int windowSize, final int stepWidth) { if (windowSize <= 0) throw new IllegalArgumentException("windowSize cannot be zero or negative"); if (stepWidth <= 0) throw new IllegalArgumentException("stepWidth cannot be zero or negative"); - return new Stream>(new LsaIterator>() { - private final Queue queue = Compat.queue(); - - @Override - public boolean hasNext() { - return iterator.hasNext(); - } - - @Override - public List nextIteration() { - int i = queue.size(); - while (i < windowSize && iterator.hasNext()) { - queue.offer(iterator.next()); - i++; - } - - // the elements that are currently in the queue are the elements of our current window - List list = new ArrayList(queue); - - // remove stepWidth elements from the queue - final int pollCount = Math.min(queue.size(), stepWidth); - for (int j = 0; j < pollCount; j++) { - queue.poll(); - } - - // if the stepWidth is greater than the windowSize, skip (stepWidth - windowSize) elements - for (int j = windowSize; j < stepWidth && iterator.hasNext(); j++) { - iterator.next(); - } - - return list; - } - }); + return new Stream>(new ObjSlidingWindow(iterator, windowSize, stepWidth)); } /** @@ -1284,20 +918,7 @@ public List nextIteration() { * @return the new stream */ public Stream peek(final Consumer action) { - return new Stream(new LsaIterator() { - - @Override - public boolean hasNext() { - return iterator.hasNext(); - } - - @Override - public T nextIteration() { - final T value = iterator.next(); - action.accept(value); - return value; - } - }); + return new Stream(new ObjPeek(iterator, action)); } /** @@ -1322,21 +943,7 @@ public T nextIteration() { */ public Stream scan(final BiFunction accumulator) { Objects.requireNonNull(accumulator); - return new Stream(new LsaExtIterator() { - - @Override - protected void nextIteration() { - hasNext = iterator.hasNext(); - if (hasNext) { - final T value = iterator.next(); - if (isInit) { - next = accumulator.apply(next, value); - } else { - next = value; - } - } - } - }); + return new Stream(new ObjScan(iterator, accumulator)); } /** @@ -1364,23 +971,7 @@ protected void nextIteration() { */ public Stream scan(final R identity, final BiFunction accumulator) { Objects.requireNonNull(accumulator); - return new Stream(new LsaExtIterator() { - - @Override - protected void nextIteration() { - if (!isInit) { - // Return identity - hasNext = true; - next = identity; - return; - } - hasNext = iterator.hasNext(); - if (hasNext) { - final T t = iterator.next(); - next = accumulator.apply(next, t); - } - } - }); + return new Stream(new ObjScanIdentity(iterator, identity, accumulator)); } /** @@ -1399,14 +990,7 @@ protected void nextIteration() { * @return the new stream */ public Stream takeWhile(final Predicate predicate) { - return new Stream(new LsaExtIterator() { - - @Override - protected void nextIteration() { - hasNext = iterator.hasNext() - && predicate.test(next = iterator.next()); - } - }); + return new Stream(new ObjTakeWhile(iterator, predicate)); } /** @@ -1428,14 +1012,7 @@ protected void nextIteration() { * @since 1.1.6 */ public Stream takeUntil(final Predicate stopPredicate) { - return new Stream(new LsaExtIterator() { - - @Override - protected void nextIteration() { - hasNext = iterator.hasNext() && !(isInit && stopPredicate.test(next)); - next = hasNext ? iterator.next() : null; - } - }); + return new Stream(new ObjTakeUntil(iterator, stopPredicate)); } /** @@ -1454,26 +1031,7 @@ protected void nextIteration() { * @return the new stream */ public Stream dropWhile(final Predicate predicate) { - return new Stream(new LsaExtIterator() { - - @Override - protected void nextIteration() { - if (!isInit) { - // Skip first time - while (hasNext = iterator.hasNext()) { - next = iterator.next(); - if (!predicate.test(next)) { - return; - } - } - } - - hasNext = hasNext && iterator.hasNext(); - if (!hasNext) return; - - next = iterator.next(); - } - }); + return new Stream(new ObjDropWhile(iterator, predicate)); } /** @@ -1503,21 +1061,7 @@ public Stream limit(final long maxSize) { if (maxSize == 0) { return Stream.empty(); } - return new Stream(new LsaIterator() { - - private long index = 0; - - @Override - public boolean hasNext() { - return (index < maxSize) && iterator.hasNext(); - } - - @Override - public T nextIteration() { - index++; - return iterator.next(); - } - }); + return new Stream(new ObjLimit(iterator, maxSize)); } /** @@ -1544,25 +1088,7 @@ public T nextIteration() { public Stream skip(final long n) { if (n < 0) throw new IllegalArgumentException("n cannot be negative"); if (n == 0) return this; - return new Stream(new LsaIterator() { - - private long skippedCount; - - @Override - public boolean hasNext() { - while (skippedCount < n) { - if (!iterator.hasNext()) return false; - iterator.next(); - skippedCount++; - } - return iterator.hasNext(); - } - - @Override - public T nextIteration() { - return iterator.next(); - } - }); + return new Stream(new ObjSkip(iterator, n)); } /** @@ -1656,20 +1182,8 @@ public Object[] apply(int value) { * @param generator the array constructor reference that accommodates future array of assigned size * @return the result of collect elements */ - @SuppressWarnings("unchecked") public R[] toArray(IntFunction generator) { - final List container = toList(); - final int size = container.size(); - - if (size >= MAX_ARRAY_SIZE) throw new IllegalArgumentException(BAD_SIZE); - - //noinspection unchecked - T[] source = container.toArray(Compat.newArray(size)); - R[] boxed = generator.apply(size); - - //noinspection SuspiciousSystemArraycopy - System.arraycopy(source, 0, boxed, 0, size); - return boxed; + return Operators.toArray(iterator, generator); } /** diff --git a/stream/src/main/java/com/annimon/stream/Compat.java b/stream/src/main/java/com/annimon/stream/internal/Compat.java similarity index 60% rename from stream/src/main/java/com/annimon/stream/Compat.java rename to stream/src/main/java/com/annimon/stream/internal/Compat.java index 6c22a1b1..54937aa8 100644 --- a/stream/src/main/java/com/annimon/stream/Compat.java +++ b/stream/src/main/java/com/annimon/stream/internal/Compat.java @@ -1,4 +1,4 @@ -package com.annimon.stream; +package com.annimon.stream.internal; import java.lang.reflect.Array; import java.util.ArrayDeque; @@ -9,9 +9,12 @@ /** * Compatibility methods for Android API < 9. */ -final class Compat { +public final class Compat { - static Queue queue() { + static final long MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8; + private static final String BAD_SIZE = "Stream size exceeds max array size"; + + public static Queue queue() { // ArrayDeque was introduced in Android 2.3 try { return new ArrayDeque(); @@ -21,7 +24,7 @@ static Queue queue() { } @SafeVarargs - static E[] newArray(int length, E... array) { + public static E[] newArray(int length, E... array) { try { return Arrays.copyOf(array, length); } catch (NoSuchMethodError nme) { @@ -30,9 +33,15 @@ static E[] newArray(int length, E... array) { } @SuppressWarnings("unchecked") - static E[] newArrayCompat(E[] array, int length) { + public static E[] newArrayCompat(E[] array, int length) { final E[] res = (E[]) Array.newInstance(array.getClass().getComponentType(), length); System.arraycopy(array, 0, res, 0, Math.min(length, array.length)); return res; } + + static void checkMaxArraySize(long size) { + if (size >= MAX_ARRAY_SIZE) { + throw new IllegalArgumentException(BAD_SIZE); + } + } } diff --git a/stream/src/main/java/com/annimon/stream/internal/Operators.java b/stream/src/main/java/com/annimon/stream/internal/Operators.java new file mode 100644 index 00000000..9fd6dad5 --- /dev/null +++ b/stream/src/main/java/com/annimon/stream/internal/Operators.java @@ -0,0 +1,60 @@ +package com.annimon.stream.internal; + +import com.annimon.stream.PrimitiveIterator; +import com.annimon.stream.function.IntFunction; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +public final class Operators { + + private Operators() {} + + public static List toList(Iterator iterator) { + final List result = new ArrayList(); + while (iterator.hasNext()) { + result.add(iterator.next()); + } + return result; + } + + @SuppressWarnings("unchecked") + public static R[] toArray(Iterator iterator, IntFunction generator) { + final List container = Operators.toList(iterator); + final int size = container.size(); + + Compat.checkMaxArraySize(size); + + //noinspection unchecked + T[] source = container.toArray(Compat.newArray(size)); + R[] boxed = generator.apply(size); + + //noinspection SuspiciousSystemArraycopy + System.arraycopy(source, 0, boxed, 0, size); + return boxed; + } + + public static int[] toIntArray(PrimitiveIterator.OfInt iterator) { + final SpinedBuffer.OfInt b = new SpinedBuffer.OfInt(); + while (iterator.hasNext()) { + b.accept(iterator.nextInt()); + } + return b.asPrimitiveArray(); + } + + public static long[] toLongArray(PrimitiveIterator.OfLong iterator) { + final SpinedBuffer.OfLong b = new SpinedBuffer.OfLong(); + while (iterator.hasNext()) { + b.accept(iterator.nextLong()); + } + return b.asPrimitiveArray(); + } + + public static double[] toDoubleArray(PrimitiveIterator.OfDouble iterator) { + final SpinedBuffer.OfDouble b = new SpinedBuffer.OfDouble(); + while (iterator.hasNext()) { + b.accept(iterator.nextDouble()); + } + return b.asPrimitiveArray(); + } +} diff --git a/stream/src/main/java/com/annimon/stream/SpinedBuffer.java b/stream/src/main/java/com/annimon/stream/internal/SpinedBuffer.java similarity index 98% rename from stream/src/main/java/com/annimon/stream/SpinedBuffer.java rename to stream/src/main/java/com/annimon/stream/internal/SpinedBuffer.java index be53664d..ec717629 100644 --- a/stream/src/main/java/com/annimon/stream/SpinedBuffer.java +++ b/stream/src/main/java/com/annimon/stream/internal/SpinedBuffer.java @@ -1,5 +1,6 @@ -package com.annimon.stream; +package com.annimon.stream.internal; +import com.annimon.stream.PrimitiveIterator; import com.annimon.stream.function.DoubleConsumer; import com.annimon.stream.function.IntConsumer; import com.annimon.stream.function.LongConsumer; @@ -192,11 +193,10 @@ void copyInto(T_ARR array, int offset) { } } - T_ARR asPrimitiveArray() { + public T_ARR asPrimitiveArray() { long size = count(); - if (size >= Stream.MAX_ARRAY_SIZE) - throw new IllegalArgumentException(Stream.BAD_SIZE); + Compat.checkMaxArraySize(size); T_ARR result = newArray((int) size); copyInto(result, 0); diff --git a/stream/src/main/java/com/annimon/stream/operator/DoubleArray.java b/stream/src/main/java/com/annimon/stream/operator/DoubleArray.java new file mode 100644 index 00000000..9e0866b2 --- /dev/null +++ b/stream/src/main/java/com/annimon/stream/operator/DoubleArray.java @@ -0,0 +1,24 @@ +package com.annimon.stream.operator; + +import com.annimon.stream.PrimitiveIterator; + +public class DoubleArray extends PrimitiveIterator.OfDouble { + + private final double[] values; + private int index; + + public DoubleArray(double[] values) { + this.values = values; + index = 0; + } + + @Override + public double nextDouble() { + return values[index++]; + } + + @Override + public boolean hasNext() { + return index < values.length; + } +} diff --git a/stream/src/main/java/com/annimon/stream/operator/DoubleConcat.java b/stream/src/main/java/com/annimon/stream/operator/DoubleConcat.java new file mode 100644 index 00000000..91850d4d --- /dev/null +++ b/stream/src/main/java/com/annimon/stream/operator/DoubleConcat.java @@ -0,0 +1,32 @@ +package com.annimon.stream.operator; + +import com.annimon.stream.PrimitiveIterator; + +public class DoubleConcat extends PrimitiveIterator.OfDouble { + + private final PrimitiveIterator.OfDouble iterator1; + private final PrimitiveIterator.OfDouble iterator2; + private boolean firstStreamIsCurrent; + + public DoubleConcat(PrimitiveIterator.OfDouble iterator1, PrimitiveIterator.OfDouble iterator2) { + this.iterator1 = iterator1; + this.iterator2 = iterator2; + firstStreamIsCurrent = true; + } + + @Override + public boolean hasNext() { + if (firstStreamIsCurrent) { + if (iterator1.hasNext()) { + return true; + } + firstStreamIsCurrent = false; + } + return iterator2.hasNext(); + } + + @Override + public double nextDouble() { + return firstStreamIsCurrent ? iterator1.nextDouble() : iterator2.nextDouble(); + } +} diff --git a/stream/src/main/java/com/annimon/stream/operator/DoubleDropWhile.java b/stream/src/main/java/com/annimon/stream/operator/DoubleDropWhile.java new file mode 100644 index 00000000..56351b5c --- /dev/null +++ b/stream/src/main/java/com/annimon/stream/operator/DoubleDropWhile.java @@ -0,0 +1,34 @@ +package com.annimon.stream.operator; + +import com.annimon.stream.PrimitiveExtIterator; +import com.annimon.stream.PrimitiveIterator; +import com.annimon.stream.function.DoublePredicate; + +public class DoubleDropWhile extends PrimitiveExtIterator.OfDouble { + + private final PrimitiveIterator.OfDouble iterator; + private final DoublePredicate predicate; + + public DoubleDropWhile(PrimitiveIterator.OfDouble iterator, DoublePredicate predicate) { + this.iterator = iterator; + this.predicate = predicate; + } + + @Override + protected void nextIteration() { + if (!isInit) { + // Skip first time + while (hasNext = iterator.hasNext()) { + next = iterator.next(); + if (!predicate.test(next)) { + return; + } + } + } + + hasNext = hasNext && iterator.hasNext(); + if (!hasNext) return; + + next = iterator.next(); + } +} diff --git a/stream/src/main/java/com/annimon/stream/operator/DoubleFilter.java b/stream/src/main/java/com/annimon/stream/operator/DoubleFilter.java new file mode 100644 index 00000000..af0d643c --- /dev/null +++ b/stream/src/main/java/com/annimon/stream/operator/DoubleFilter.java @@ -0,0 +1,33 @@ +package com.annimon.stream.operator; + +import com.annimon.stream.PrimitiveIterator; +import com.annimon.stream.function.DoublePredicate; + +public class DoubleFilter extends PrimitiveIterator.OfDouble { + + private final PrimitiveIterator.OfDouble iterator; + private final DoublePredicate predicate; + private double next; + + public DoubleFilter(PrimitiveIterator.OfDouble iterator, DoublePredicate predicate) { + this.iterator = iterator; + this.predicate = predicate; + } + + @Override + public boolean hasNext() { + while (iterator.hasNext()) { + // TODO nextDouble + next = iterator.next(); + if (predicate.test(next)) { + return true; + } + } + return false; + } + + @Override + public double nextDouble() { + return next; + } +} diff --git a/stream/src/main/java/com/annimon/stream/operator/DoubleFlatMap.java b/stream/src/main/java/com/annimon/stream/operator/DoubleFlatMap.java new file mode 100644 index 00000000..9576ca1e --- /dev/null +++ b/stream/src/main/java/com/annimon/stream/operator/DoubleFlatMap.java @@ -0,0 +1,46 @@ +package com.annimon.stream.operator; + +import com.annimon.stream.DoubleStream; +import com.annimon.stream.PrimitiveIterator; +import com.annimon.stream.function.DoubleFunction; +import java.util.NoSuchElementException; + +public class DoubleFlatMap extends PrimitiveIterator.OfDouble { + + private final PrimitiveIterator.OfDouble iterator; + private final DoubleFunction mapper; + private PrimitiveIterator.OfDouble inner; + + public DoubleFlatMap(PrimitiveIterator.OfDouble iterator, DoubleFunction mapper) { + this.iterator = iterator; + this.mapper = mapper; + } + + @Override + public boolean hasNext() { + if (inner != null && inner.hasNext()) { + return true; + } + while (iterator.hasNext()) { + // TODO nextDouble + final double arg = iterator.next(); + final DoubleStream result = mapper.apply(arg); + if (result == null) { + continue; + } + if (result.iterator().hasNext()) { + inner = result.iterator(); + return true; + } + } + return false; + } + + @Override + public double nextDouble() { + if (inner == null) { + throw new NoSuchElementException(); + } + return inner.nextDouble(); + } +} diff --git a/stream/src/main/java/com/annimon/stream/operator/DoubleGenerate.java b/stream/src/main/java/com/annimon/stream/operator/DoubleGenerate.java new file mode 100644 index 00000000..74a868ac --- /dev/null +++ b/stream/src/main/java/com/annimon/stream/operator/DoubleGenerate.java @@ -0,0 +1,23 @@ +package com.annimon.stream.operator; + +import com.annimon.stream.PrimitiveIterator; +import com.annimon.stream.function.DoubleSupplier; + +public class DoubleGenerate extends PrimitiveIterator.OfDouble { + + private final DoubleSupplier supplier; + + public DoubleGenerate(DoubleSupplier supplier) { + this.supplier = supplier; + } + + @Override + public boolean hasNext() { + return true; + } + + @Override + public double nextDouble() { + return supplier.getAsDouble(); + } +} diff --git a/stream/src/main/java/com/annimon/stream/operator/DoubleIterate.java b/stream/src/main/java/com/annimon/stream/operator/DoubleIterate.java new file mode 100644 index 00000000..43eafff6 --- /dev/null +++ b/stream/src/main/java/com/annimon/stream/operator/DoubleIterate.java @@ -0,0 +1,27 @@ +package com.annimon.stream.operator; + +import com.annimon.stream.PrimitiveIterator; +import com.annimon.stream.function.DoubleUnaryOperator; + +public class DoubleIterate extends PrimitiveIterator.OfDouble { + + private final DoubleUnaryOperator op; + private double current; + + public DoubleIterate(double seed, DoubleUnaryOperator f) { + this.op = f; + current = seed; + } + + @Override + public boolean hasNext() { + return true; + } + + @Override + public double nextDouble() { + final double old = current; + current = op.applyAsDouble(current); + return old; + } +} diff --git a/stream/src/main/java/com/annimon/stream/operator/DoubleLimit.java b/stream/src/main/java/com/annimon/stream/operator/DoubleLimit.java new file mode 100644 index 00000000..89082565 --- /dev/null +++ b/stream/src/main/java/com/annimon/stream/operator/DoubleLimit.java @@ -0,0 +1,27 @@ +package com.annimon.stream.operator; + +import com.annimon.stream.PrimitiveIterator; + +public class DoubleLimit extends PrimitiveIterator.OfDouble { + + private final PrimitiveIterator.OfDouble iterator; + private final long maxSize; + private long index; + + public DoubleLimit(PrimitiveIterator.OfDouble iterator, long maxSize) { + this.iterator = iterator; + this.maxSize = maxSize; + index = 0; + } + + @Override + public boolean hasNext() { + return (index < maxSize) && iterator.hasNext(); + } + + @Override + public double nextDouble() { + index++; + return iterator.nextDouble(); + } +} diff --git a/stream/src/main/java/com/annimon/stream/operator/DoubleMap.java b/stream/src/main/java/com/annimon/stream/operator/DoubleMap.java new file mode 100644 index 00000000..e26ace9e --- /dev/null +++ b/stream/src/main/java/com/annimon/stream/operator/DoubleMap.java @@ -0,0 +1,25 @@ +package com.annimon.stream.operator; + +import com.annimon.stream.PrimitiveIterator; +import com.annimon.stream.function.DoubleUnaryOperator; + +public class DoubleMap extends PrimitiveIterator.OfDouble { + + private final PrimitiveIterator.OfDouble iterator; + private final DoubleUnaryOperator mapper; + + public DoubleMap(PrimitiveIterator.OfDouble iterator, DoubleUnaryOperator mapper) { + this.iterator = iterator; + this.mapper = mapper; + } + + @Override + public boolean hasNext() { + return iterator.hasNext(); + } + + @Override + public double nextDouble() { + return mapper.applyAsDouble(iterator.nextDouble()); + } +} diff --git a/stream/src/main/java/com/annimon/stream/operator/DoubleMapToInt.java b/stream/src/main/java/com/annimon/stream/operator/DoubleMapToInt.java new file mode 100644 index 00000000..80198b7a --- /dev/null +++ b/stream/src/main/java/com/annimon/stream/operator/DoubleMapToInt.java @@ -0,0 +1,25 @@ +package com.annimon.stream.operator; + +import com.annimon.stream.PrimitiveIterator; +import com.annimon.stream.function.DoubleToIntFunction; + +public class DoubleMapToInt extends PrimitiveIterator.OfInt { + + private final PrimitiveIterator.OfDouble iterator; + private final DoubleToIntFunction mapper; + + public DoubleMapToInt(PrimitiveIterator.OfDouble iterator, DoubleToIntFunction mapper) { + this.iterator = iterator; + this.mapper = mapper; + } + + @Override + public boolean hasNext() { + return iterator.hasNext(); + } + + @Override + public int nextInt() { + return mapper.applyAsInt(iterator.nextDouble()); + } +} diff --git a/stream/src/main/java/com/annimon/stream/operator/DoubleMapToLong.java b/stream/src/main/java/com/annimon/stream/operator/DoubleMapToLong.java new file mode 100644 index 00000000..0f580a4a --- /dev/null +++ b/stream/src/main/java/com/annimon/stream/operator/DoubleMapToLong.java @@ -0,0 +1,25 @@ +package com.annimon.stream.operator; + +import com.annimon.stream.PrimitiveIterator; +import com.annimon.stream.function.DoubleToLongFunction; + +public class DoubleMapToLong extends PrimitiveIterator.OfLong { + + private final PrimitiveIterator.OfDouble iterator; + private final DoubleToLongFunction mapper; + + public DoubleMapToLong(PrimitiveIterator.OfDouble iterator, DoubleToLongFunction mapper) { + this.iterator = iterator; + this.mapper = mapper; + } + + @Override + public boolean hasNext() { + return iterator.hasNext(); + } + + @Override + public long nextLong() { + return mapper.applyAsLong(iterator.nextDouble()); + } +} diff --git a/stream/src/main/java/com/annimon/stream/operator/DoubleMapToObj.java b/stream/src/main/java/com/annimon/stream/operator/DoubleMapToObj.java new file mode 100644 index 00000000..f662fa1f --- /dev/null +++ b/stream/src/main/java/com/annimon/stream/operator/DoubleMapToObj.java @@ -0,0 +1,26 @@ +package com.annimon.stream.operator; + +import com.annimon.stream.LsaIterator; +import com.annimon.stream.PrimitiveIterator; +import com.annimon.stream.function.DoubleFunction; + +public class DoubleMapToObj extends LsaIterator { + + private final PrimitiveIterator.OfDouble iterator; + private final DoubleFunction mapper; + + public DoubleMapToObj(PrimitiveIterator.OfDouble iterator, DoubleFunction mapper) { + this.iterator = iterator; + this.mapper = mapper; + } + + @Override + public boolean hasNext() { + return iterator.hasNext(); + } + + @Override + public R nextIteration() { + return mapper.apply(iterator.nextDouble()); + } +} diff --git a/stream/src/main/java/com/annimon/stream/operator/DoublePeek.java b/stream/src/main/java/com/annimon/stream/operator/DoublePeek.java new file mode 100644 index 00000000..df590407 --- /dev/null +++ b/stream/src/main/java/com/annimon/stream/operator/DoublePeek.java @@ -0,0 +1,27 @@ +package com.annimon.stream.operator; + +import com.annimon.stream.PrimitiveIterator; +import com.annimon.stream.function.DoubleConsumer; + +public class DoublePeek extends PrimitiveIterator.OfDouble { + + private final PrimitiveIterator.OfDouble iterator; + private final DoubleConsumer action; + + public DoublePeek(PrimitiveIterator.OfDouble iterator, DoubleConsumer action) { + this.iterator = iterator; + this.action = action; + } + + @Override + public boolean hasNext() { + return iterator.hasNext(); + } + + @Override + public double nextDouble() { + final double value = iterator.nextDouble(); + action.accept(value); + return value; + } +} diff --git a/stream/src/main/java/com/annimon/stream/operator/DoubleSample.java b/stream/src/main/java/com/annimon/stream/operator/DoubleSample.java new file mode 100644 index 00000000..9bb56972 --- /dev/null +++ b/stream/src/main/java/com/annimon/stream/operator/DoubleSample.java @@ -0,0 +1,30 @@ +package com.annimon.stream.operator; + +import com.annimon.stream.PrimitiveIterator; + +public class DoubleSample extends PrimitiveIterator.OfDouble { + + private final PrimitiveIterator.OfDouble iterator; + private final int stepWidth; + + public DoubleSample(PrimitiveIterator.OfDouble iterator, int stepWidth) { + this.iterator = iterator; + this.stepWidth = stepWidth; + } + + @Override + public boolean hasNext() { + return iterator.hasNext(); + } + + @Override + public double nextDouble() { + final double result = iterator.nextDouble(); + int skip = 1; + while (skip < stepWidth && iterator.hasNext()) { + iterator.nextDouble(); + skip++; + } + return result; + } +} diff --git a/stream/src/main/java/com/annimon/stream/operator/DoubleScan.java b/stream/src/main/java/com/annimon/stream/operator/DoubleScan.java new file mode 100644 index 00000000..1097d3b9 --- /dev/null +++ b/stream/src/main/java/com/annimon/stream/operator/DoubleScan.java @@ -0,0 +1,30 @@ +package com.annimon.stream.operator; + +import com.annimon.stream.PrimitiveExtIterator; +import com.annimon.stream.PrimitiveIterator; +import com.annimon.stream.function.DoubleBinaryOperator; + +public class DoubleScan extends PrimitiveExtIterator.OfDouble { + + private final PrimitiveIterator.OfDouble iterator; + private final DoubleBinaryOperator accumulator; + + public DoubleScan(PrimitiveIterator.OfDouble iterator, DoubleBinaryOperator accumulator) { + this.iterator = iterator; + this.accumulator = accumulator; + } + + @Override + protected void nextIteration() { + hasNext = iterator.hasNext(); + if (hasNext) { + // TODO nextDouble + final double current = iterator.next(); + if (isInit) { + next = accumulator.applyAsDouble(next, current); + } else { + next = current; + } + } + } +} diff --git a/stream/src/main/java/com/annimon/stream/operator/DoubleScanIdentity.java b/stream/src/main/java/com/annimon/stream/operator/DoubleScanIdentity.java new file mode 100644 index 00000000..ab78cdb2 --- /dev/null +++ b/stream/src/main/java/com/annimon/stream/operator/DoubleScanIdentity.java @@ -0,0 +1,34 @@ +package com.annimon.stream.operator; + +import com.annimon.stream.PrimitiveExtIterator; +import com.annimon.stream.PrimitiveIterator; +import com.annimon.stream.function.DoubleBinaryOperator; + +public class DoubleScanIdentity extends PrimitiveExtIterator.OfDouble { + + private final PrimitiveIterator.OfDouble iterator; + private final double identity; + private final DoubleBinaryOperator accumulator; + + public DoubleScanIdentity(PrimitiveIterator.OfDouble iterator, double identity, + DoubleBinaryOperator accumulator) { + this.iterator = iterator; + this.identity = identity; + this.accumulator = accumulator; + } + + @Override + protected void nextIteration() { + if (!isInit) { + // Return identity + hasNext = true; + next = identity; + return; + } + hasNext = iterator.hasNext(); + if (hasNext) { + final double current = iterator.next(); + next = accumulator.applyAsDouble(next, current); + } + } +} diff --git a/stream/src/main/java/com/annimon/stream/operator/DoubleSingleElement.java b/stream/src/main/java/com/annimon/stream/operator/DoubleSingleElement.java new file mode 100644 index 00000000..5244d000 --- /dev/null +++ b/stream/src/main/java/com/annimon/stream/operator/DoubleSingleElement.java @@ -0,0 +1,25 @@ +package com.annimon.stream.operator; + +import com.annimon.stream.PrimitiveIterator; + +public class DoubleSingleElement extends PrimitiveIterator.OfDouble { + + private final double element; + private boolean hasNext; + + public DoubleSingleElement(double element) { + this.element = element; + hasNext = true; + } + + @Override + public boolean hasNext() { + return hasNext; + } + + @Override + public double nextDouble() { + hasNext = false; + return element; + } +} diff --git a/stream/src/main/java/com/annimon/stream/operator/DoubleSkip.java b/stream/src/main/java/com/annimon/stream/operator/DoubleSkip.java new file mode 100644 index 00000000..d67ce23b --- /dev/null +++ b/stream/src/main/java/com/annimon/stream/operator/DoubleSkip.java @@ -0,0 +1,33 @@ +package com.annimon.stream.operator; + +import com.annimon.stream.PrimitiveIterator; + +public class DoubleSkip extends PrimitiveIterator.OfDouble { + + private final PrimitiveIterator.OfDouble iterator; + private final long n; + private long skipped; + + public DoubleSkip(PrimitiveIterator.OfDouble iterator, long n) { + this.iterator = iterator; + this.n = n; + skipped = 0; + } + + @Override + public boolean hasNext() { + while (iterator.hasNext()) { + if (skipped == n) { + break; + } + iterator.nextDouble(); + skipped++; + } + return iterator.hasNext(); + } + + @Override + public double nextDouble() { + return iterator.nextDouble(); + } +} diff --git a/stream/src/main/java/com/annimon/stream/operator/DoubleSorted.java b/stream/src/main/java/com/annimon/stream/operator/DoubleSorted.java new file mode 100644 index 00000000..4cd6c4a2 --- /dev/null +++ b/stream/src/main/java/com/annimon/stream/operator/DoubleSorted.java @@ -0,0 +1,30 @@ +package com.annimon.stream.operator; + +import com.annimon.stream.internal.Operators; +import com.annimon.stream.PrimitiveExtIterator; +import com.annimon.stream.PrimitiveIterator; +import java.util.Arrays; + +public class DoubleSorted extends PrimitiveExtIterator.OfDouble { + + private final PrimitiveIterator.OfDouble iterator; + private int index; + private double[] array; + + public DoubleSorted(PrimitiveIterator.OfDouble iterator) { + this.iterator = iterator; + index = 0; + } + + @Override + protected void nextIteration() { + if (!isInit) { + array = Operators.toDoubleArray(iterator); + Arrays.sort(array); + } + hasNext = index < array.length; + if (hasNext) { + next = array[index++]; + } + } +} diff --git a/stream/src/main/java/com/annimon/stream/operator/DoubleTakeUntil.java b/stream/src/main/java/com/annimon/stream/operator/DoubleTakeUntil.java new file mode 100644 index 00000000..46f65be9 --- /dev/null +++ b/stream/src/main/java/com/annimon/stream/operator/DoubleTakeUntil.java @@ -0,0 +1,24 @@ +package com.annimon.stream.operator; + +import com.annimon.stream.PrimitiveExtIterator; +import com.annimon.stream.PrimitiveIterator; +import com.annimon.stream.function.DoublePredicate; + +public class DoubleTakeUntil extends PrimitiveExtIterator.OfDouble { + + private final PrimitiveIterator.OfDouble iterator; + private final DoublePredicate stopPredicate; + + public DoubleTakeUntil(PrimitiveIterator.OfDouble iterator, DoublePredicate stopPredicate) { + this.iterator = iterator; + this.stopPredicate = stopPredicate; + } + + @Override + protected void nextIteration() { + hasNext = iterator.hasNext() && !(isInit && stopPredicate.test(next)); + if (hasNext) { + next = iterator.next(); + } + } +} diff --git a/stream/src/main/java/com/annimon/stream/operator/DoubleTakeWhile.java b/stream/src/main/java/com/annimon/stream/operator/DoubleTakeWhile.java new file mode 100644 index 00000000..22fa91a7 --- /dev/null +++ b/stream/src/main/java/com/annimon/stream/operator/DoubleTakeWhile.java @@ -0,0 +1,22 @@ +package com.annimon.stream.operator; + +import com.annimon.stream.PrimitiveExtIterator; +import com.annimon.stream.PrimitiveIterator; +import com.annimon.stream.function.DoublePredicate; + +public class DoubleTakeWhile extends PrimitiveExtIterator.OfDouble { + + private final PrimitiveIterator.OfDouble iterator; + private final DoublePredicate predicate; + + public DoubleTakeWhile(PrimitiveIterator.OfDouble iterator, DoublePredicate predicate) { + this.iterator = iterator; + this.predicate = predicate; + } + + @Override + protected void nextIteration() { + hasNext = iterator.hasNext() + && predicate.test(next = iterator.next()); + } +} diff --git a/stream/src/main/java/com/annimon/stream/operator/IntArray.java b/stream/src/main/java/com/annimon/stream/operator/IntArray.java new file mode 100644 index 00000000..d48e9921 --- /dev/null +++ b/stream/src/main/java/com/annimon/stream/operator/IntArray.java @@ -0,0 +1,24 @@ +package com.annimon.stream.operator; + +import com.annimon.stream.PrimitiveIterator; + +public class IntArray extends PrimitiveIterator.OfInt { + + private final int[] values; + private int index; + + public IntArray(int[] values) { + this.values = values; + index = 0; + } + + @Override + public boolean hasNext() { + return index < values.length; + } + + @Override + public int nextInt() { + return values[index++]; + } +} diff --git a/stream/src/main/java/com/annimon/stream/operator/IntConcat.java b/stream/src/main/java/com/annimon/stream/operator/IntConcat.java new file mode 100644 index 00000000..36475960 --- /dev/null +++ b/stream/src/main/java/com/annimon/stream/operator/IntConcat.java @@ -0,0 +1,32 @@ +package com.annimon.stream.operator; + +import com.annimon.stream.PrimitiveIterator; + +public class IntConcat extends PrimitiveIterator.OfInt { + + private final PrimitiveIterator.OfInt iterator1; + private final PrimitiveIterator.OfInt iterator2; + private boolean firstStreamIsCurrent; + + public IntConcat(PrimitiveIterator.OfInt iterator1, PrimitiveIterator.OfInt iterator2) { + this.iterator1 = iterator1; + this.iterator2 = iterator2; + firstStreamIsCurrent = true; + } + + @Override + public boolean hasNext() { + if (firstStreamIsCurrent) { + if (iterator1.hasNext()) { + return true; + } + firstStreamIsCurrent = false; + } + return iterator2.hasNext(); + } + + @Override + public int nextInt() { + return firstStreamIsCurrent ? iterator1.nextInt() : iterator2.nextInt(); + } +} diff --git a/stream/src/main/java/com/annimon/stream/operator/IntDropWhile.java b/stream/src/main/java/com/annimon/stream/operator/IntDropWhile.java new file mode 100644 index 00000000..c278a566 --- /dev/null +++ b/stream/src/main/java/com/annimon/stream/operator/IntDropWhile.java @@ -0,0 +1,34 @@ +package com.annimon.stream.operator; + +import com.annimon.stream.PrimitiveExtIterator; +import com.annimon.stream.PrimitiveIterator; +import com.annimon.stream.function.IntPredicate; + +public class IntDropWhile extends PrimitiveExtIterator.OfInt { + + private final PrimitiveIterator.OfInt iterator; + private final IntPredicate predicate; + + public IntDropWhile(PrimitiveIterator.OfInt iterator, IntPredicate predicate) { + this.iterator = iterator; + this.predicate = predicate; + } + + @Override + protected void nextIteration() { + if (!isInit) { + // Skip first time + while (hasNext = iterator.hasNext()) { + next = iterator.next(); + if (!predicate.test(next)) { + return; + } + } + } + + hasNext = hasNext && iterator.hasNext(); + if (!hasNext) return; + + next = iterator.next(); + } +} diff --git a/stream/src/main/java/com/annimon/stream/operator/IntFilter.java b/stream/src/main/java/com/annimon/stream/operator/IntFilter.java new file mode 100644 index 00000000..1cfd6ad2 --- /dev/null +++ b/stream/src/main/java/com/annimon/stream/operator/IntFilter.java @@ -0,0 +1,33 @@ +package com.annimon.stream.operator; + +import com.annimon.stream.PrimitiveIterator; +import com.annimon.stream.function.IntPredicate; + +public class IntFilter extends PrimitiveIterator.OfInt { + + private final PrimitiveIterator.OfInt iterator; + private final IntPredicate predicate; + private int next; + + public IntFilter(PrimitiveIterator.OfInt iterator, IntPredicate predicate) { + this.iterator = iterator; + this.predicate = predicate; + } + + @Override + public boolean hasNext() { + while (iterator.hasNext()) { + // TODO nextInt + next = iterator.next(); + if (predicate.test(next)) { + return true; + } + } + return false; + } + + @Override + public int nextInt() { + return next; + } +} diff --git a/stream/src/main/java/com/annimon/stream/operator/IntFlatMap.java b/stream/src/main/java/com/annimon/stream/operator/IntFlatMap.java new file mode 100644 index 00000000..d6151c9a --- /dev/null +++ b/stream/src/main/java/com/annimon/stream/operator/IntFlatMap.java @@ -0,0 +1,46 @@ +package com.annimon.stream.operator; + +import com.annimon.stream.IntStream; +import com.annimon.stream.PrimitiveIterator; +import com.annimon.stream.function.IntFunction; +import java.util.NoSuchElementException; + +public class IntFlatMap extends PrimitiveIterator.OfInt { + + private final PrimitiveIterator.OfInt iterator; + private final IntFunction mapper; + private PrimitiveIterator.OfInt inner; + + public IntFlatMap(PrimitiveIterator.OfInt iterator, IntFunction mapper) { + this.iterator = iterator; + this.mapper = mapper; + } + + @Override + public boolean hasNext() { + if (inner != null && inner.hasNext()) { + return true; + } + while (iterator.hasNext()) { + // TODO nextInt + final int arg = iterator.next(); + final IntStream result = mapper.apply(arg); + if (result == null) { + continue; + } + if (result.iterator().hasNext()) { + inner = result.iterator(); + return true; + } + } + return false; + } + + @Override + public int nextInt() { + if (inner == null) { + throw new NoSuchElementException(); + } + return inner.nextInt(); + } +} diff --git a/stream/src/main/java/com/annimon/stream/operator/IntGenerate.java b/stream/src/main/java/com/annimon/stream/operator/IntGenerate.java new file mode 100644 index 00000000..1aca8bb1 --- /dev/null +++ b/stream/src/main/java/com/annimon/stream/operator/IntGenerate.java @@ -0,0 +1,23 @@ +package com.annimon.stream.operator; + +import com.annimon.stream.PrimitiveIterator; +import com.annimon.stream.function.IntSupplier; + +public class IntGenerate extends PrimitiveIterator.OfInt { + + private final IntSupplier supplier; + + public IntGenerate(IntSupplier supplier) { + this.supplier = supplier; + } + + @Override + public boolean hasNext() { + return true; + } + + @Override + public int nextInt() { + return supplier.getAsInt(); + } +} diff --git a/stream/src/main/java/com/annimon/stream/operator/IntIterate.java b/stream/src/main/java/com/annimon/stream/operator/IntIterate.java new file mode 100644 index 00000000..a2bf6f5f --- /dev/null +++ b/stream/src/main/java/com/annimon/stream/operator/IntIterate.java @@ -0,0 +1,27 @@ +package com.annimon.stream.operator; + +import com.annimon.stream.PrimitiveIterator; +import com.annimon.stream.function.IntUnaryOperator; + +public class IntIterate extends PrimitiveIterator.OfInt { + + private final IntUnaryOperator op; + private int current; + + public IntIterate(int seed, IntUnaryOperator f) { + this.op = f; + current = seed; + } + + @Override + public boolean hasNext() { + return true; + } + + @Override + public int nextInt() { + final int old = current; + current = op.applyAsInt(current); + return old; + } +} diff --git a/stream/src/main/java/com/annimon/stream/operator/IntLimit.java b/stream/src/main/java/com/annimon/stream/operator/IntLimit.java new file mode 100644 index 00000000..08ab137c --- /dev/null +++ b/stream/src/main/java/com/annimon/stream/operator/IntLimit.java @@ -0,0 +1,27 @@ +package com.annimon.stream.operator; + +import com.annimon.stream.PrimitiveIterator; + +public class IntLimit extends PrimitiveIterator.OfInt { + + private final PrimitiveIterator.OfInt iterator; + private final long maxSize; + private long index; + + public IntLimit(PrimitiveIterator.OfInt iterator, long maxSize) { + this.iterator = iterator; + this.maxSize = maxSize; + index = 0; + } + + @Override + public boolean hasNext() { + return (index < maxSize) && iterator.hasNext(); + } + + @Override + public int nextInt() { + index++; + return iterator.nextInt(); + } +} diff --git a/stream/src/main/java/com/annimon/stream/operator/IntMap.java b/stream/src/main/java/com/annimon/stream/operator/IntMap.java new file mode 100644 index 00000000..2a7f3fa4 --- /dev/null +++ b/stream/src/main/java/com/annimon/stream/operator/IntMap.java @@ -0,0 +1,25 @@ +package com.annimon.stream.operator; + +import com.annimon.stream.PrimitiveIterator; +import com.annimon.stream.function.IntUnaryOperator; + +public class IntMap extends PrimitiveIterator.OfInt { + + private final PrimitiveIterator.OfInt iterator; + private final IntUnaryOperator mapper; + + public IntMap(PrimitiveIterator.OfInt iterator, IntUnaryOperator mapper) { + this.iterator = iterator; + this.mapper = mapper; + } + + @Override + public boolean hasNext() { + return iterator.hasNext(); + } + + @Override + public int nextInt() { + return mapper.applyAsInt(iterator.nextInt()); + } +} diff --git a/stream/src/main/java/com/annimon/stream/operator/IntMapToDouble.java b/stream/src/main/java/com/annimon/stream/operator/IntMapToDouble.java new file mode 100644 index 00000000..a7d64325 --- /dev/null +++ b/stream/src/main/java/com/annimon/stream/operator/IntMapToDouble.java @@ -0,0 +1,25 @@ +package com.annimon.stream.operator; + +import com.annimon.stream.PrimitiveIterator; +import com.annimon.stream.function.IntToDoubleFunction; + +public class IntMapToDouble extends PrimitiveIterator.OfDouble { + + private final PrimitiveIterator.OfInt iterator; + private final IntToDoubleFunction mapper; + + public IntMapToDouble(PrimitiveIterator.OfInt iterator, IntToDoubleFunction mapper) { + this.iterator = iterator; + this.mapper = mapper; + } + + @Override + public boolean hasNext() { + return iterator.hasNext(); + } + + @Override + public double nextDouble() { + return mapper.applyAsDouble(iterator.nextInt()); + } +} diff --git a/stream/src/main/java/com/annimon/stream/operator/IntMapToLong.java b/stream/src/main/java/com/annimon/stream/operator/IntMapToLong.java new file mode 100644 index 00000000..3f2f6cd7 --- /dev/null +++ b/stream/src/main/java/com/annimon/stream/operator/IntMapToLong.java @@ -0,0 +1,25 @@ +package com.annimon.stream.operator; + +import com.annimon.stream.PrimitiveIterator; +import com.annimon.stream.function.IntToLongFunction; + +public class IntMapToLong extends PrimitiveIterator.OfLong { + + private final PrimitiveIterator.OfInt iterator; + private final IntToLongFunction mapper; + + public IntMapToLong(PrimitiveIterator.OfInt iterator, IntToLongFunction mapper) { + this.iterator = iterator; + this.mapper = mapper; + } + + @Override + public boolean hasNext() { + return iterator.hasNext(); + } + + @Override + public long nextLong() { + return mapper.applyAsLong(iterator.nextInt()); + } +} diff --git a/stream/src/main/java/com/annimon/stream/operator/IntMapToObj.java b/stream/src/main/java/com/annimon/stream/operator/IntMapToObj.java new file mode 100644 index 00000000..3d32036e --- /dev/null +++ b/stream/src/main/java/com/annimon/stream/operator/IntMapToObj.java @@ -0,0 +1,26 @@ +package com.annimon.stream.operator; + +import com.annimon.stream.LsaIterator; +import com.annimon.stream.PrimitiveIterator; +import com.annimon.stream.function.IntFunction; + +public class IntMapToObj extends LsaIterator { + + private final PrimitiveIterator.OfInt iterator; + private final IntFunction mapper; + + public IntMapToObj(PrimitiveIterator.OfInt iterator, IntFunction mapper) { + this.iterator = iterator; + this.mapper = mapper; + } + + @Override + public boolean hasNext() { + return iterator.hasNext(); + } + + @Override + public R nextIteration() { + return mapper.apply(iterator.nextInt()); + } +} diff --git a/stream/src/main/java/com/annimon/stream/operator/IntPeek.java b/stream/src/main/java/com/annimon/stream/operator/IntPeek.java new file mode 100644 index 00000000..531ebca3 --- /dev/null +++ b/stream/src/main/java/com/annimon/stream/operator/IntPeek.java @@ -0,0 +1,27 @@ +package com.annimon.stream.operator; + +import com.annimon.stream.PrimitiveIterator; +import com.annimon.stream.function.IntConsumer; + +public class IntPeek extends PrimitiveIterator.OfInt { + + private final PrimitiveIterator.OfInt iterator; + private final IntConsumer action; + + public IntPeek(PrimitiveIterator.OfInt iterator, IntConsumer action) { + this.iterator = iterator; + this.action = action; + } + + @Override + public boolean hasNext() { + return iterator.hasNext(); + } + + @Override + public int nextInt() { + final int value = iterator.nextInt(); + action.accept(value); + return value; + } +} diff --git a/stream/src/main/java/com/annimon/stream/operator/IntRangeClosed.java b/stream/src/main/java/com/annimon/stream/operator/IntRangeClosed.java new file mode 100644 index 00000000..2d740d98 --- /dev/null +++ b/stream/src/main/java/com/annimon/stream/operator/IntRangeClosed.java @@ -0,0 +1,30 @@ +package com.annimon.stream.operator; + +import com.annimon.stream.PrimitiveIterator; + +public class IntRangeClosed extends PrimitiveIterator.OfInt { + + private final int endInclusive; + private int current; + private boolean hasNext; + + public IntRangeClosed(int startInclusive, int endInclusive) { + this.endInclusive = endInclusive; + current = startInclusive; + hasNext = current <= endInclusive; + } + + @Override + public boolean hasNext() { + return hasNext; + } + + @Override + public int nextInt() { + if (current >= endInclusive) { + hasNext = false; + return endInclusive; + } + return current++; + } +} diff --git a/stream/src/main/java/com/annimon/stream/operator/IntSample.java b/stream/src/main/java/com/annimon/stream/operator/IntSample.java new file mode 100644 index 00000000..649a888f --- /dev/null +++ b/stream/src/main/java/com/annimon/stream/operator/IntSample.java @@ -0,0 +1,30 @@ +package com.annimon.stream.operator; + +import com.annimon.stream.PrimitiveIterator; + +public class IntSample extends PrimitiveIterator.OfInt { + + private final PrimitiveIterator.OfInt iterator; + private final int stepWidth; + + public IntSample(PrimitiveIterator.OfInt iterator, int stepWidth) { + this.iterator = iterator; + this.stepWidth = stepWidth; + } + + @Override + public boolean hasNext() { + return iterator.hasNext(); + } + + @Override + public int nextInt() { + final int result = iterator.nextInt(); + int skip = 1; + while (skip < stepWidth && iterator.hasNext()) { + iterator.nextInt(); + skip++; + } + return result; + } +} diff --git a/stream/src/main/java/com/annimon/stream/operator/IntScan.java b/stream/src/main/java/com/annimon/stream/operator/IntScan.java new file mode 100644 index 00000000..d72da1f8 --- /dev/null +++ b/stream/src/main/java/com/annimon/stream/operator/IntScan.java @@ -0,0 +1,29 @@ +package com.annimon.stream.operator; + +import com.annimon.stream.PrimitiveExtIterator; +import com.annimon.stream.PrimitiveIterator; +import com.annimon.stream.function.IntBinaryOperator; + +public class IntScan extends PrimitiveExtIterator.OfInt { + + private final PrimitiveIterator.OfInt iterator; + private final IntBinaryOperator accumulator; + + public IntScan(PrimitiveIterator.OfInt iterator, IntBinaryOperator accumulator) { + this.iterator = iterator; + this.accumulator = accumulator; + } + + @Override + protected void nextIteration() { + hasNext = iterator.hasNext(); + if (hasNext) { + final int current = iterator.next(); + if (isInit) { + next = accumulator.applyAsInt(next, current); + } else { + next = current; + } + } + } +} diff --git a/stream/src/main/java/com/annimon/stream/operator/IntScanIdentity.java b/stream/src/main/java/com/annimon/stream/operator/IntScanIdentity.java new file mode 100644 index 00000000..b875543b --- /dev/null +++ b/stream/src/main/java/com/annimon/stream/operator/IntScanIdentity.java @@ -0,0 +1,33 @@ +package com.annimon.stream.operator; + +import com.annimon.stream.PrimitiveExtIterator; +import com.annimon.stream.PrimitiveIterator; +import com.annimon.stream.function.IntBinaryOperator; + +public class IntScanIdentity extends PrimitiveExtIterator.OfInt { + + private final PrimitiveIterator.OfInt iterator; + private final int identity; + private final IntBinaryOperator accumulator; + + public IntScanIdentity(PrimitiveIterator.OfInt iterator, int identity, IntBinaryOperator accumulator) { + this.iterator = iterator; + this.identity = identity; + this.accumulator = accumulator; + } + + @Override + protected void nextIteration() { + if (!isInit) { + // Return identity + hasNext = true; + next = identity; + return; + } + hasNext = iterator.hasNext(); + if (hasNext) { + final int current = iterator.next(); + next = accumulator.applyAsInt(next, current); + } + } +} diff --git a/stream/src/main/java/com/annimon/stream/operator/IntSingleElement.java b/stream/src/main/java/com/annimon/stream/operator/IntSingleElement.java new file mode 100644 index 00000000..3b8b10ff --- /dev/null +++ b/stream/src/main/java/com/annimon/stream/operator/IntSingleElement.java @@ -0,0 +1,25 @@ +package com.annimon.stream.operator; + +import com.annimon.stream.PrimitiveIterator; + +public class IntSingleElement extends PrimitiveIterator.OfInt { + + private final int element; + private boolean hasNext; + + public IntSingleElement(int element) { + this.element = element; + hasNext = true; + } + + @Override + public boolean hasNext() { + return hasNext; + } + + @Override + public int nextInt() { + hasNext = false; + return element; + } +} diff --git a/stream/src/main/java/com/annimon/stream/operator/IntSkip.java b/stream/src/main/java/com/annimon/stream/operator/IntSkip.java new file mode 100644 index 00000000..cb6b0702 --- /dev/null +++ b/stream/src/main/java/com/annimon/stream/operator/IntSkip.java @@ -0,0 +1,34 @@ +package com.annimon.stream.operator; + +import com.annimon.stream.PrimitiveIterator; + +public class IntSkip extends PrimitiveIterator.OfInt { + + private final PrimitiveIterator.OfInt iterator; + private final long n; + private long skipped; + + public IntSkip(PrimitiveIterator.OfInt iterator, long n) { + this.iterator = iterator; + this.n = n; + skipped = 0; + } + + @Override + public boolean hasNext() { + while (iterator.hasNext()) { + if (skipped == n) { + break; + } + iterator.nextInt(); + skipped++; + } + + return iterator.hasNext(); + } + + @Override + public int nextInt() { + return iterator.nextInt(); + } +} diff --git a/stream/src/main/java/com/annimon/stream/operator/IntSorted.java b/stream/src/main/java/com/annimon/stream/operator/IntSorted.java new file mode 100644 index 00000000..ef439cdb --- /dev/null +++ b/stream/src/main/java/com/annimon/stream/operator/IntSorted.java @@ -0,0 +1,30 @@ +package com.annimon.stream.operator; + +import com.annimon.stream.internal.Operators; +import com.annimon.stream.PrimitiveExtIterator; +import com.annimon.stream.PrimitiveIterator; +import java.util.Arrays; + +public class IntSorted extends PrimitiveExtIterator.OfInt { + + private final PrimitiveIterator.OfInt iterator; + private int index; + private int[] array; + + public IntSorted(PrimitiveIterator.OfInt iterator) { + this.iterator = iterator; + index = 0; + } + + @Override + protected void nextIteration() { + if (!isInit) { + array = Operators.toIntArray(iterator); + Arrays.sort(array); + } + hasNext = index < array.length; + if (hasNext) { + next = array[index++]; + } + } +} diff --git a/stream/src/main/java/com/annimon/stream/operator/IntTakeUntil.java b/stream/src/main/java/com/annimon/stream/operator/IntTakeUntil.java new file mode 100644 index 00000000..e9ea085e --- /dev/null +++ b/stream/src/main/java/com/annimon/stream/operator/IntTakeUntil.java @@ -0,0 +1,24 @@ +package com.annimon.stream.operator; + +import com.annimon.stream.PrimitiveExtIterator; +import com.annimon.stream.PrimitiveIterator; +import com.annimon.stream.function.IntPredicate; + +public class IntTakeUntil extends PrimitiveExtIterator.OfInt { + + private final PrimitiveIterator.OfInt iterator; + private final IntPredicate stopPredicate; + + public IntTakeUntil(PrimitiveIterator.OfInt iterator, IntPredicate stopPredicate) { + this.iterator = iterator; + this.stopPredicate = stopPredicate; + } + + @Override + protected void nextIteration() { + hasNext = iterator.hasNext() && !(isInit && stopPredicate.test(next)); + if (hasNext) { + next = iterator.next(); + } + } +} diff --git a/stream/src/main/java/com/annimon/stream/operator/IntTakeWhile.java b/stream/src/main/java/com/annimon/stream/operator/IntTakeWhile.java new file mode 100644 index 00000000..da871ca0 --- /dev/null +++ b/stream/src/main/java/com/annimon/stream/operator/IntTakeWhile.java @@ -0,0 +1,22 @@ +package com.annimon.stream.operator; + +import com.annimon.stream.PrimitiveExtIterator; +import com.annimon.stream.PrimitiveIterator; +import com.annimon.stream.function.IntPredicate; + +public class IntTakeWhile extends PrimitiveExtIterator.OfInt { + + private final PrimitiveIterator.OfInt iterator; + private final IntPredicate predicate; + + public IntTakeWhile(PrimitiveIterator.OfInt iterator, IntPredicate predicate) { + this.iterator = iterator; + this.predicate = predicate; + } + + @Override + protected void nextIteration() { + hasNext = iterator.hasNext() + && predicate.test(next = iterator.next()); + } +} diff --git a/stream/src/main/java/com/annimon/stream/operator/LongArray.java b/stream/src/main/java/com/annimon/stream/operator/LongArray.java new file mode 100644 index 00000000..57f9de05 --- /dev/null +++ b/stream/src/main/java/com/annimon/stream/operator/LongArray.java @@ -0,0 +1,24 @@ +package com.annimon.stream.operator; + +import com.annimon.stream.PrimitiveIterator; + +public class LongArray extends PrimitiveIterator.OfLong { + + private final long[] values; + private int index; + + public LongArray(long[] values) { + this.values = values; + index = 0; + } + + @Override + public long nextLong() { + return values[index++]; + } + + @Override + public boolean hasNext() { + return index < values.length; + } +} diff --git a/stream/src/main/java/com/annimon/stream/operator/LongConcat.java b/stream/src/main/java/com/annimon/stream/operator/LongConcat.java new file mode 100644 index 00000000..6f6c8f9d --- /dev/null +++ b/stream/src/main/java/com/annimon/stream/operator/LongConcat.java @@ -0,0 +1,32 @@ +package com.annimon.stream.operator; + +import com.annimon.stream.PrimitiveIterator; + +public class LongConcat extends PrimitiveIterator.OfLong { + + private final PrimitiveIterator.OfLong iterator1; + private final PrimitiveIterator.OfLong iterator2; + private boolean firstStreamIsCurrent; + + public LongConcat(PrimitiveIterator.OfLong iterator1, PrimitiveIterator.OfLong iterator2) { + this.iterator1 = iterator1; + this.iterator2 = iterator2; + firstStreamIsCurrent = true; + } + + @Override + public boolean hasNext() { + if (firstStreamIsCurrent) { + if (iterator1.hasNext()) { + return true; + } + firstStreamIsCurrent = false; + } + return iterator2.hasNext(); + } + + @Override + public long nextLong() { + return firstStreamIsCurrent ? iterator1.nextLong() : iterator2.nextLong(); + } +} diff --git a/stream/src/main/java/com/annimon/stream/operator/LongDropWhile.java b/stream/src/main/java/com/annimon/stream/operator/LongDropWhile.java new file mode 100644 index 00000000..fef4c39d --- /dev/null +++ b/stream/src/main/java/com/annimon/stream/operator/LongDropWhile.java @@ -0,0 +1,34 @@ +package com.annimon.stream.operator; + +import com.annimon.stream.PrimitiveExtIterator; +import com.annimon.stream.PrimitiveIterator; +import com.annimon.stream.function.LongPredicate; + +public class LongDropWhile extends PrimitiveExtIterator.OfLong { + + private final PrimitiveIterator.OfLong iterator; + private final LongPredicate predicate; + + public LongDropWhile(PrimitiveIterator.OfLong iterator, LongPredicate predicate) { + this.iterator = iterator; + this.predicate = predicate; + } + + @Override + protected void nextIteration() { + if (!isInit) { + // Skip first time + while (hasNext = iterator.hasNext()) { + next = iterator.next(); + if (!predicate.test(next)) { + return; + } + } + } + + hasNext = hasNext && iterator.hasNext(); + if (!hasNext) return; + + next = iterator.next(); + } +} diff --git a/stream/src/main/java/com/annimon/stream/operator/LongFilter.java b/stream/src/main/java/com/annimon/stream/operator/LongFilter.java new file mode 100644 index 00000000..b9798c92 --- /dev/null +++ b/stream/src/main/java/com/annimon/stream/operator/LongFilter.java @@ -0,0 +1,33 @@ +package com.annimon.stream.operator; + +import com.annimon.stream.PrimitiveIterator; +import com.annimon.stream.function.LongPredicate; + +public class LongFilter extends PrimitiveIterator.OfLong { + + private final PrimitiveIterator.OfLong iterator; + private final LongPredicate predicate; + private long next; + + public LongFilter(PrimitiveIterator.OfLong iterator, LongPredicate predicate) { + this.iterator = iterator; + this.predicate = predicate; + } + + @Override + public boolean hasNext() { + while (iterator.hasNext()) { + // TODO nextLong + next = iterator.next(); + if (predicate.test(next)) { + return true; + } + } + return false; + } + + @Override + public long nextLong() { + return next; + } +} diff --git a/stream/src/main/java/com/annimon/stream/operator/LongFlatMap.java b/stream/src/main/java/com/annimon/stream/operator/LongFlatMap.java new file mode 100644 index 00000000..a9e181a6 --- /dev/null +++ b/stream/src/main/java/com/annimon/stream/operator/LongFlatMap.java @@ -0,0 +1,46 @@ +package com.annimon.stream.operator; + +import com.annimon.stream.LongStream; +import com.annimon.stream.PrimitiveIterator; +import com.annimon.stream.function.LongFunction; +import java.util.NoSuchElementException; + +public class LongFlatMap extends PrimitiveIterator.OfLong { + + private final PrimitiveIterator.OfLong iterator; + private final LongFunction mapper; + private PrimitiveIterator.OfLong inner; + + public LongFlatMap(PrimitiveIterator.OfLong iterator, LongFunction mapper) { + this.iterator = iterator; + this.mapper = mapper; + } + + @Override + public boolean hasNext() { + if (inner != null && inner.hasNext()) { + return true; + } + while (iterator.hasNext()) { + // TODO nextLong + final long arg = iterator.next(); + final LongStream result = mapper.apply(arg); + if (result == null) { + continue; + } + if (result.iterator().hasNext()) { + inner = result.iterator(); + return true; + } + } + return false; + } + + @Override + public long nextLong() { + if (inner == null) { + throw new NoSuchElementException(); + } + return inner.nextLong(); + } +} diff --git a/stream/src/main/java/com/annimon/stream/operator/LongGenerate.java b/stream/src/main/java/com/annimon/stream/operator/LongGenerate.java new file mode 100644 index 00000000..01082982 --- /dev/null +++ b/stream/src/main/java/com/annimon/stream/operator/LongGenerate.java @@ -0,0 +1,23 @@ +package com.annimon.stream.operator; + +import com.annimon.stream.PrimitiveIterator; +import com.annimon.stream.function.LongSupplier; + +public class LongGenerate extends PrimitiveIterator.OfLong { + + private final LongSupplier supplier; + + public LongGenerate(LongSupplier supplier) { + this.supplier = supplier; + } + + @Override + public boolean hasNext() { + return true; + } + + @Override + public long nextLong() { + return supplier.getAsLong(); + } +} diff --git a/stream/src/main/java/com/annimon/stream/operator/LongIterate.java b/stream/src/main/java/com/annimon/stream/operator/LongIterate.java new file mode 100644 index 00000000..fd85bf7c --- /dev/null +++ b/stream/src/main/java/com/annimon/stream/operator/LongIterate.java @@ -0,0 +1,27 @@ +package com.annimon.stream.operator; + +import com.annimon.stream.PrimitiveIterator; +import com.annimon.stream.function.LongUnaryOperator; + +public class LongIterate extends PrimitiveIterator.OfLong { + + private final LongUnaryOperator op; + private long current; + + public LongIterate(long seed, LongUnaryOperator f) { + this.op = f; + current = seed; + } + + @Override + public boolean hasNext() { + return true; + } + + @Override + public long nextLong() { + final long old = current; + current = op.applyAsLong(current); + return old; + } +} diff --git a/stream/src/main/java/com/annimon/stream/operator/LongLimit.java b/stream/src/main/java/com/annimon/stream/operator/LongLimit.java new file mode 100644 index 00000000..1e309a5f --- /dev/null +++ b/stream/src/main/java/com/annimon/stream/operator/LongLimit.java @@ -0,0 +1,27 @@ +package com.annimon.stream.operator; + +import com.annimon.stream.PrimitiveIterator; + +public class LongLimit extends PrimitiveIterator.OfLong { + + private final PrimitiveIterator.OfLong iterator; + private final long maxSize; + private long index; + + public LongLimit(PrimitiveIterator.OfLong iterator, long maxSize) { + this.iterator = iterator; + this.maxSize = maxSize; + index = 0; + } + + @Override + public boolean hasNext() { + return (index < maxSize) && iterator.hasNext(); + } + + @Override + public long nextLong() { + index++; + return iterator.nextLong(); + } +} diff --git a/stream/src/main/java/com/annimon/stream/operator/LongMap.java b/stream/src/main/java/com/annimon/stream/operator/LongMap.java new file mode 100644 index 00000000..acabc3a3 --- /dev/null +++ b/stream/src/main/java/com/annimon/stream/operator/LongMap.java @@ -0,0 +1,25 @@ +package com.annimon.stream.operator; + +import com.annimon.stream.PrimitiveIterator; +import com.annimon.stream.function.LongUnaryOperator; + +public class LongMap extends PrimitiveIterator.OfLong { + + private final PrimitiveIterator.OfLong iterator; + private final LongUnaryOperator mapper; + + public LongMap(PrimitiveIterator.OfLong iterator, LongUnaryOperator mapper) { + this.iterator = iterator; + this.mapper = mapper; + } + + @Override + public boolean hasNext() { + return iterator.hasNext(); + } + + @Override + public long nextLong() { + return mapper.applyAsLong(iterator.nextLong()); + } +} diff --git a/stream/src/main/java/com/annimon/stream/operator/LongMapToDouble.java b/stream/src/main/java/com/annimon/stream/operator/LongMapToDouble.java new file mode 100644 index 00000000..69406e41 --- /dev/null +++ b/stream/src/main/java/com/annimon/stream/operator/LongMapToDouble.java @@ -0,0 +1,25 @@ +package com.annimon.stream.operator; + +import com.annimon.stream.PrimitiveIterator; +import com.annimon.stream.function.LongToDoubleFunction; + +public class LongMapToDouble extends PrimitiveIterator.OfDouble { + + private final PrimitiveIterator.OfLong iterator; + private final LongToDoubleFunction mapper; + + public LongMapToDouble(PrimitiveIterator.OfLong iterator, LongToDoubleFunction mapper) { + this.iterator = iterator; + this.mapper = mapper; + } + + @Override + public boolean hasNext() { + return iterator.hasNext(); + } + + @Override + public double nextDouble() { + return mapper.applyAsDouble(iterator.nextLong()); + } +} diff --git a/stream/src/main/java/com/annimon/stream/operator/LongMapToInt.java b/stream/src/main/java/com/annimon/stream/operator/LongMapToInt.java new file mode 100644 index 00000000..3fe5c427 --- /dev/null +++ b/stream/src/main/java/com/annimon/stream/operator/LongMapToInt.java @@ -0,0 +1,25 @@ +package com.annimon.stream.operator; + +import com.annimon.stream.PrimitiveIterator; +import com.annimon.stream.function.LongToIntFunction; + +public class LongMapToInt extends PrimitiveIterator.OfInt { + + private final PrimitiveIterator.OfLong iterator; + private final LongToIntFunction mapper; + + public LongMapToInt(PrimitiveIterator.OfLong iterator, LongToIntFunction mapper) { + this.iterator = iterator; + this.mapper = mapper; + } + + @Override + public boolean hasNext() { + return iterator.hasNext(); + } + + @Override + public int nextInt() { + return mapper.applyAsInt(iterator.nextLong()); + } +} diff --git a/stream/src/main/java/com/annimon/stream/operator/LongMapToObj.java b/stream/src/main/java/com/annimon/stream/operator/LongMapToObj.java new file mode 100644 index 00000000..8caa499d --- /dev/null +++ b/stream/src/main/java/com/annimon/stream/operator/LongMapToObj.java @@ -0,0 +1,26 @@ +package com.annimon.stream.operator; + +import com.annimon.stream.LsaIterator; +import com.annimon.stream.PrimitiveIterator; +import com.annimon.stream.function.LongFunction; + +public class LongMapToObj extends LsaIterator { + + private final PrimitiveIterator.OfLong iterator; + private final LongFunction mapper; + + public LongMapToObj(PrimitiveIterator.OfLong iterator, LongFunction mapper) { + this.iterator = iterator; + this.mapper = mapper; + } + + @Override + public boolean hasNext() { + return iterator.hasNext(); + } + + @Override + public R nextIteration() { + return mapper.apply(iterator.nextLong()); + } +} diff --git a/stream/src/main/java/com/annimon/stream/operator/LongPeek.java b/stream/src/main/java/com/annimon/stream/operator/LongPeek.java new file mode 100644 index 00000000..0a69148c --- /dev/null +++ b/stream/src/main/java/com/annimon/stream/operator/LongPeek.java @@ -0,0 +1,27 @@ +package com.annimon.stream.operator; + +import com.annimon.stream.PrimitiveIterator; +import com.annimon.stream.function.LongConsumer; + +public class LongPeek extends PrimitiveIterator.OfLong { + + private final PrimitiveIterator.OfLong iterator; + private final LongConsumer action; + + public LongPeek(PrimitiveIterator.OfLong iterator, LongConsumer action) { + this.iterator = iterator; + this.action = action; + } + + @Override + public boolean hasNext() { + return iterator.hasNext(); + } + + @Override + public long nextLong() { + final long value = iterator.nextLong(); + action.accept(value); + return value; + } +} diff --git a/stream/src/main/java/com/annimon/stream/operator/LongRangeClosed.java b/stream/src/main/java/com/annimon/stream/operator/LongRangeClosed.java new file mode 100644 index 00000000..13048bb3 --- /dev/null +++ b/stream/src/main/java/com/annimon/stream/operator/LongRangeClosed.java @@ -0,0 +1,30 @@ +package com.annimon.stream.operator; + +import com.annimon.stream.PrimitiveIterator; + +public class LongRangeClosed extends PrimitiveIterator.OfLong { + + private final long endInclusive; + private long current; + private boolean hasNext; + + public LongRangeClosed(long startInclusive, long endInclusive) { + this.endInclusive = endInclusive; + current = startInclusive; + hasNext = current <= endInclusive; + } + + @Override + public boolean hasNext() { + return hasNext; + } + + @Override + public long nextLong() { + if (current >= endInclusive) { + hasNext = false; + return endInclusive; + } + return current++; + } +} diff --git a/stream/src/main/java/com/annimon/stream/operator/LongSample.java b/stream/src/main/java/com/annimon/stream/operator/LongSample.java new file mode 100644 index 00000000..9d6e923b --- /dev/null +++ b/stream/src/main/java/com/annimon/stream/operator/LongSample.java @@ -0,0 +1,30 @@ +package com.annimon.stream.operator; + +import com.annimon.stream.PrimitiveIterator; + +public class LongSample extends PrimitiveIterator.OfLong { + + private final PrimitiveIterator.OfLong iterator; + private final int stepWidth; + + public LongSample(PrimitiveIterator.OfLong iterator, int stepWidth) { + this.iterator = iterator; + this.stepWidth = stepWidth; + } + + @Override + public boolean hasNext() { + return iterator.hasNext(); + } + + @Override + public long nextLong() { + final long result = iterator.nextLong(); + int skip = 1; + while (skip < stepWidth && iterator.hasNext()) { + iterator.nextLong(); + skip++; + } + return result; + } +} diff --git a/stream/src/main/java/com/annimon/stream/operator/LongScan.java b/stream/src/main/java/com/annimon/stream/operator/LongScan.java new file mode 100644 index 00000000..d651faae --- /dev/null +++ b/stream/src/main/java/com/annimon/stream/operator/LongScan.java @@ -0,0 +1,30 @@ +package com.annimon.stream.operator; + +import com.annimon.stream.PrimitiveExtIterator; +import com.annimon.stream.PrimitiveIterator; +import com.annimon.stream.function.LongBinaryOperator; + +public class LongScan extends PrimitiveExtIterator.OfLong { + + private final PrimitiveIterator.OfLong iterator; + private final LongBinaryOperator accumulator; + + public LongScan(PrimitiveIterator.OfLong iterator, LongBinaryOperator accumulator) { + this.iterator = iterator; + this.accumulator = accumulator; + } + + @Override + protected void nextIteration() { + hasNext = iterator.hasNext(); + if (hasNext) { + // TODO nextLong + final long current = iterator.next(); + if (isInit) { + next = accumulator.applyAsLong(next, current); + } else { + next = current; + } + } + } +} diff --git a/stream/src/main/java/com/annimon/stream/operator/LongScanIdentity.java b/stream/src/main/java/com/annimon/stream/operator/LongScanIdentity.java new file mode 100644 index 00000000..2cd628f1 --- /dev/null +++ b/stream/src/main/java/com/annimon/stream/operator/LongScanIdentity.java @@ -0,0 +1,33 @@ +package com.annimon.stream.operator; + +import com.annimon.stream.PrimitiveExtIterator; +import com.annimon.stream.PrimitiveIterator; +import com.annimon.stream.function.LongBinaryOperator; + +public class LongScanIdentity extends PrimitiveExtIterator.OfLong { + + private final PrimitiveIterator.OfLong iterator; + private final long identity; + private final LongBinaryOperator accumulator; + + public LongScanIdentity(PrimitiveIterator.OfLong iterator, long identity, LongBinaryOperator accumulator) { + this.iterator = iterator; + this.identity = identity; + this.accumulator = accumulator; + } + + @Override + protected void nextIteration() { + if (!isInit) { + // Return identity + hasNext = true; + next = identity; + return; + } + hasNext = iterator.hasNext(); + if (hasNext) { + final long current = iterator.next(); + next = accumulator.applyAsLong(next, current); + } + } +} diff --git a/stream/src/main/java/com/annimon/stream/operator/LongSingleElement.java b/stream/src/main/java/com/annimon/stream/operator/LongSingleElement.java new file mode 100644 index 00000000..f205abff --- /dev/null +++ b/stream/src/main/java/com/annimon/stream/operator/LongSingleElement.java @@ -0,0 +1,25 @@ +package com.annimon.stream.operator; + +import com.annimon.stream.PrimitiveIterator; + +public class LongSingleElement extends PrimitiveIterator.OfLong { + + private final long element; + private boolean hasNext; + + public LongSingleElement(long element) { + this.element = element; + hasNext = true; + } + + @Override + public boolean hasNext() { + return hasNext; + } + + @Override + public long nextLong() { + hasNext = false; + return element; + } +} diff --git a/stream/src/main/java/com/annimon/stream/operator/LongSkip.java b/stream/src/main/java/com/annimon/stream/operator/LongSkip.java new file mode 100644 index 00000000..10bed018 --- /dev/null +++ b/stream/src/main/java/com/annimon/stream/operator/LongSkip.java @@ -0,0 +1,33 @@ +package com.annimon.stream.operator; + +import com.annimon.stream.PrimitiveIterator; + +public class LongSkip extends PrimitiveIterator.OfLong { + + private final PrimitiveIterator.OfLong iterator; + private final long n; + private long skipped; + + public LongSkip(PrimitiveIterator.OfLong iterator, long n) { + this.iterator = iterator; + this.n = n; + skipped = 0; + } + + @Override + public boolean hasNext() { + while (iterator.hasNext()) { + if (skipped == n) { + break; + } + iterator.nextLong(); + skipped++; + } + return iterator.hasNext(); + } + + @Override + public long nextLong() { + return iterator.nextLong(); + } +} diff --git a/stream/src/main/java/com/annimon/stream/operator/LongSorted.java b/stream/src/main/java/com/annimon/stream/operator/LongSorted.java new file mode 100644 index 00000000..e4f6b086 --- /dev/null +++ b/stream/src/main/java/com/annimon/stream/operator/LongSorted.java @@ -0,0 +1,30 @@ +package com.annimon.stream.operator; + +import com.annimon.stream.internal.Operators; +import com.annimon.stream.PrimitiveExtIterator; +import com.annimon.stream.PrimitiveIterator; +import java.util.Arrays; + +public class LongSorted extends PrimitiveExtIterator.OfLong { + + private final PrimitiveIterator.OfLong iterator; + private int index; + private long[] array; + + public LongSorted(PrimitiveIterator.OfLong iterator) { + this.iterator = iterator; + index = 0; + } + + @Override + protected void nextIteration() { + if (!isInit) { + array = Operators.toLongArray(iterator); + Arrays.sort(array); + } + hasNext = index < array.length; + if (hasNext) { + next = array[index++]; + } + } +} diff --git a/stream/src/main/java/com/annimon/stream/operator/LongTakeUntil.java b/stream/src/main/java/com/annimon/stream/operator/LongTakeUntil.java new file mode 100644 index 00000000..f4599282 --- /dev/null +++ b/stream/src/main/java/com/annimon/stream/operator/LongTakeUntil.java @@ -0,0 +1,24 @@ +package com.annimon.stream.operator; + +import com.annimon.stream.PrimitiveExtIterator; +import com.annimon.stream.PrimitiveIterator; +import com.annimon.stream.function.LongPredicate; + +public class LongTakeUntil extends PrimitiveExtIterator.OfLong { + + private final PrimitiveIterator.OfLong iterator; + private final LongPredicate stopPredicate; + + public LongTakeUntil(PrimitiveIterator.OfLong iterator, LongPredicate stopPredicate) { + this.iterator = iterator; + this.stopPredicate = stopPredicate; + } + + @Override + protected void nextIteration() { + hasNext = iterator.hasNext() && !(isInit && stopPredicate.test(next)); + if (hasNext) { + next = iterator.next(); + } + } +} diff --git a/stream/src/main/java/com/annimon/stream/operator/LongTakeWhile.java b/stream/src/main/java/com/annimon/stream/operator/LongTakeWhile.java new file mode 100644 index 00000000..fd44ea10 --- /dev/null +++ b/stream/src/main/java/com/annimon/stream/operator/LongTakeWhile.java @@ -0,0 +1,22 @@ +package com.annimon.stream.operator; + +import com.annimon.stream.PrimitiveExtIterator; +import com.annimon.stream.PrimitiveIterator; +import com.annimon.stream.function.LongPredicate; + +public class LongTakeWhile extends PrimitiveExtIterator.OfLong { + + private final PrimitiveIterator.OfLong iterator; + private final LongPredicate predicate; + + public LongTakeWhile(PrimitiveIterator.OfLong iterator, LongPredicate predicate) { + this.iterator = iterator; + this.predicate = predicate; + } + + @Override + protected void nextIteration() { + hasNext = iterator.hasNext() + && predicate.test(next = iterator.next()); + } +} diff --git a/stream/src/main/java/com/annimon/stream/operator/ObjArray.java b/stream/src/main/java/com/annimon/stream/operator/ObjArray.java new file mode 100644 index 00000000..c2e4a3be --- /dev/null +++ b/stream/src/main/java/com/annimon/stream/operator/ObjArray.java @@ -0,0 +1,24 @@ +package com.annimon.stream.operator; + +import com.annimon.stream.LsaIterator; + +public class ObjArray extends LsaIterator { + + private final T[] elements; + private int index; + + public ObjArray(T[] elements) { + this.elements = elements; + index = 0; + } + + @Override + public boolean hasNext() { + return index < elements.length; + } + + @Override + public T nextIteration() { + return elements[index++]; + } +} diff --git a/stream/src/main/java/com/annimon/stream/operator/ObjChunkBy.java b/stream/src/main/java/com/annimon/stream/operator/ObjChunkBy.java new file mode 100644 index 00000000..fbfb9bc7 --- /dev/null +++ b/stream/src/main/java/com/annimon/stream/operator/ObjChunkBy.java @@ -0,0 +1,51 @@ +package com.annimon.stream.operator; + +import com.annimon.stream.LsaIterator; +import com.annimon.stream.function.Function; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +public class ObjChunkBy extends LsaIterator> { + + private final Iterator iterator; + private final Function classifier; + private T next; + private boolean peekedNext; + + public ObjChunkBy(Iterator iterator, Function classifier) { + this.iterator = iterator; + this.classifier = classifier; + } + + @Override + public boolean hasNext() { + return peekedNext || iterator.hasNext(); + } + + @Override + public List nextIteration() { + final K key = classifier.apply(peek()); + + final List list = new ArrayList(); + do { + list.add(takeNext()); + } while ( iterator.hasNext() && key.equals(classifier.apply(peek())) ); + + return list; + } + + private T takeNext() { + final T element = peek(); + peekedNext = false; + return element; + } + + private T peek() { + if (!peekedNext) { + next = iterator.next(); + peekedNext = true; + } + return next; + } +} diff --git a/stream/src/main/java/com/annimon/stream/operator/ObjConcat.java b/stream/src/main/java/com/annimon/stream/operator/ObjConcat.java new file mode 100644 index 00000000..997b34ab --- /dev/null +++ b/stream/src/main/java/com/annimon/stream/operator/ObjConcat.java @@ -0,0 +1,30 @@ +package com.annimon.stream.operator; + +import com.annimon.stream.LsaExtIterator; +import java.util.Iterator; + +public class ObjConcat extends LsaExtIterator { + + private final Iterator iterator1; + private final Iterator iterator2; + + public ObjConcat(Iterator iterator1, Iterator iterator2) { + this.iterator1 = iterator1; + this.iterator2 = iterator2; + } + + @Override + protected void nextIteration() { + if (iterator1.hasNext()) { + next = iterator1.next(); + hasNext = true; + return; + } + if (iterator2.hasNext()) { + next = iterator2.next(); + hasNext = true; + return; + } + hasNext = false; + } +} diff --git a/stream/src/main/java/com/annimon/stream/operator/ObjDistinct.java b/stream/src/main/java/com/annimon/stream/operator/ObjDistinct.java new file mode 100644 index 00000000..43cb13e5 --- /dev/null +++ b/stream/src/main/java/com/annimon/stream/operator/ObjDistinct.java @@ -0,0 +1,28 @@ +package com.annimon.stream.operator; + +import com.annimon.stream.LsaExtIterator; +import java.util.HashSet; +import java.util.Iterator; +import java.util.Set; + +public class ObjDistinct extends LsaExtIterator { + + private final Iterator iterator; + private final Set set; + + public ObjDistinct(Iterator iterator) { + this.iterator = iterator; + set = new HashSet(); + } + + @Override + protected void nextIteration() { + while (hasNext = iterator.hasNext()) { + next = iterator.next(); + if (!set.contains(next)) { + set.add(next); + return; + } + } + } +} diff --git a/stream/src/main/java/com/annimon/stream/operator/ObjDropWhile.java b/stream/src/main/java/com/annimon/stream/operator/ObjDropWhile.java new file mode 100644 index 00000000..12c1a62a --- /dev/null +++ b/stream/src/main/java/com/annimon/stream/operator/ObjDropWhile.java @@ -0,0 +1,34 @@ +package com.annimon.stream.operator; + +import com.annimon.stream.LsaExtIterator; +import com.annimon.stream.function.Predicate; +import java.util.Iterator; + +public class ObjDropWhile extends LsaExtIterator { + + private final Iterator iterator; + private final Predicate predicate; + + public ObjDropWhile(Iterator iterator, Predicate predicate) { + this.iterator = iterator; + this.predicate = predicate; + } + + @Override + protected void nextIteration() { + if (!isInit) { + // Skip first time + while (hasNext = iterator.hasNext()) { + next = iterator.next(); + if (!predicate.test(next)) { + return; + } + } + } + + hasNext = hasNext && iterator.hasNext(); + if (!hasNext) return; + + next = iterator.next(); + } +} diff --git a/stream/src/main/java/com/annimon/stream/operator/ObjFilter.java b/stream/src/main/java/com/annimon/stream/operator/ObjFilter.java new file mode 100644 index 00000000..343bcdd4 --- /dev/null +++ b/stream/src/main/java/com/annimon/stream/operator/ObjFilter.java @@ -0,0 +1,55 @@ +package com.annimon.stream.operator; + +import com.annimon.stream.function.Predicate; +import java.util.Iterator; +import java.util.NoSuchElementException; + +public class ObjFilter implements Iterator { + + private final Iterator iterator; + private final Predicate predicate; + private boolean hasNext, hasNextEvaluated; + private T next; + + public ObjFilter(Iterator iterator, Predicate predicate) { + this.iterator = iterator; + this.predicate = predicate; + } + + @Override + public boolean hasNext() { + if (!hasNextEvaluated) { + nextIteration(); + hasNextEvaluated = true; + } + return hasNext; + } + + @Override + public T next() { + if (!hasNextEvaluated) { + hasNext = hasNext(); + } + if (!hasNext) { + throw new NoSuchElementException(); + } + hasNextEvaluated = false; + return next; + } + + private void nextIteration() { + while (iterator.hasNext()) { + next = iterator.next(); + if (predicate.test(next)) { + hasNext = true; + return; + } + } + hasNext = false; + } + + @Override + public void remove() { + throw new UnsupportedOperationException("remove not supported"); + } +} diff --git a/stream/src/main/java/com/annimon/stream/operator/ObjFlatMap.java b/stream/src/main/java/com/annimon/stream/operator/ObjFlatMap.java new file mode 100644 index 00000000..566ded32 --- /dev/null +++ b/stream/src/main/java/com/annimon/stream/operator/ObjFlatMap.java @@ -0,0 +1,43 @@ +package com.annimon.stream.operator; + +import com.annimon.stream.LsaExtIterator; +import com.annimon.stream.Stream; +import com.annimon.stream.function.Function; +import java.util.Iterator; + +public class ObjFlatMap extends LsaExtIterator { + + private final Iterator iterator; + private final Function> mapper; + private Iterator inner; + + public ObjFlatMap(Iterator iterator, + Function> mapper) { + this.iterator = iterator; + this.mapper = mapper; + } + + @Override + protected void nextIteration() { + if ((inner != null) && inner.hasNext()) { + next = inner.next(); + hasNext = true; + return; + } + while (iterator.hasNext()) { + if (inner == null || !inner.hasNext()) { + final T arg = iterator.next(); + final Stream result = mapper.apply(arg); + if (result != null) { + inner = result.iterator(); + } + } + if ((inner != null) && inner.hasNext()) { + next = inner.next(); + hasNext = true; + return; + } + } + hasNext = false; + } +} diff --git a/stream/src/main/java/com/annimon/stream/operator/ObjFlatMapToDouble.java b/stream/src/main/java/com/annimon/stream/operator/ObjFlatMapToDouble.java new file mode 100644 index 00000000..f74ead39 --- /dev/null +++ b/stream/src/main/java/com/annimon/stream/operator/ObjFlatMapToDouble.java @@ -0,0 +1,44 @@ +package com.annimon.stream.operator; + +import com.annimon.stream.DoubleStream; +import com.annimon.stream.PrimitiveExtIterator; +import com.annimon.stream.PrimitiveIterator; +import com.annimon.stream.function.Function; +import java.util.Iterator; + +public class ObjFlatMapToDouble extends PrimitiveExtIterator.OfDouble { + + private final Iterator iterator; + private final Function mapper; + private PrimitiveIterator.OfDouble inner; + + public ObjFlatMapToDouble(Iterator iterator, + Function mapper) { + this.iterator = iterator; + this.mapper = mapper; + } + + @Override + protected void nextIteration() { + if ((inner != null) && inner.hasNext()) { + next = inner.next(); + hasNext = true; + return; + } + while (iterator.hasNext()) { + if (inner == null || !inner.hasNext()) { + final T arg = iterator.next(); + final DoubleStream result = mapper.apply(arg); + if (result != null) { + inner = result.iterator(); + } + } + if ((inner != null) && inner.hasNext()) { + next = inner.next(); + hasNext = true; + return; + } + } + hasNext = false; + } +} diff --git a/stream/src/main/java/com/annimon/stream/operator/ObjFlatMapToInt.java b/stream/src/main/java/com/annimon/stream/operator/ObjFlatMapToInt.java new file mode 100644 index 00000000..161e1021 --- /dev/null +++ b/stream/src/main/java/com/annimon/stream/operator/ObjFlatMapToInt.java @@ -0,0 +1,43 @@ +package com.annimon.stream.operator; + +import com.annimon.stream.IntStream; +import com.annimon.stream.PrimitiveExtIterator; +import com.annimon.stream.PrimitiveIterator; +import com.annimon.stream.function.Function; +import java.util.Iterator; + +public class ObjFlatMapToInt extends PrimitiveExtIterator.OfInt { + + private final Iterator iterator; + private final Function mapper; + private PrimitiveIterator.OfInt inner; + + public ObjFlatMapToInt(Iterator iterator, Function mapper) { + this.iterator = iterator; + this.mapper = mapper; + } + + @Override + protected void nextIteration() { + if ((inner != null) && inner.hasNext()) { + next = inner.next(); + hasNext = true; + return; + } + while (iterator.hasNext()) { + if (inner == null || !inner.hasNext()) { + final T arg = iterator.next(); + final IntStream result = mapper.apply(arg); + if (result != null) { + inner = result.iterator(); + } + } + if ((inner != null) && inner.hasNext()) { + next = inner.next(); + hasNext = true; + return; + } + } + hasNext = false; + } +} diff --git a/stream/src/main/java/com/annimon/stream/operator/ObjFlatMapToLong.java b/stream/src/main/java/com/annimon/stream/operator/ObjFlatMapToLong.java new file mode 100644 index 00000000..a38294f7 --- /dev/null +++ b/stream/src/main/java/com/annimon/stream/operator/ObjFlatMapToLong.java @@ -0,0 +1,44 @@ +package com.annimon.stream.operator; + +import com.annimon.stream.LongStream; +import com.annimon.stream.PrimitiveExtIterator; +import com.annimon.stream.PrimitiveIterator; +import com.annimon.stream.function.Function; +import java.util.Iterator; + +public class ObjFlatMapToLong extends PrimitiveExtIterator.OfLong { + + private final Iterator iterator; + private final Function mapper; + private PrimitiveIterator.OfLong inner; + + public ObjFlatMapToLong(Iterator iterator, + Function mapper) { + this.iterator = iterator; + this.mapper = mapper; + } + + @Override + protected void nextIteration() { + if ((inner != null) && inner.hasNext()) { + next = inner.next(); + hasNext = true; + return; + } + while (iterator.hasNext()) { + if (inner == null || !inner.hasNext()) { + final T arg = iterator.next(); + final LongStream result = mapper.apply(arg); + if (result != null) { + inner = result.iterator(); + } + } + if ((inner != null) && inner.hasNext()) { + next = inner.next(); + hasNext = true; + return; + } + } + hasNext = false; + } +} diff --git a/stream/src/main/java/com/annimon/stream/operator/ObjGenerate.java b/stream/src/main/java/com/annimon/stream/operator/ObjGenerate.java new file mode 100644 index 00000000..9b7b26ab --- /dev/null +++ b/stream/src/main/java/com/annimon/stream/operator/ObjGenerate.java @@ -0,0 +1,23 @@ +package com.annimon.stream.operator; + +import com.annimon.stream.LsaIterator; +import com.annimon.stream.function.Supplier; + +public class ObjGenerate extends LsaIterator { + + private final Supplier supplier; + + public ObjGenerate(Supplier supplier) { + this.supplier = supplier; + } + + @Override + public boolean hasNext() { + return true; + } + + @Override + public T nextIteration() { + return supplier.get(); + } +} diff --git a/stream/src/main/java/com/annimon/stream/operator/ObjIterate.java b/stream/src/main/java/com/annimon/stream/operator/ObjIterate.java new file mode 100644 index 00000000..916bd9a5 --- /dev/null +++ b/stream/src/main/java/com/annimon/stream/operator/ObjIterate.java @@ -0,0 +1,27 @@ +package com.annimon.stream.operator; + +import com.annimon.stream.LsaIterator; +import com.annimon.stream.function.UnaryOperator; + +public class ObjIterate extends LsaIterator { + + private final UnaryOperator op; + private T current; + + public ObjIterate(T seed, UnaryOperator op) { + this.op = op; + current = seed; + } + + @Override + public boolean hasNext() { + return true; + } + + @Override + public T nextIteration() { + final T old = current; + current = op.apply(current); + return old; + } +} diff --git a/stream/src/main/java/com/annimon/stream/operator/ObjLimit.java b/stream/src/main/java/com/annimon/stream/operator/ObjLimit.java new file mode 100644 index 00000000..657c1dce --- /dev/null +++ b/stream/src/main/java/com/annimon/stream/operator/ObjLimit.java @@ -0,0 +1,28 @@ +package com.annimon.stream.operator; + +import com.annimon.stream.LsaIterator; +import java.util.Iterator; + +public class ObjLimit extends LsaIterator { + + private final Iterator iterator; + private final long maxSize; + private long index; + + public ObjLimit(Iterator iterator, long maxSize) { + this.iterator = iterator; + this.maxSize = maxSize; + index = 0; + } + + @Override + public boolean hasNext() { + return (index < maxSize) && iterator.hasNext(); + } + + @Override + public T nextIteration() { + index++; + return iterator.next(); + } +} diff --git a/stream/src/main/java/com/annimon/stream/operator/ObjMap.java b/stream/src/main/java/com/annimon/stream/operator/ObjMap.java new file mode 100644 index 00000000..76c85f1c --- /dev/null +++ b/stream/src/main/java/com/annimon/stream/operator/ObjMap.java @@ -0,0 +1,26 @@ +package com.annimon.stream.operator; + +import com.annimon.stream.LsaIterator; +import com.annimon.stream.function.Function; +import java.util.Iterator; + +public class ObjMap extends LsaIterator { + + private final Iterator iterator; + private final Function mapper; + + public ObjMap(Iterator iterator, Function mapper) { + this.iterator = iterator; + this.mapper = mapper; + } + + @Override + public boolean hasNext() { + return iterator.hasNext(); + } + + @Override + public R nextIteration() { + return mapper.apply(iterator.next()); + } +} diff --git a/stream/src/main/java/com/annimon/stream/operator/ObjMapToDouble.java b/stream/src/main/java/com/annimon/stream/operator/ObjMapToDouble.java new file mode 100644 index 00000000..1be4167a --- /dev/null +++ b/stream/src/main/java/com/annimon/stream/operator/ObjMapToDouble.java @@ -0,0 +1,26 @@ +package com.annimon.stream.operator; + +import com.annimon.stream.PrimitiveIterator; +import com.annimon.stream.function.ToDoubleFunction; +import java.util.Iterator; + +public class ObjMapToDouble extends PrimitiveIterator.OfDouble { + + private final Iterator iterator; + private final ToDoubleFunction mapper; + + public ObjMapToDouble(Iterator iterator, ToDoubleFunction mapper) { + this.iterator = iterator; + this.mapper = mapper; + } + + @Override + public boolean hasNext() { + return iterator.hasNext(); + } + + @Override + public double nextDouble() { + return mapper.applyAsDouble(iterator.next()); + } +} diff --git a/stream/src/main/java/com/annimon/stream/operator/ObjMapToInt.java b/stream/src/main/java/com/annimon/stream/operator/ObjMapToInt.java new file mode 100644 index 00000000..8fd2cf57 --- /dev/null +++ b/stream/src/main/java/com/annimon/stream/operator/ObjMapToInt.java @@ -0,0 +1,26 @@ +package com.annimon.stream.operator; + +import com.annimon.stream.PrimitiveIterator; +import com.annimon.stream.function.ToIntFunction; +import java.util.Iterator; + +public class ObjMapToInt extends PrimitiveIterator.OfInt { + + private final Iterator iterator; + private final ToIntFunction mapper; + + public ObjMapToInt(Iterator iterator, ToIntFunction mapper) { + this.iterator = iterator; + this.mapper = mapper; + } + + @Override + public boolean hasNext() { + return iterator.hasNext(); + } + + @Override + public int nextInt() { + return mapper.applyAsInt(iterator.next()); + } +} diff --git a/stream/src/main/java/com/annimon/stream/operator/ObjMapToLong.java b/stream/src/main/java/com/annimon/stream/operator/ObjMapToLong.java new file mode 100644 index 00000000..49a79fb2 --- /dev/null +++ b/stream/src/main/java/com/annimon/stream/operator/ObjMapToLong.java @@ -0,0 +1,26 @@ +package com.annimon.stream.operator; + +import com.annimon.stream.PrimitiveIterator; +import com.annimon.stream.function.ToLongFunction; +import java.util.Iterator; + +public class ObjMapToLong extends PrimitiveIterator.OfLong { + + private final Iterator iterator; + private final ToLongFunction mapper; + + public ObjMapToLong(Iterator iterator, ToLongFunction mapper) { + this.iterator = iterator; + this.mapper = mapper; + } + + @Override + public boolean hasNext() { + return iterator.hasNext(); + } + + @Override + public long nextLong() { + return mapper.applyAsLong(iterator.next()); + } +} diff --git a/stream/src/main/java/com/annimon/stream/operator/ObjPeek.java b/stream/src/main/java/com/annimon/stream/operator/ObjPeek.java new file mode 100644 index 00000000..acd27223 --- /dev/null +++ b/stream/src/main/java/com/annimon/stream/operator/ObjPeek.java @@ -0,0 +1,28 @@ +package com.annimon.stream.operator; + +import com.annimon.stream.LsaIterator; +import com.annimon.stream.function.Consumer; +import java.util.Iterator; + +public class ObjPeek extends LsaIterator { + + private final Iterator iterator; + private final Consumer action; + + public ObjPeek(Iterator iterator, Consumer action) { + this.iterator = iterator; + this.action = action; + } + + @Override + public boolean hasNext() { + return iterator.hasNext(); + } + + @Override + public T nextIteration() { + final T value = iterator.next(); + action.accept(value); + return value; + } +} diff --git a/stream/src/main/java/com/annimon/stream/operator/ObjScan.java b/stream/src/main/java/com/annimon/stream/operator/ObjScan.java new file mode 100644 index 00000000..c4ca127b --- /dev/null +++ b/stream/src/main/java/com/annimon/stream/operator/ObjScan.java @@ -0,0 +1,29 @@ +package com.annimon.stream.operator; + +import com.annimon.stream.LsaExtIterator; +import com.annimon.stream.function.BiFunction; +import java.util.Iterator; + +public class ObjScan extends LsaExtIterator { + + private final Iterator iterator; + private final BiFunction accumulator; + + public ObjScan(Iterator iterator, BiFunction accumulator) { + this.iterator = iterator; + this.accumulator = accumulator; + } + + @Override + protected void nextIteration() { + hasNext = iterator.hasNext(); + if (hasNext) { + final T value = iterator.next(); + if (isInit) { + next = accumulator.apply(next, value); + } else { + next = value; + } + } + } +} diff --git a/stream/src/main/java/com/annimon/stream/operator/ObjScanIdentity.java b/stream/src/main/java/com/annimon/stream/operator/ObjScanIdentity.java new file mode 100644 index 00000000..30f9ad83 --- /dev/null +++ b/stream/src/main/java/com/annimon/stream/operator/ObjScanIdentity.java @@ -0,0 +1,34 @@ +package com.annimon.stream.operator; + +import com.annimon.stream.LsaExtIterator; +import com.annimon.stream.function.BiFunction; +import java.util.Iterator; + +public class ObjScanIdentity extends LsaExtIterator { + + private final Iterator iterator; + private final R identity; + private final BiFunction accumulator; + + public ObjScanIdentity(Iterator iterator, R identity, + BiFunction accumulator) { + this.iterator = iterator; + this.identity = identity; + this.accumulator = accumulator; + } + + @Override + protected void nextIteration() { + if (!isInit) { + // Return identity + hasNext = true; + next = identity; + return; + } + hasNext = iterator.hasNext(); + if (hasNext) { + final T t = iterator.next(); + next = accumulator.apply(next, t); + } + } +} diff --git a/stream/src/main/java/com/annimon/stream/operator/ObjSkip.java b/stream/src/main/java/com/annimon/stream/operator/ObjSkip.java new file mode 100644 index 00000000..b31f4b5f --- /dev/null +++ b/stream/src/main/java/com/annimon/stream/operator/ObjSkip.java @@ -0,0 +1,34 @@ +package com.annimon.stream.operator; + +import com.annimon.stream.LsaIterator; +import java.util.Iterator; + +public class ObjSkip extends LsaIterator { + + private final Iterator iterator; + private final long n; + private long skipped; + + public ObjSkip(Iterator iterator, long n) { + this.iterator = iterator; + this.n = n; + skipped = 0; + } + + @Override + public boolean hasNext() { + while (skipped < n) { + if (!iterator.hasNext()) { + return false; + } + iterator.next(); + skipped++; + } + return iterator.hasNext(); + } + + @Override + public T nextIteration() { + return iterator.next(); + } +} diff --git a/stream/src/main/java/com/annimon/stream/operator/ObjSlidingWindow.java b/stream/src/main/java/com/annimon/stream/operator/ObjSlidingWindow.java new file mode 100644 index 00000000..68258aa6 --- /dev/null +++ b/stream/src/main/java/com/annimon/stream/operator/ObjSlidingWindow.java @@ -0,0 +1,53 @@ +package com.annimon.stream.operator; + +import com.annimon.stream.internal.Compat; +import com.annimon.stream.LsaIterator; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.Queue; + +public class ObjSlidingWindow extends LsaIterator> { + + private final Queue queue; + private final Iterator iterator; + private final int windowSize; + private final int stepWidth; + + public ObjSlidingWindow(Iterator iterator, int windowSize, int stepWidth) { + this.iterator = iterator; + this.windowSize = windowSize; + this.stepWidth = stepWidth; + queue = Compat.queue(); + } + + @Override + public boolean hasNext() { + return iterator.hasNext(); + } + + @Override + public List nextIteration() { + int i = queue.size(); + while (i < windowSize && iterator.hasNext()) { + queue.offer(iterator.next()); + i++; + } + + // the elements that are currently in the queue are the elements of our current window + List list = new ArrayList(queue); + + // remove stepWidth elements from the queue + final int pollCount = Math.min(queue.size(), stepWidth); + for (int j = 0; j < pollCount; j++) { + queue.poll(); + } + + // if the stepWidth is greater than the windowSize, skip (stepWidth - windowSize) elements + for (int j = windowSize; j < stepWidth && iterator.hasNext(); j++) { + iterator.next(); + } + + return list; + } +} diff --git a/stream/src/main/java/com/annimon/stream/operator/ObjSorted.java b/stream/src/main/java/com/annimon/stream/operator/ObjSorted.java new file mode 100644 index 00000000..d888f712 --- /dev/null +++ b/stream/src/main/java/com/annimon/stream/operator/ObjSorted.java @@ -0,0 +1,33 @@ +package com.annimon.stream.operator; + +import com.annimon.stream.internal.Operators; +import com.annimon.stream.LsaExtIterator; +import java.util.Collections; +import java.util.Comparator; +import java.util.Iterator; +import java.util.List; + +public class ObjSorted extends LsaExtIterator { + + private final Iterator iterator; + private final Comparator comparator; + private Iterator sortedIterator; + + public ObjSorted(Iterator iterator, Comparator comparator) { + this.iterator = iterator; + this.comparator = comparator; + } + + @Override + protected void nextIteration() { + if (!isInit) { + final List list = Operators.toList(iterator); + Collections.sort(list, comparator); + sortedIterator = list.iterator(); + } + hasNext = sortedIterator.hasNext(); + if (hasNext) { + next = sortedIterator.next(); + } + } +} diff --git a/stream/src/main/java/com/annimon/stream/operator/ObjTakeUntil.java b/stream/src/main/java/com/annimon/stream/operator/ObjTakeUntil.java new file mode 100644 index 00000000..7ebbe06f --- /dev/null +++ b/stream/src/main/java/com/annimon/stream/operator/ObjTakeUntil.java @@ -0,0 +1,24 @@ +package com.annimon.stream.operator; + +import com.annimon.stream.LsaExtIterator; +import com.annimon.stream.function.Predicate; +import java.util.Iterator; + +public class ObjTakeUntil extends LsaExtIterator { + + private final Iterator iterator; + private final Predicate stopPredicate; + + public ObjTakeUntil(Iterator iterator, Predicate predicate) { + this.iterator = iterator; + this.stopPredicate = predicate; + } + + @Override + protected void nextIteration() { + hasNext = iterator.hasNext() && !(isInit && stopPredicate.test(next)); + if (hasNext) { + next = iterator.next(); + } + } +} diff --git a/stream/src/main/java/com/annimon/stream/operator/ObjTakeWhile.java b/stream/src/main/java/com/annimon/stream/operator/ObjTakeWhile.java new file mode 100644 index 00000000..b35f68a5 --- /dev/null +++ b/stream/src/main/java/com/annimon/stream/operator/ObjTakeWhile.java @@ -0,0 +1,22 @@ +package com.annimon.stream.operator; + +import com.annimon.stream.LsaExtIterator; +import com.annimon.stream.function.Predicate; +import java.util.Iterator; + +public class ObjTakeWhile extends LsaExtIterator { + + private final Iterator iterator; + private final Predicate predicate; + + public ObjTakeWhile(Iterator iterator, Predicate predicate) { + this.iterator = iterator; + this.predicate = predicate; + } + + @Override + protected void nextIteration() { + hasNext = iterator.hasNext() + && predicate.test(next = iterator.next()); + } +} diff --git a/stream/src/main/java/com/annimon/stream/operator/ObjZip.java b/stream/src/main/java/com/annimon/stream/operator/ObjZip.java new file mode 100644 index 00000000..f16e4667 --- /dev/null +++ b/stream/src/main/java/com/annimon/stream/operator/ObjZip.java @@ -0,0 +1,29 @@ +package com.annimon.stream.operator; + +import com.annimon.stream.LsaIterator; +import com.annimon.stream.function.BiFunction; +import java.util.Iterator; + +public class ObjZip extends LsaIterator { + + private final Iterator iterator1; + private final Iterator iterator2; + private final BiFunction combiner; + + public ObjZip(Iterator iterator1, Iterator iterator2, + BiFunction combiner) { + this.iterator1 = iterator1; + this.iterator2 = iterator2; + this.combiner = combiner; + } + + @Override + public boolean hasNext() { + return iterator1.hasNext() && iterator2.hasNext(); + } + + @Override + public R nextIteration() { + return combiner.apply(iterator1.next(), iterator2.next()); + } +} diff --git a/stream/src/test/java/com/annimon/stream/StreamTest.java b/stream/src/test/java/com/annimon/stream/StreamTest.java index 412d9108..05e144c6 100644 --- a/stream/src/test/java/com/annimon/stream/StreamTest.java +++ b/stream/src/test/java/com/annimon/stream/StreamTest.java @@ -1554,28 +1554,6 @@ public void testCustomTerminalOperator_Sum() { assertEquals(15, sum); } - @Test - public void testNewArrayCompat() { - String[] strings = new String[] {"abc", "def", "fff"}; - - String[] copy = Compat.newArrayCompat(strings, 5); - - assertEquals(5, copy.length); - assertEquals("abc", copy[0]); - assertEquals(null, copy[3]); - - String[] empty = new String[0]; - - String[] emptyCopy = Compat.newArrayCompat(empty, 3); - - assertEquals(3, emptyCopy.length); - - emptyCopy = Compat.newArrayCompat(empty, 0); - - assertEquals(0, emptyCopy.length); - } - - @Test public void testCustomTerminalOperator_ForEach() { PrintConsumer consumer = new PrintConsumer(); diff --git a/stream/src/test/java/com/annimon/stream/internal/CompatTest.java b/stream/src/test/java/com/annimon/stream/internal/CompatTest.java new file mode 100644 index 00000000..2a4e9567 --- /dev/null +++ b/stream/src/test/java/com/annimon/stream/internal/CompatTest.java @@ -0,0 +1,28 @@ +package com.annimon.stream.internal; + +import org.junit.Test; +import static org.junit.Assert.assertEquals; + +public final class CompatTest { + + @Test + public void testNewArrayCompat() { + String[] strings = new String[] {"abc", "def", "fff"}; + + String[] copy = Compat.newArrayCompat(strings, 5); + + assertEquals(5, copy.length); + assertEquals("abc", copy[0]); + assertEquals(null, copy[3]); + + String[] empty = new String[0]; + + String[] emptyCopy = Compat.newArrayCompat(empty, 3); + + assertEquals(3, emptyCopy.length); + + emptyCopy = Compat.newArrayCompat(empty, 0); + + assertEquals(0, emptyCopy.length); + } +} diff --git a/stream/src/test/java/com/annimon/stream/internal/OperatorsTest.java b/stream/src/test/java/com/annimon/stream/internal/OperatorsTest.java new file mode 100644 index 00000000..adfdd1c2 --- /dev/null +++ b/stream/src/test/java/com/annimon/stream/internal/OperatorsTest.java @@ -0,0 +1,16 @@ +package com.annimon.stream.internal; + +import org.junit.Test; +import static com.annimon.stream.test.hamcrest.CommonMatcher.hasOnlyPrivateConstructors; +import static org.junit.Assert.assertThat; + +/** + * Tests for {@link Operators} +*/ +public class OperatorsTest { + + @Test + public void testPrivateConstructor() { + assertThat(Operators.class, hasOnlyPrivateConstructors()); + } +} diff --git a/stream/src/test/java/com/annimon/stream/SpinedBufferTest.java b/stream/src/test/java/com/annimon/stream/internal/SpinedBufferTest.java similarity index 98% rename from stream/src/test/java/com/annimon/stream/SpinedBufferTest.java rename to stream/src/test/java/com/annimon/stream/internal/SpinedBufferTest.java index c34b1967..d8d4c678 100644 --- a/stream/src/test/java/com/annimon/stream/SpinedBufferTest.java +++ b/stream/src/test/java/com/annimon/stream/internal/SpinedBufferTest.java @@ -1,5 +1,6 @@ -package com.annimon.stream; +package com.annimon.stream.internal; +import com.annimon.stream.PrimitiveIterator; import org.junit.Test; import static com.annimon.stream.test.hamcrest.CommonMatcher.hasOnlyPrivateConstructors; import static org.hamcrest.Matchers.closeTo; @@ -503,7 +504,7 @@ public void testIntToArrayTooBig() { SpinedBuffer.OfInt b = new SpinedBuffer.OfInt() { @Override public long count() { - return Stream.MAX_ARRAY_SIZE; + return Compat.MAX_ARRAY_SIZE; } }; @@ -515,7 +516,7 @@ public void testLongToArrayTooBig() { SpinedBuffer.OfLong b = new SpinedBuffer.OfLong() { @Override public long count() { - return Stream.MAX_ARRAY_SIZE; + return Compat.MAX_ARRAY_SIZE; } }; @@ -527,7 +528,7 @@ public void testDoubleToArrayTooBig() { SpinedBuffer.OfDouble b = new SpinedBuffer.OfDouble() { @Override public long count() { - return Stream.MAX_ARRAY_SIZE; + return Compat.MAX_ARRAY_SIZE; } }; From 36bfd3c089159dcd7841b2dbba9db21b9ee20525 Mon Sep 17 00:00:00 2001 From: Victor Date: Wed, 22 Feb 2017 21:36:19 +0200 Subject: [PATCH 2/6] Fix unnecessary boxing in primitive filter, flatMap, scan, single operators --- stream/src/main/java/com/annimon/stream/DoubleStream.java | 4 ++-- stream/src/main/java/com/annimon/stream/IntStream.java | 4 ++-- stream/src/main/java/com/annimon/stream/LongStream.java | 4 ++-- .../main/java/com/annimon/stream/operator/DoubleFilter.java | 3 +-- .../main/java/com/annimon/stream/operator/DoubleFlatMap.java | 3 +-- .../src/main/java/com/annimon/stream/operator/DoubleScan.java | 3 +-- .../src/main/java/com/annimon/stream/operator/IntFilter.java | 3 +-- .../src/main/java/com/annimon/stream/operator/IntFlatMap.java | 3 +-- .../src/main/java/com/annimon/stream/operator/LongFilter.java | 3 +-- .../main/java/com/annimon/stream/operator/LongFlatMap.java | 3 +-- .../src/main/java/com/annimon/stream/operator/LongScan.java | 3 +-- 11 files changed, 14 insertions(+), 22 deletions(-) diff --git a/stream/src/main/java/com/annimon/stream/DoubleStream.java b/stream/src/main/java/com/annimon/stream/DoubleStream.java index b6826490..fd7aa809 100644 --- a/stream/src/main/java/com/annimon/stream/DoubleStream.java +++ b/stream/src/main/java/com/annimon/stream/DoubleStream.java @@ -965,7 +965,7 @@ public double single() { throw new NoSuchElementException("DoubleStream contains no element"); } - final double singleCandidate = iterator.next(); + final double singleCandidate = iterator.nextDouble(); if (iterator.hasNext()) { throw new IllegalStateException("DoubleStream contains more than one element"); } @@ -1000,7 +1000,7 @@ public OptionalDouble findSingle() { return OptionalDouble.empty(); } - final double singleCandidate = iterator.next(); + final double singleCandidate = iterator.nextDouble(); if (iterator.hasNext()) { throw new IllegalStateException("DoubleStream contains more than one element"); } diff --git a/stream/src/main/java/com/annimon/stream/IntStream.java b/stream/src/main/java/com/annimon/stream/IntStream.java index e4cb77de..ff98f9e9 100644 --- a/stream/src/main/java/com/annimon/stream/IntStream.java +++ b/stream/src/main/java/com/annimon/stream/IntStream.java @@ -1008,7 +1008,7 @@ public OptionalInt findFirst() { */ public int single() { if (iterator.hasNext()) { - int singleCandidate = iterator.next(); + int singleCandidate = iterator.nextInt(); if (iterator.hasNext()) { throw new IllegalStateException("IntStream contains more than one element"); } else { @@ -1044,7 +1044,7 @@ public int single() { */ public OptionalInt findSingle() { if (iterator.hasNext()) { - int singleCandidate = iterator.next(); + int singleCandidate = iterator.nextInt(); if (iterator.hasNext()) { throw new IllegalStateException("IntStream contains more than one element"); } else { diff --git a/stream/src/main/java/com/annimon/stream/LongStream.java b/stream/src/main/java/com/annimon/stream/LongStream.java index 123bd61a..6c04ba5b 100644 --- a/stream/src/main/java/com/annimon/stream/LongStream.java +++ b/stream/src/main/java/com/annimon/stream/LongStream.java @@ -981,7 +981,7 @@ public long single() { throw new NoSuchElementException("LongStream contains no element"); } - final long singleCandidate = iterator.next(); + final long singleCandidate = iterator.nextLong(); if (iterator.hasNext()) { throw new IllegalStateException("LongStream contains more than one element"); } @@ -1016,7 +1016,7 @@ public OptionalLong findSingle() { return OptionalLong.empty(); } - final long singleCandidate = iterator.next(); + final long singleCandidate = iterator.nextLong(); if (iterator.hasNext()) { throw new IllegalStateException("LongStream contains more than one element"); } diff --git a/stream/src/main/java/com/annimon/stream/operator/DoubleFilter.java b/stream/src/main/java/com/annimon/stream/operator/DoubleFilter.java index af0d643c..b4b84c3d 100644 --- a/stream/src/main/java/com/annimon/stream/operator/DoubleFilter.java +++ b/stream/src/main/java/com/annimon/stream/operator/DoubleFilter.java @@ -17,8 +17,7 @@ public DoubleFilter(PrimitiveIterator.OfDouble iterator, DoublePredicate predica @Override public boolean hasNext() { while (iterator.hasNext()) { - // TODO nextDouble - next = iterator.next(); + next = iterator.nextDouble(); if (predicate.test(next)) { return true; } diff --git a/stream/src/main/java/com/annimon/stream/operator/DoubleFlatMap.java b/stream/src/main/java/com/annimon/stream/operator/DoubleFlatMap.java index 9576ca1e..23443b9f 100644 --- a/stream/src/main/java/com/annimon/stream/operator/DoubleFlatMap.java +++ b/stream/src/main/java/com/annimon/stream/operator/DoubleFlatMap.java @@ -22,8 +22,7 @@ public boolean hasNext() { return true; } while (iterator.hasNext()) { - // TODO nextDouble - final double arg = iterator.next(); + final double arg = iterator.nextDouble(); final DoubleStream result = mapper.apply(arg); if (result == null) { continue; diff --git a/stream/src/main/java/com/annimon/stream/operator/DoubleScan.java b/stream/src/main/java/com/annimon/stream/operator/DoubleScan.java index 1097d3b9..b0fe900a 100644 --- a/stream/src/main/java/com/annimon/stream/operator/DoubleScan.java +++ b/stream/src/main/java/com/annimon/stream/operator/DoubleScan.java @@ -18,8 +18,7 @@ public DoubleScan(PrimitiveIterator.OfDouble iterator, DoubleBinaryOperator accu protected void nextIteration() { hasNext = iterator.hasNext(); if (hasNext) { - // TODO nextDouble - final double current = iterator.next(); + final double current = iterator.nextDouble(); if (isInit) { next = accumulator.applyAsDouble(next, current); } else { diff --git a/stream/src/main/java/com/annimon/stream/operator/IntFilter.java b/stream/src/main/java/com/annimon/stream/operator/IntFilter.java index 1cfd6ad2..2eacf57a 100644 --- a/stream/src/main/java/com/annimon/stream/operator/IntFilter.java +++ b/stream/src/main/java/com/annimon/stream/operator/IntFilter.java @@ -17,8 +17,7 @@ public IntFilter(PrimitiveIterator.OfInt iterator, IntPredicate predicate) { @Override public boolean hasNext() { while (iterator.hasNext()) { - // TODO nextInt - next = iterator.next(); + next = iterator.nextInt(); if (predicate.test(next)) { return true; } diff --git a/stream/src/main/java/com/annimon/stream/operator/IntFlatMap.java b/stream/src/main/java/com/annimon/stream/operator/IntFlatMap.java index d6151c9a..6b246798 100644 --- a/stream/src/main/java/com/annimon/stream/operator/IntFlatMap.java +++ b/stream/src/main/java/com/annimon/stream/operator/IntFlatMap.java @@ -22,8 +22,7 @@ public boolean hasNext() { return true; } while (iterator.hasNext()) { - // TODO nextInt - final int arg = iterator.next(); + final int arg = iterator.nextInt(); final IntStream result = mapper.apply(arg); if (result == null) { continue; diff --git a/stream/src/main/java/com/annimon/stream/operator/LongFilter.java b/stream/src/main/java/com/annimon/stream/operator/LongFilter.java index b9798c92..e748c57b 100644 --- a/stream/src/main/java/com/annimon/stream/operator/LongFilter.java +++ b/stream/src/main/java/com/annimon/stream/operator/LongFilter.java @@ -17,8 +17,7 @@ public LongFilter(PrimitiveIterator.OfLong iterator, LongPredicate predicate) { @Override public boolean hasNext() { while (iterator.hasNext()) { - // TODO nextLong - next = iterator.next(); + next = iterator.nextLong(); if (predicate.test(next)) { return true; } diff --git a/stream/src/main/java/com/annimon/stream/operator/LongFlatMap.java b/stream/src/main/java/com/annimon/stream/operator/LongFlatMap.java index a9e181a6..c861e29c 100644 --- a/stream/src/main/java/com/annimon/stream/operator/LongFlatMap.java +++ b/stream/src/main/java/com/annimon/stream/operator/LongFlatMap.java @@ -22,8 +22,7 @@ public boolean hasNext() { return true; } while (iterator.hasNext()) { - // TODO nextLong - final long arg = iterator.next(); + final long arg = iterator.nextLong(); final LongStream result = mapper.apply(arg); if (result == null) { continue; diff --git a/stream/src/main/java/com/annimon/stream/operator/LongScan.java b/stream/src/main/java/com/annimon/stream/operator/LongScan.java index d651faae..b2da5681 100644 --- a/stream/src/main/java/com/annimon/stream/operator/LongScan.java +++ b/stream/src/main/java/com/annimon/stream/operator/LongScan.java @@ -18,8 +18,7 @@ public LongScan(PrimitiveIterator.OfLong iterator, LongBinaryOperator accumulato protected void nextIteration() { hasNext = iterator.hasNext(); if (hasNext) { - // TODO nextLong - final long current = iterator.next(); + final long current = iterator.nextLong(); if (isInit) { next = accumulator.applyAsLong(next, current); } else { From c8d0844cd72de02ec4554333cecc043540474a2a Mon Sep 17 00:00:00 2001 From: Victor Date: Wed, 22 Feb 2017 21:42:28 +0200 Subject: [PATCH 3/6] Replace primitive single element operator with an array --- .../java/com/annimon/stream/DoubleStream.java | 2 +- .../java/com/annimon/stream/IntStream.java | 2 +- .../java/com/annimon/stream/LongStream.java | 2 +- .../stream/operator/DoubleSingleElement.java | 25 ------------------- .../stream/operator/IntSingleElement.java | 25 ------------------- .../stream/operator/LongSingleElement.java | 25 ------------------- 6 files changed, 3 insertions(+), 78 deletions(-) delete mode 100644 stream/src/main/java/com/annimon/stream/operator/DoubleSingleElement.java delete mode 100644 stream/src/main/java/com/annimon/stream/operator/IntSingleElement.java delete mode 100644 stream/src/main/java/com/annimon/stream/operator/LongSingleElement.java diff --git a/stream/src/main/java/com/annimon/stream/DoubleStream.java b/stream/src/main/java/com/annimon/stream/DoubleStream.java index fd7aa809..b395dd49 100644 --- a/stream/src/main/java/com/annimon/stream/DoubleStream.java +++ b/stream/src/main/java/com/annimon/stream/DoubleStream.java @@ -71,7 +71,7 @@ public static DoubleStream of(final double... values) { * @return the new stream */ public static DoubleStream of(final double t) { - return new DoubleStream(new DoubleSingleElement(t)); + return new DoubleStream(new DoubleArray(new double[] { t })); } /** diff --git a/stream/src/main/java/com/annimon/stream/IntStream.java b/stream/src/main/java/com/annimon/stream/IntStream.java index ff98f9e9..699681b3 100644 --- a/stream/src/main/java/com/annimon/stream/IntStream.java +++ b/stream/src/main/java/com/annimon/stream/IntStream.java @@ -68,7 +68,7 @@ public static IntStream of(final int... values) { * @return the new stream */ public static IntStream of(final int t) { - return new IntStream(new IntSingleElement(t)); + return new IntStream(new IntArray(new int[] { t })); } /** diff --git a/stream/src/main/java/com/annimon/stream/LongStream.java b/stream/src/main/java/com/annimon/stream/LongStream.java index 6c04ba5b..b9ea658f 100644 --- a/stream/src/main/java/com/annimon/stream/LongStream.java +++ b/stream/src/main/java/com/annimon/stream/LongStream.java @@ -71,7 +71,7 @@ public static LongStream of(final long... values) { * @return the new stream */ public static LongStream of(final long t) { - return new LongStream(new LongSingleElement(t)); + return new LongStream(new LongArray(new long[] { t })); } /** diff --git a/stream/src/main/java/com/annimon/stream/operator/DoubleSingleElement.java b/stream/src/main/java/com/annimon/stream/operator/DoubleSingleElement.java deleted file mode 100644 index 5244d000..00000000 --- a/stream/src/main/java/com/annimon/stream/operator/DoubleSingleElement.java +++ /dev/null @@ -1,25 +0,0 @@ -package com.annimon.stream.operator; - -import com.annimon.stream.PrimitiveIterator; - -public class DoubleSingleElement extends PrimitiveIterator.OfDouble { - - private final double element; - private boolean hasNext; - - public DoubleSingleElement(double element) { - this.element = element; - hasNext = true; - } - - @Override - public boolean hasNext() { - return hasNext; - } - - @Override - public double nextDouble() { - hasNext = false; - return element; - } -} diff --git a/stream/src/main/java/com/annimon/stream/operator/IntSingleElement.java b/stream/src/main/java/com/annimon/stream/operator/IntSingleElement.java deleted file mode 100644 index 3b8b10ff..00000000 --- a/stream/src/main/java/com/annimon/stream/operator/IntSingleElement.java +++ /dev/null @@ -1,25 +0,0 @@ -package com.annimon.stream.operator; - -import com.annimon.stream.PrimitiveIterator; - -public class IntSingleElement extends PrimitiveIterator.OfInt { - - private final int element; - private boolean hasNext; - - public IntSingleElement(int element) { - this.element = element; - hasNext = true; - } - - @Override - public boolean hasNext() { - return hasNext; - } - - @Override - public int nextInt() { - hasNext = false; - return element; - } -} diff --git a/stream/src/main/java/com/annimon/stream/operator/LongSingleElement.java b/stream/src/main/java/com/annimon/stream/operator/LongSingleElement.java deleted file mode 100644 index f205abff..00000000 --- a/stream/src/main/java/com/annimon/stream/operator/LongSingleElement.java +++ /dev/null @@ -1,25 +0,0 @@ -package com.annimon.stream.operator; - -import com.annimon.stream.PrimitiveIterator; - -public class LongSingleElement extends PrimitiveIterator.OfLong { - - private final long element; - private boolean hasNext; - - public LongSingleElement(long element) { - this.element = element; - hasNext = true; - } - - @Override - public boolean hasNext() { - return hasNext; - } - - @Override - public long nextLong() { - hasNext = false; - return element; - } -} From 794f4a538851c804bea5e3211c7ec28ca201f13c Mon Sep 17 00:00:00 2001 From: Victor Date: Wed, 22 Feb 2017 22:25:41 +0200 Subject: [PATCH 4/6] Small fixes --- stream/src/main/java/com/annimon/stream/Collectors.java | 8 +++++--- stream/src/main/java/com/annimon/stream/LsaIterator.java | 1 + .../test/java/com/annimon/stream/RandomCompatTest.java | 1 - 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/stream/src/main/java/com/annimon/stream/Collectors.java b/stream/src/main/java/com/annimon/stream/Collectors.java index 9fdac5d7..99480ef6 100644 --- a/stream/src/main/java/com/annimon/stream/Collectors.java +++ b/stream/src/main/java/com/annimon/stream/Collectors.java @@ -117,7 +117,7 @@ public void accept(Set t, T u) { */ public static Collector> toMap( final Function keyMapper) { - return toMap(keyMapper, UnaryOperator.Util.identity(), Collectors.hashMapSupplier()); + return Collectors.toMap(keyMapper, UnaryOperator.Util.identity()); } /** @@ -133,7 +133,8 @@ public void accept(Set t, T u) { public static Collector> toMap( final Function keyMapper, final Function valueMapper) { - return toMap(keyMapper, valueMapper, Collectors.hashMapSupplier()); + return Collectors.>toMap(keyMapper, valueMapper, + Collectors.hashMapSupplier()); } /** @@ -693,7 +694,8 @@ public static Collector collectingAndThen( public static Collector> groupingBy( Function classifier, Collector downstream) { - return groupingBy(classifier, Collectors.hashMapSupplier(), downstream); + return Collectors.>groupingBy(classifier, + Collectors.hashMapSupplier(), downstream); } /** diff --git a/stream/src/main/java/com/annimon/stream/LsaIterator.java b/stream/src/main/java/com/annimon/stream/LsaIterator.java index c959f2a9..df1849e4 100644 --- a/stream/src/main/java/com/annimon/stream/LsaIterator.java +++ b/stream/src/main/java/com/annimon/stream/LsaIterator.java @@ -5,6 +5,7 @@ /** * Abstract iterator with implemented {@code remove} method. + * @param the type of the elements */ public abstract class LsaIterator implements Iterator { diff --git a/stream/src/test/java/com/annimon/stream/RandomCompatTest.java b/stream/src/test/java/com/annimon/stream/RandomCompatTest.java index 8162a60c..aa9d4bdc 100644 --- a/stream/src/test/java/com/annimon/stream/RandomCompatTest.java +++ b/stream/src/test/java/com/annimon/stream/RandomCompatTest.java @@ -213,7 +213,6 @@ public void accept(long value) { new RandomCompat().longs(Long.MAX_VALUE - 5, Long.MAX_VALUE).peek(new LongConsumer() { @Override public void accept(long value) { - System.out.println(value); if (value < Long.MAX_VALUE - 5 || value == Long.MAX_VALUE) fail(); } From 5d437beea9a2f9ee1391e01bfd0ba50a927c70d0 Mon Sep 17 00:00:00 2001 From: Victor Date: Wed, 22 Feb 2017 22:33:57 +0200 Subject: [PATCH 5/6] Reduce calls to first iterator hasNext method in ObjConcat --- .../java/com/annimon/stream/operator/ObjConcat.java | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/stream/src/main/java/com/annimon/stream/operator/ObjConcat.java b/stream/src/main/java/com/annimon/stream/operator/ObjConcat.java index 997b34ab..0692cb97 100644 --- a/stream/src/main/java/com/annimon/stream/operator/ObjConcat.java +++ b/stream/src/main/java/com/annimon/stream/operator/ObjConcat.java @@ -7,18 +7,23 @@ public class ObjConcat extends LsaExtIterator { private final Iterator iterator1; private final Iterator iterator2; + private boolean firstStreamIsCurrent; public ObjConcat(Iterator iterator1, Iterator iterator2) { this.iterator1 = iterator1; this.iterator2 = iterator2; + firstStreamIsCurrent = true; } @Override protected void nextIteration() { - if (iterator1.hasNext()) { - next = iterator1.next(); - hasNext = true; - return; + if (firstStreamIsCurrent) { + if (iterator1.hasNext()) { + next = iterator1.next(); + hasNext = true; + return; + } + firstStreamIsCurrent = false; } if (iterator2.hasNext()) { next = iterator2.next(); From 178c6cba028dc26aba4f11adcd1e03a5453f07ee Mon Sep 17 00:00:00 2001 From: Victor Date: Wed, 22 Feb 2017 23:08:41 +0200 Subject: [PATCH 6/6] Return an empty stream if passed array is empty --- .../src/main/java/com/annimon/stream/DoubleStream.java | 3 +++ stream/src/main/java/com/annimon/stream/IntStream.java | 3 +++ stream/src/main/java/com/annimon/stream/LongStream.java | 3 +++ stream/src/main/java/com/annimon/stream/Stream.java | 3 +++ .../test/java/com/annimon/stream/DoubleStreamTest.java | 7 +++++++ .../src/test/java/com/annimon/stream/IntStreamTest.java | 9 ++++++++- .../src/test/java/com/annimon/stream/LongStreamTest.java | 7 +++++++ stream/src/test/java/com/annimon/stream/StreamTest.java | 7 +++++++ 8 files changed, 41 insertions(+), 1 deletion(-) diff --git a/stream/src/main/java/com/annimon/stream/DoubleStream.java b/stream/src/main/java/com/annimon/stream/DoubleStream.java index b395dd49..5d4a2a0c 100644 --- a/stream/src/main/java/com/annimon/stream/DoubleStream.java +++ b/stream/src/main/java/com/annimon/stream/DoubleStream.java @@ -61,6 +61,9 @@ public static DoubleStream of(PrimitiveIterator.OfDouble iterator) { */ public static DoubleStream of(final double... values) { Objects.requireNonNull(values); + if (values.length == 0) { + return DoubleStream.empty(); + } return new DoubleStream(new DoubleArray(values)); } diff --git a/stream/src/main/java/com/annimon/stream/IntStream.java b/stream/src/main/java/com/annimon/stream/IntStream.java index 699681b3..50ddf1ad 100644 --- a/stream/src/main/java/com/annimon/stream/IntStream.java +++ b/stream/src/main/java/com/annimon/stream/IntStream.java @@ -58,6 +58,9 @@ public static IntStream of(PrimitiveIterator.OfInt iterator) { */ public static IntStream of(final int... values) { Objects.requireNonNull(values); + if (values.length == 0) { + return IntStream.empty(); + } return new IntStream(new IntArray(values)); } diff --git a/stream/src/main/java/com/annimon/stream/LongStream.java b/stream/src/main/java/com/annimon/stream/LongStream.java index b9ea658f..cee94e62 100644 --- a/stream/src/main/java/com/annimon/stream/LongStream.java +++ b/stream/src/main/java/com/annimon/stream/LongStream.java @@ -61,6 +61,9 @@ public static LongStream of(PrimitiveIterator.OfLong iterator) { */ public static LongStream of(final long... values) { Objects.requireNonNull(values); + if (values.length == 0) { + return LongStream.empty(); + } return new LongStream(new LongArray(values)); } diff --git a/stream/src/main/java/com/annimon/stream/Stream.java b/stream/src/main/java/com/annimon/stream/Stream.java index d5ff4177..3a281f6f 100644 --- a/stream/src/main/java/com/annimon/stream/Stream.java +++ b/stream/src/main/java/com/annimon/stream/Stream.java @@ -78,6 +78,9 @@ public static Stream of(Iterable iterable) { */ public static Stream of(final T... elements) { Objects.requireNonNull(elements); + if (elements.length == 0) { + return Stream.empty(); + } return new Stream(new ObjArray(elements)); } diff --git a/stream/src/test/java/com/annimon/stream/DoubleStreamTest.java b/stream/src/test/java/com/annimon/stream/DoubleStreamTest.java index cb3b0dfd..de7fb587 100644 --- a/stream/src/test/java/com/annimon/stream/DoubleStreamTest.java +++ b/stream/src/test/java/com/annimon/stream/DoubleStreamTest.java @@ -16,6 +16,7 @@ import java.util.NoSuchElementException; import org.junit.Test; import static com.annimon.stream.test.hamcrest.DoubleStreamMatcher.assertElements; +import static com.annimon.stream.test.hamcrest.DoubleStreamMatcher.assertIsEmpty; import static com.annimon.stream.test.hamcrest.DoubleStreamMatcher.elements; import static com.annimon.stream.test.hamcrest.DoubleStreamMatcher.isEmpty; import static com.annimon.stream.test.hamcrest.OptionalDoubleMatcher.hasValue; @@ -80,6 +81,12 @@ public void testStreamOfDoublesNull() { DoubleStream.of((double[]) null); } + @Test + public void testStreamOfEmptyArray() { + DoubleStream.of(new double[0]) + .custom(assertIsEmpty()); + } + @Test public void testStreamOfDouble() { assertThat(DoubleStream.of(1.234), elements(arrayContaining(1.234))); diff --git a/stream/src/test/java/com/annimon/stream/IntStreamTest.java b/stream/src/test/java/com/annimon/stream/IntStreamTest.java index 4b0833fa..bc44a95f 100644 --- a/stream/src/test/java/com/annimon/stream/IntStreamTest.java +++ b/stream/src/test/java/com/annimon/stream/IntStreamTest.java @@ -20,6 +20,7 @@ import org.hamcrest.Matchers; import org.junit.Test; import static com.annimon.stream.test.hamcrest.IntStreamMatcher.assertElements; +import static com.annimon.stream.test.hamcrest.IntStreamMatcher.assertIsEmpty; import static com.annimon.stream.test.hamcrest.OptionalIntMatcher.hasValue; import static com.annimon.stream.test.hamcrest.StreamMatcher.elements; import static org.hamcrest.CoreMatchers.is; @@ -74,7 +75,7 @@ public void testStreamOfInts() { assertTrue(IntStream.of(data1).count() == 5); assertTrue(IntStream.of(data2).findFirst().getAsInt() == 42); - assertTrue(!IntStream.of(data3).findFirst().isPresent()); + assertFalse(IntStream.of(data3).findFirst().isPresent()); } @Test(expected = NullPointerException.class) @@ -82,6 +83,12 @@ public void testStreamOfIntsNull() { IntStream.of((int[]) null); } + @Test + public void testStreamOfEmptyArray() { + IntStream.of(new int[0]) + .custom(assertIsEmpty()); + } + @Test public void testStreamOfInt() { assertTrue(IntStream.of(42).count() == 1); diff --git a/stream/src/test/java/com/annimon/stream/LongStreamTest.java b/stream/src/test/java/com/annimon/stream/LongStreamTest.java index 44ac83e9..c667a878 100644 --- a/stream/src/test/java/com/annimon/stream/LongStreamTest.java +++ b/stream/src/test/java/com/annimon/stream/LongStreamTest.java @@ -17,6 +17,7 @@ import java.util.NoSuchElementException; import org.junit.Test; import static com.annimon.stream.test.hamcrest.LongStreamMatcher.assertElements; +import static com.annimon.stream.test.hamcrest.LongStreamMatcher.assertIsEmpty; import static com.annimon.stream.test.hamcrest.LongStreamMatcher.elements; import static com.annimon.stream.test.hamcrest.LongStreamMatcher.isEmpty; import static com.annimon.stream.test.hamcrest.OptionalLongMatcher.hasValue; @@ -75,6 +76,12 @@ public void testStreamOfLongsNull() { LongStream.of((long[]) null); } + @Test + public void testStreamOfEmptyArray() { + LongStream.of(new long[0]) + .custom(assertIsEmpty()); + } + @Test public void testStreamOfLong() { assertThat(LongStream.of(1234), elements(arrayContaining(1234L))); diff --git a/stream/src/test/java/com/annimon/stream/StreamTest.java b/stream/src/test/java/com/annimon/stream/StreamTest.java index 05e144c6..2898a8e8 100644 --- a/stream/src/test/java/com/annimon/stream/StreamTest.java +++ b/stream/src/test/java/com/annimon/stream/StreamTest.java @@ -15,6 +15,7 @@ import com.annimon.stream.function.UnaryOperator; import com.annimon.stream.test.hamcrest.DoubleStreamMatcher; import com.annimon.stream.test.hamcrest.OptionalMatcher; +import com.annimon.stream.test.hamcrest.StreamMatcher; import java.math.BigInteger; import java.util.ArrayList; import java.util.Arrays; @@ -91,6 +92,12 @@ public void testStreamOfMapNull() { Stream.of((Map)null); } + @Test + public void testStreamOfEmptyArray() { + Stream.of(new String[0]) + .custom(StreamMatcher.assertIsEmpty()); + } + @Test public void testStreamOfIterator() { final PrintConsumer consumer = new PrintConsumer();