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 95ce1c0fe..0ee323c9b 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 @@ -41,7 +41,8 @@ import org.teavm.classlib.java.util.stream.doubleimpl.TSingleDoubleStreamImpl; import org.teavm.classlib.java.util.stream.doubleimpl.TSpecializedConcatDoubleStream; public interface TDoubleStream extends TBaseStream { - interface Builder { + interface Builder extends DoubleConsumer { + @Override void accept(double t); default Builder add(double t) { @@ -64,6 +65,14 @@ public interface TDoubleStream extends TBaseStream { TDoubleStream flatMap(DoubleFunction mapper); + default TDoubleStream mapMulti(DoubleMapMultiConsumer mapper) { + return flatMap(e -> { + Builder builder = builder(); + mapper.accept(e, builder); + return builder.build(); + }); + } + TDoubleStream distinct(); TDoubleStream sorted(); @@ -147,4 +156,9 @@ public interface TDoubleStream extends TBaseStream { return new TGenericConcatDoubleStream(a, b); } } + + @FunctionalInterface + interface DoubleMapMultiConsumer { + void accept(double value, DoubleConsumer dc); + } } 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 7796d6575..9c6ac057d 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 @@ -43,7 +43,8 @@ import org.teavm.classlib.java.util.stream.intimpl.TSingleIntStreamImpl; import org.teavm.classlib.java.util.stream.intimpl.TSpecializedConcatIntStream; public interface TIntStream extends TBaseStream { - interface Builder { + interface Builder extends IntConsumer { + @Override void accept(int t); default Builder add(int t) { @@ -66,6 +67,14 @@ public interface TIntStream extends TBaseStream { TIntStream flatMap(IntFunction mapper); + default TIntStream mapMulti(IntMapMultiConsumer mapper) { + return flatMap(e -> { + Builder builder = builder(); + mapper.accept(e, builder); + return builder.build(); + }); + } + TIntStream distinct(); TIntStream sorted(); @@ -161,4 +170,9 @@ public interface TIntStream extends TBaseStream { return new TGenericConcatIntStream(a, b); } } + + @FunctionalInterface + interface IntMapMultiConsumer { + void accept(int value, IntConsumer ic); + } } 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 6db9ce723..58167b433 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 @@ -43,7 +43,8 @@ import org.teavm.classlib.java.util.stream.longimpl.TSingleLongStreamImpl; import org.teavm.classlib.java.util.stream.longimpl.TSpecializedConcatLongStream; public interface TLongStream extends TBaseStream { - interface Builder { + interface Builder extends LongConsumer { + @Override void accept(long t); default Builder add(long t) { @@ -66,6 +67,14 @@ public interface TLongStream extends TBaseStream { TLongStream flatMap(LongFunction mapper); + default TLongStream mapMulti(LongMapMultiConsumer mapper) { + return flatMap(e -> { + Builder builder = builder(); + mapper.accept(e, builder); + return builder.build(); + }); + } + TLongStream distinct(); TLongStream sorted(); @@ -159,4 +168,9 @@ public interface TLongStream extends TBaseStream { return new TGenericConcatLongStream(a, b); } } + + @FunctionalInterface + interface LongMapMultiConsumer { + void accept(long value, LongConsumer lc); + } } 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 0e32bb9f6..81ef57825 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 @@ -22,8 +22,11 @@ import java.util.function.BiConsumer; import java.util.function.BiFunction; import java.util.function.BinaryOperator; import java.util.function.Consumer; +import java.util.function.DoubleConsumer; import java.util.function.Function; +import java.util.function.IntConsumer; import java.util.function.IntFunction; +import java.util.function.LongConsumer; import java.util.function.Predicate; import java.util.function.Supplier; import java.util.function.ToDoubleFunction; @@ -42,7 +45,8 @@ import org.teavm.classlib.java.util.stream.impl.TSpecializedConcatStream; import org.teavm.classlib.java.util.stream.impl.TStreamBuilder; public interface TStream extends TBaseStream> { - interface Builder { + interface Builder extends Consumer { + @Override void accept(T t); default Builder add(T t) { @@ -71,6 +75,38 @@ public interface TStream extends TBaseStream> { TDoubleStream flatMapToDouble(Function mapper); + default TStream mapMulti(BiConsumer> mapper) { + return flatMap(e -> { + TStream.Builder builder = builder(); + mapper.accept(e, builder); + return builder.build(); + }); + } + + default TIntStream mapMultiToInt(BiConsumer mapper) { + return flatMapToInt(e -> { + TIntStream.Builder builder = TIntStream.builder(); + mapper.accept(e, builder); + return builder.build(); + }); + } + + default TLongStream mapMultiToLong(BiConsumer mapper) { + return flatMapToLong(e -> { + TLongStream.Builder builder = TLongStream.builder(); + mapper.accept(e, builder); + return builder.build(); + }); + } + + default TDoubleStream mapMultiToDouble(BiConsumer mapper) { + return flatMapToDouble(e -> { + TDoubleStream.Builder builder = TDoubleStream.builder(); + mapper.accept(e, builder); + return builder.build(); + }); + } + TStream distinct(); TStream sorted(); diff --git a/tests/src/test/java/org/teavm/classlib/java/util/stream/IntStreamTest.java b/tests/src/test/java/org/teavm/classlib/java/util/stream/IntStreamTest.java index f1835d25e..1fbc7a668 100644 --- a/tests/src/test/java/org/teavm/classlib/java/util/stream/IntStreamTest.java +++ b/tests/src/test/java/org/teavm/classlib/java/util/stream/IntStreamTest.java @@ -344,4 +344,14 @@ public class IntStreamTest { assertEquals(Integer.MIN_VALUE, empty.getMax()); assertEquals(0L, empty.getSum()); } + + @Test + public void mapMultiWorks() { + int[] mapped = IntStream.rangeClosed(0, 3).mapMulti((cnt, cons) -> { + for (int i = 0; i < cnt; i++) { + cons.accept(cnt); + } + }).toArray(); + assertArrayEquals(new int[] {1, 2, 2, 3, 3, 3}, mapped); + } } 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 8b65eb717..b45f71b9d 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 @@ -440,4 +440,21 @@ public class StreamTest { // ok } } + + @Test + public void mapMultiWorks() { + String[] mapped = Stream.of(" a ", "", " bb ").mapMulti((s, cons) -> { + String trim = s.trim(); + if (!trim.isEmpty()) { + cons.accept(trim); + } + }).toArray(String[]::new); + assertArrayEquals(new String[] {"a", "bb"}, mapped); + int[] mappedInt = Stream.of("a", "", "bb").mapMultiToInt((s, cons) -> { + if (s.length() % 2 == 0) { + cons.accept(s.length()); + } + }).toArray(); + assertArrayEquals(new int[] {0, 2}, mappedInt); + } } \ No newline at end of file