From ac2e5d6fa07732c2a0216d90ddc58a666ecb261b Mon Sep 17 00:00:00 2001 From: Ivan Hetman Date: Wed, 5 Jul 2023 20:40:08 +0300 Subject: [PATCH] classlib: added Stream iterate method (#721) --- .../classlib/java/util/stream/TDoubleStream.java | 4 ++++ .../teavm/classlib/java/util/stream/TIntStream.java | 4 ++++ .../teavm/classlib/java/util/stream/TLongStream.java | 4 ++++ .../org/teavm/classlib/java/util/stream/TStream.java | 4 ++++ .../util/stream/doubleimpl/TIterateDoubleStream.java | 9 +++++++++ .../java/util/stream/impl/TIterateStream.java | 9 +++++++++ .../java/util/stream/intimpl/TIterateIntStream.java | 9 +++++++++ .../java/util/stream/longimpl/TIterateLongStream.java | 9 +++++++++ .../teavm/classlib/java/util/stream/StreamTest.java | 11 +++++++++++ 9 files changed, 63 insertions(+) diff --git a/classlib/src/main/java/org/teavm/classlib/java/util/stream/TDoubleStream.java b/classlib/src/main/java/org/teavm/classlib/java/util/stream/TDoubleStream.java index 0ee323c9b..9b5819786 100644 --- a/classlib/src/main/java/org/teavm/classlib/java/util/stream/TDoubleStream.java +++ b/classlib/src/main/java/org/teavm/classlib/java/util/stream/TDoubleStream.java @@ -145,6 +145,10 @@ public interface TDoubleStream extends TBaseStream { return new TIterateDoubleStream(seed, f); } + static TDoubleStream iterate(double seed, DoublePredicate pr, DoubleUnaryOperator f) { + return new TIterateDoubleStream(seed, pr, f); + } + static TDoubleStream generate(DoubleSupplier s) { return new TGenerateDoubleStream(s); } diff --git a/classlib/src/main/java/org/teavm/classlib/java/util/stream/TIntStream.java b/classlib/src/main/java/org/teavm/classlib/java/util/stream/TIntStream.java index 9c6ac057d..841e07d56 100644 --- a/classlib/src/main/java/org/teavm/classlib/java/util/stream/TIntStream.java +++ b/classlib/src/main/java/org/teavm/classlib/java/util/stream/TIntStream.java @@ -151,6 +151,10 @@ public interface TIntStream extends TBaseStream { return new TIterateIntStream(seed, f); } + static TIntStream iterate(int seed, IntPredicate pr, IntUnaryOperator f) { + return new TIterateIntStream(seed, pr, f); + } + static TIntStream generate(IntSupplier s) { return new TGenerateIntStream(s); } diff --git a/classlib/src/main/java/org/teavm/classlib/java/util/stream/TLongStream.java b/classlib/src/main/java/org/teavm/classlib/java/util/stream/TLongStream.java index 58167b433..88c48f06d 100644 --- a/classlib/src/main/java/org/teavm/classlib/java/util/stream/TLongStream.java +++ b/classlib/src/main/java/org/teavm/classlib/java/util/stream/TLongStream.java @@ -149,6 +149,10 @@ public interface TLongStream extends TBaseStream { return new TIterateLongStream(seed, f); } + static TLongStream iterate(long seed, LongPredicate pr, LongUnaryOperator f) { + return new TIterateLongStream(seed, pr, f); + } + static TLongStream generate(LongSupplier s) { return new TGenerateLongStream(s); } diff --git a/classlib/src/main/java/org/teavm/classlib/java/util/stream/TStream.java b/classlib/src/main/java/org/teavm/classlib/java/util/stream/TStream.java index 81ef57825..c3a9d150a 100644 --- a/classlib/src/main/java/org/teavm/classlib/java/util/stream/TStream.java +++ b/classlib/src/main/java/org/teavm/classlib/java/util/stream/TStream.java @@ -176,6 +176,10 @@ public interface TStream extends TBaseStream> { return new TIterateStream<>(seed, f); } + static TStream iterate(T seed, Predicate pr, UnaryOperator f) { + return new TIterateStream<>(seed, pr, f); + } + static TStream generate(Supplier s) { return new TGenerateStream<>(s); } diff --git a/classlib/src/main/java/org/teavm/classlib/java/util/stream/doubleimpl/TIterateDoubleStream.java b/classlib/src/main/java/org/teavm/classlib/java/util/stream/doubleimpl/TIterateDoubleStream.java index 024049e39..2adc343de 100644 --- a/classlib/src/main/java/org/teavm/classlib/java/util/stream/doubleimpl/TIterateDoubleStream.java +++ b/classlib/src/main/java/org/teavm/classlib/java/util/stream/doubleimpl/TIterateDoubleStream.java @@ -20,16 +20,25 @@ import java.util.function.DoubleUnaryOperator; public class TIterateDoubleStream extends TSimpleDoubleStreamImpl { private double value; + private DoublePredicate pr; private DoubleUnaryOperator f; public TIterateDoubleStream(double value, DoubleUnaryOperator f) { + this(value, t -> true, f); + } + + public TIterateDoubleStream(double value, DoublePredicate pr, DoubleUnaryOperator f) { this.value = value; + this.pr = pr; this.f = f; } @Override public boolean next(DoublePredicate consumer) { while (true) { + if (!pr.test(value)) { + return false; + } double valueToReport = value; value = f.applyAsDouble(value); if (!consumer.test(valueToReport)) { diff --git a/classlib/src/main/java/org/teavm/classlib/java/util/stream/impl/TIterateStream.java b/classlib/src/main/java/org/teavm/classlib/java/util/stream/impl/TIterateStream.java index 1522cef78..e230f1d44 100644 --- a/classlib/src/main/java/org/teavm/classlib/java/util/stream/impl/TIterateStream.java +++ b/classlib/src/main/java/org/teavm/classlib/java/util/stream/impl/TIterateStream.java @@ -20,16 +20,25 @@ import java.util.function.UnaryOperator; public class TIterateStream extends TSimpleStreamImpl { private T value; + private Predicate pr; private UnaryOperator f; public TIterateStream(T value, UnaryOperator f) { + this(value, t -> true, f); + } + + public TIterateStream(T value, Predicate pr, UnaryOperator f) { this.value = value; + this.pr = pr; this.f = f; } @Override public boolean next(Predicate consumer) { while (true) { + if (!pr.test(value)) { + return false; + } T valueToReport = value; value = f.apply(value); if (!consumer.test(valueToReport)) { diff --git a/classlib/src/main/java/org/teavm/classlib/java/util/stream/intimpl/TIterateIntStream.java b/classlib/src/main/java/org/teavm/classlib/java/util/stream/intimpl/TIterateIntStream.java index 5d37d0093..a8d379d4a 100644 --- a/classlib/src/main/java/org/teavm/classlib/java/util/stream/intimpl/TIterateIntStream.java +++ b/classlib/src/main/java/org/teavm/classlib/java/util/stream/intimpl/TIterateIntStream.java @@ -20,16 +20,25 @@ import java.util.function.IntUnaryOperator; public class TIterateIntStream extends TSimpleIntStreamImpl { private int value; + private IntPredicate pr; private IntUnaryOperator f; public TIterateIntStream(int value, IntUnaryOperator f) { + this(value, t -> true, f); + } + + public TIterateIntStream(int value, IntPredicate pr, IntUnaryOperator f) { this.value = value; + this.pr = pr; this.f = f; } @Override public boolean next(IntPredicate consumer) { while (true) { + if (!pr.test(value)) { + return false; + } int valueToReport = value; value = f.applyAsInt(value); if (!consumer.test(valueToReport)) { diff --git a/classlib/src/main/java/org/teavm/classlib/java/util/stream/longimpl/TIterateLongStream.java b/classlib/src/main/java/org/teavm/classlib/java/util/stream/longimpl/TIterateLongStream.java index d7c2e58f6..b418661f1 100644 --- a/classlib/src/main/java/org/teavm/classlib/java/util/stream/longimpl/TIterateLongStream.java +++ b/classlib/src/main/java/org/teavm/classlib/java/util/stream/longimpl/TIterateLongStream.java @@ -20,16 +20,25 @@ import java.util.function.LongUnaryOperator; public class TIterateLongStream extends TSimpleLongStreamImpl { private long value; + private LongPredicate pr; private LongUnaryOperator f; public TIterateLongStream(long value, LongUnaryOperator f) { + this(value, t -> true, f); + } + + public TIterateLongStream(long value, LongPredicate pr, LongUnaryOperator f) { this.value = value; + this.pr = pr; this.f = f; } @Override public boolean next(LongPredicate consumer) { while (true) { + if (!pr.test(value)) { + return false; + } long valueToReport = value; value = f.applyAsLong(value); if (!consumer.test(valueToReport)) { diff --git a/tests/src/test/java/org/teavm/classlib/java/util/stream/StreamTest.java b/tests/src/test/java/org/teavm/classlib/java/util/stream/StreamTest.java index b45f71b9d..09ac579d7 100644 --- a/tests/src/test/java/org/teavm/classlib/java/util/stream/StreamTest.java +++ b/tests/src/test/java/org/teavm/classlib/java/util/stream/StreamTest.java @@ -457,4 +457,15 @@ public class StreamTest { }).toArray(); assertArrayEquals(new int[] {0, 2}, mappedInt); } + + @Test + public void iterateWorks() { + for (int c = 0; c < 10; c++) { + int cnt = c; + int sum = Stream.iterate(1, i -> i < 2 * cnt, i -> i + 2).mapToInt(Integer::intValue).sum(); + assertEquals(cnt * cnt, sum); + } + List repetitions = Stream.iterate("", s -> s.length() < 5, s -> s + "a").toList(); + assertEquals(List.of("", "a", "aa", "aaa", "aaaa"), repetitions); + } } \ No newline at end of file