OpenJDK / lambda / lambda / jdk
changeset 8077:4a8fddc0b945
Remove FlatMapper and relevant flatMap variants; migrate to flatMap(e -> stream)
line wrap: on
line diff
--- a/src/share/classes/java/util/stream/DelegatingStream.java Tue Apr 09 13:58:43 2013 -0400 +++ b/src/share/classes/java/util/stream/DelegatingStream.java Tue Apr 09 15:36:39 2013 -0400 @@ -113,22 +113,17 @@ } @Override - public <R> Stream<R> flatMap(FlatMapper<? super T, R> mapper) { - return delegate.flatMap(mapper); - } - - @Override - public IntStream flatMapToInt(FlatMapper.ToInt<? super T> mapper) { + public IntStream flatMapToInt(Function<? super T, ? extends IntStream> mapper) { return delegate.flatMapToInt(mapper); } @Override - public LongStream flatMapToLong(FlatMapper.ToLong<? super T> mapper) { + public LongStream flatMapToLong(Function<? super T, ? extends LongStream> mapper) { return delegate.flatMapToLong(mapper); } @Override - public DoubleStream flatMapToDouble(FlatMapper.ToDouble<? super T> mapper) { + public DoubleStream flatMapToDouble(Function<? super T, ? extends DoubleStream> mapper) { return delegate.flatMapToDouble(mapper); }
--- a/src/share/classes/java/util/stream/DoublePipeline.java Tue Apr 09 13:58:43 2013 -0400 +++ b/src/share/classes/java/util/stream/DoublePipeline.java Tue Apr 09 15:36:39 2013 -0400 @@ -243,19 +243,16 @@ @Override public final DoubleStream flatMap(DoubleFunction<? extends DoubleStream> mapper) { - return flatMap((double i, DoubleConsumer sink) -> mapper.apply(i).sequential().forEach(sink)); - } - - @Override - public final DoubleStream flatMap(FlatMapper.OfDoubleToDouble mapper) { - Objects.requireNonNull(mapper); return new StatelessOp<Double>(this, StreamShape.DOUBLE_VALUE, - StreamOpFlag.NOT_SORTED | StreamOpFlag.NOT_DISTINCT | StreamOpFlag.NOT_SIZED) { + StreamOpFlag.NOT_SORTED | StreamOpFlag.NOT_DISTINCT | StreamOpFlag.NOT_SIZED) { @Override Sink<Double> opWrapSink(int flags, Sink<Double> sink) { return new Sink.ChainedDouble(sink) { public void accept(double t) { - mapper.flattenInto(t, (Sink.OfDouble) downstream); + // We can do better that this too; optimize for depth=0 case and just grab spliterator and forEach it + DoubleStream result = mapper.apply(t); + if (result != null) + result.sequential().forEach(i -> downstream.accept(i)); } }; }
--- a/src/share/classes/java/util/stream/DoubleStream.java Tue Apr 09 13:58:43 2013 -0400 +++ b/src/share/classes/java/util/stream/DoubleStream.java Tue Apr 09 15:36:39 2013 -0400 @@ -150,10 +150,6 @@ * <p>This is an <a href="package-summary.html#StreamOps">intermediate * operation</a>. * - * @implNote - * <p>This implementation is likely to be less efficient than the other - * form of {@link #flatMap(FlatMapper.OfDoubleToDouble)}, and is provided for - * convenience. * @param mapper A <a href="package-summary.html#NonInterference"> * non-interfering, stateless</a> function to be applied to * each element which produces a stream of new @@ -164,26 +160,6 @@ DoubleStream flatMap(DoubleFunction<? extends DoubleStream> mapper); /** - * Produces a stream consisting of the results of replacing each - * element of this stream with zero or more transformed values, according - * to the transformation encoded in the provided {@code FlatMapper.OfDoubleToDouble}. - * - * <p>This is an <a href="package-summary.html#StreamOps">intermediate - * operation</a>. - * @implNote - * This form of {@code flatMap} is usually less convenient to use than the - * {@link #flatMap(DoubleFunction)} form, but is often considerably more - * efficient because it eliminates the overhead of stream construction - * and traversal. - * @param mapper A <a href="package-summary.html#NonInterference"> - * non-interfering, stateless</a> {@code FlatMapper.OfDoubleToDouble} - * that transforms each element into zero or more resulting - * values - * @return the new stream - */ - DoubleStream flatMap(FlatMapper.OfDoubleToDouble mapper); - - /** * Produces a stream consisting of the distinct elements of this stream. * * <p>This is a <a href="package-summary.html#StreamOps">stateful
--- a/src/share/classes/java/util/stream/FlatMapper.java Tue Apr 09 13:58:43 2013 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,156 +0,0 @@ -/* - * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package java.util.stream; - -import java.util.function.Consumer; -import java.util.function.DoubleConsumer; -import java.util.function.IntConsumer; -import java.util.function.LongConsumer; - -/** - * An operation that maps an element of type {@code T} to zero or more elements - * of type {@code U}. - * - * <p>These functional interfaces are used to describe the arguments of - * {@link Stream#flatMap(FlatMapper)} and related methods. - * - * @apiNote - * Example: @@@ - * <pre>{@code - * }</pre> - * - * <p>Rather than representing the result as a {@code Collection} or array, the - * results are emitted directly into a {@link Consumer}, to avoid the overhead - * of creating and iterating the (often empty or small) intermediate data - * structure. - * @see Stream#flatMap(FlatMapper) - * @since 1.8 - */ -@FunctionalInterface -public interface FlatMapper<T, U> { - /** - * Accept an input element and emit zero or more output elements into the - * provided {@code Consumer} - * @param element The input element - * @param sink A {@code Consumer} to receive the output elements - */ - void flattenInto(T element, Consumer<U> sink); - - /** - * An operation that maps an element of type {@code T} to zero or more - * elements of type {@code int}. - * This is the int-bearing specialization of {@code FlatMapper}. - */ - @FunctionalInterface - interface ToInt<T> { - /** - * Accept an input element and emit zero or more output elements into - * the provided {@code IntConsumer} - * @param element The input element - * @param sink A {@code IntConsumer} to receive the output elements - */ - void flattenInto(T element, IntConsumer sink); - } - - /** - * An operation that maps an element of type {@code T} to zero or more - * elements of type {@code long}. - * This is the long-bearing specialization of {@code FlatMapper}. - */ - @FunctionalInterface - interface ToLong<T> { - /** - * Accept an input element and emit zero or more output elements into - * the provided {@code LongConsumer} - * @param element The input element - * @param sink A {@code LongConsumer} to receive the output elements - */ - void flattenInto(T element, LongConsumer sink); - } - - /** - * An operation that maps an element of type {@code T} to zero or more - * elements of type {@code double}. - * This is the double-bearing specialization of {@code FlatMapper}. - */ - @FunctionalInterface - interface ToDouble<T> { - /** - * Accept an input element and emit zero or more output elements into - * the provided {@code DoubleConsumer} - * @param element The input element - * @param sink A {@code DoubleConsumer} to receive the output elements - */ - void flattenInto(T element, DoubleConsumer sink); - } - - /** - * An operation that maps an element of type {@code int} to zero or more - * elements of type {@code int}. - * This is the int-to-int specialization of {@code FlatMapper}. - */ - @FunctionalInterface - interface OfIntToInt { - /** - * Accept an input element and emit zero or more output elements into - * the provided {@code IntConsumer} - * @param element The input element - * @param sink A {@code IntConsumer} to receive the output elements - */ - void flattenInto(int element, IntConsumer sink); - } - - /** - * An operation that maps an element of type {@code long} to zero or more - * elements of type {@code long}. - * This is the long-to-long specialization of {@code FlatMapper}. - */ - @FunctionalInterface - interface OfLongToLong { - /** - * Accept an input element and emit zero or more output elements into - * the provided {@code LongConsumer} - * @param element The input element - * @param sink A {@code LongConsumer} to receive the output elements - */ - void flattenInto(long element, LongConsumer sink); - } - - /** - * An operation that maps an element of type {@code double} to zero or more - * elements of type {@code double}. - * This is the double-to-double specialization of {@code FlatMapper}. - */ - @FunctionalInterface - interface OfDoubleToDouble { - /** - * Accept an input element and emit zero or more output elements into - * the provided {@code DoubleConsumer} - * @param element The input element - * @param sink A {@code DoubleConsumer} to receive the output elements - */ - void flattenInto(double element, DoubleConsumer sink); - } -}
--- a/src/share/classes/java/util/stream/IntPipeline.java Tue Apr 09 13:58:43 2013 -0400 +++ b/src/share/classes/java/util/stream/IntPipeline.java Tue Apr 09 15:36:39 2013 -0400 @@ -271,19 +271,16 @@ @Override public final IntStream flatMap(IntFunction<? extends IntStream> mapper) { - return flatMap((int i, IntConsumer sink) -> mapper.apply(i).sequential().forEach(sink)); - } - - @Override - public final IntStream flatMap(FlatMapper.OfIntToInt mapper) { - Objects.requireNonNull(mapper); return new StatelessOp<Integer>(this, StreamShape.INT_VALUE, StreamOpFlag.NOT_SORTED | StreamOpFlag.NOT_DISTINCT | StreamOpFlag.NOT_SIZED) { @Override Sink<Integer> opWrapSink(int flags, Sink<Integer> sink) { return new Sink.ChainedInt(sink) { public void accept(int t) { - mapper.flattenInto(t, (Sink.OfInt) downstream); + // We can do better that this too; optimize for depth=0 case and just grab spliterator and forEach it + IntStream result = mapper.apply(t); + if (result != null) + result.sequential().forEach(i -> downstream.accept(i)); } }; }
--- a/src/share/classes/java/util/stream/IntStream.java Tue Apr 09 13:58:43 2013 -0400 +++ b/src/share/classes/java/util/stream/IntStream.java Tue Apr 09 15:36:39 2013 -0400 @@ -151,10 +151,6 @@ * <p>This is an <a href="package-summary.html#StreamOps">intermediate * operation</a>. * - * @implNote - * <p>This implementation is likely to be less efficient than the other - * form of {@link #flatMap(FlatMapper.OfIntToInt)}, and is provided for - * convenience. * @param mapper A <a href="package-summary.html#NonInterference"> * non-interfering, stateless</a> function to be applied to * each element which produces an {@code IntStream} of new @@ -165,26 +161,6 @@ IntStream flatMap(IntFunction<? extends IntStream> mapper); /** - * Produces a stream consisting of the results of replacing each - * element of this stream with zero or more transformed values, according - * to the transformation encoded in the provided {@code FlatMapper.OfIntToInt}. - * - * <p>This is an <a href="package-summary.html#StreamOps">intermediate - * operation</a>. - * @implNote - * This form of {@code flatMap} is usually less convenient to use than the - * {@link #flatMap(IntFunction)} form, but is often considerably more - * efficient because it eliminates the overhead of stream construction - * and traversal. - * @param mapper A <a href="package-summary.html#NonInterference"> - * non-interfering, stateless</a> {@code FlatMapper.OfIntToInt} - * that transforms each element into zero or more resulting - * values - * @return the new stream - */ - IntStream flatMap(FlatMapper.OfIntToInt mapper); - - /** * Produces a stream consisting of the distinct elements of this stream. * * <p>This is a <a href="package-summary.html#StreamOps">stateful
--- a/src/share/classes/java/util/stream/LongPipeline.java Tue Apr 09 13:58:43 2013 -0400 +++ b/src/share/classes/java/util/stream/LongPipeline.java Tue Apr 09 15:36:39 2013 -0400 @@ -255,19 +255,16 @@ @Override public final LongStream flatMap(LongFunction<? extends LongStream> mapper) { - return flatMap((long i, LongConsumer sink) -> mapper.apply(i).sequential().forEach(sink)); - } - - @Override - public final LongStream flatMap(FlatMapper.OfLongToLong mapper) { - Objects.requireNonNull(mapper); return new StatelessOp<Long>(this, StreamShape.LONG_VALUE, StreamOpFlag.NOT_SORTED | StreamOpFlag.NOT_DISTINCT | StreamOpFlag.NOT_SIZED) { @Override Sink<Long> opWrapSink(int flags, Sink<Long> sink) { return new Sink.ChainedLong(sink) { public void accept(long t) { - mapper.flattenInto(t, (Sink.OfLong) downstream); + // We can do better that this too; optimize for depth=0 case and just grab spliterator and forEach it + LongStream result = mapper.apply(t); + if (result != null) + result.sequential().forEach(i -> downstream.accept(i)); } }; }
--- a/src/share/classes/java/util/stream/LongStream.java Tue Apr 09 13:58:43 2013 -0400 +++ b/src/share/classes/java/util/stream/LongStream.java Tue Apr 09 15:36:39 2013 -0400 @@ -151,10 +151,6 @@ * <p>This is an <a href="package-summary.html#StreamOps">intermediate * operation</a>. * - * @implNote - * <p>This implementation is likely to be less efficient than the other - * form of {@link #flatMap(FlatMapper.OfLongToLong)}, and is provided for - * convenience. * @param mapper A <a href="package-summary.html#NonInterference"> * non-interfering, stateless</a> function to be applied to * each element which produces an stream of new @@ -165,26 +161,6 @@ LongStream flatMap(LongFunction<? extends LongStream> mapper); /** - * Produces a stream consisting of the results of replacing each - * element of this stream with zero or more transformed values, according - * to the transformation encoded in the provided {@code FlatMapper.OfLongToLong}. - * - * <p>This is an <a href="package-summary.html#StreamOps">intermediate - * operation</a>. - * @implNote - * This form of {@code flatMap} is usually less convenient to use than the - * {@link #flatMap(LongFunction)} form, but is often considerably more - * efficient because it eliminates the overhead of stream construction - * and traversal. - * @param mapper A <a href="package-summary.html#NonInterference"> - * non-interfering, stateless</a> {@code FlatMapper.OfLongToLong} - * that transforms each element into zero or more resulting - * values - * @return the new stream - */ - LongStream flatMap(FlatMapper.OfLongToLong mapper); - - /** * Produces a stream consisting of the distinct elements of this stream. * * <p>This is a <a href="package-summary.html#StreamOps">stateful
--- a/src/share/classes/java/util/stream/ReferencePipeline.java Tue Apr 09 13:58:43 2013 -0400 +++ b/src/share/classes/java/util/stream/ReferencePipeline.java Tue Apr 09 15:36:39 2013 -0400 @@ -35,8 +35,11 @@ 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; @@ -242,19 +245,16 @@ public final <R> Stream<R> flatMap(Function<? super U, ? extends Stream<? extends R>> mapper) { Objects.requireNonNull(mapper); // We can do better than this, by polling cancellationRequested when stream is infinite - return flatMap((U u, Consumer<R> sink) -> mapper.apply(u).sequential().forEach(sink)); - } - - @Override - public final <R> Stream<R> flatMap(FlatMapper<? super U, R> mapper) { - Objects.requireNonNull(mapper); return new StatelessOp<U, R>(this, StreamShape.REFERENCE, StreamOpFlag.NOT_SORTED | StreamOpFlag.NOT_DISTINCT | StreamOpFlag.NOT_SIZED) { @Override Sink<U> opWrapSink(int flags, Sink<R> sink) { return new Sink.ChainedReference<U>(sink) { public void accept(U u) { - mapper.flattenInto(u, downstream); + // We can do better that this too; optimize for depth=0 case and just grab spliterator and forEach it + Stream<? extends R> result = mapper.apply(u); + if (result != null) + result.sequential().forEach(downstream); } }; } @@ -262,15 +262,20 @@ } @Override - public final IntStream flatMapToInt(FlatMapper.ToInt<? super U> mapper) { + public final IntStream flatMapToInt(Function<? super U, ? extends IntStream> mapper) { Objects.requireNonNull(mapper); + // We can do better than this, by polling cancellationRequested when stream is infinite return new IntPipeline.StatelessOp<U>(this, StreamShape.REFERENCE, - StreamOpFlag.NOT_SORTED | StreamOpFlag.NOT_DISTINCT | StreamOpFlag.NOT_SIZED) { + StreamOpFlag.NOT_SORTED | StreamOpFlag.NOT_DISTINCT | StreamOpFlag.NOT_SIZED) { @Override Sink<U> opWrapSink(int flags, Sink<Integer> sink) { return new Sink.ChainedReference<U>(sink) { + IntConsumer downstreamAsInt = downstream::accept; public void accept(U u) { - mapper.flattenInto(u, (Sink.OfInt) downstream); + // We can do better that this too; optimize for depth=0 case and just grab spliterator and forEach it + IntStream result = mapper.apply(u); + if (result != null) + result.sequential().forEach(downstreamAsInt); } }; } @@ -278,15 +283,20 @@ } @Override - public final DoubleStream flatMapToDouble(FlatMapper.ToDouble<? super U> mapper) { + public final DoubleStream flatMapToDouble(Function<? super U, ? extends DoubleStream> mapper) { Objects.requireNonNull(mapper); + // We can do better than this, by polling cancellationRequested when stream is infinite return new DoublePipeline.StatelessOp<U>(this, StreamShape.REFERENCE, - StreamOpFlag.NOT_SORTED | StreamOpFlag.NOT_DISTINCT | StreamOpFlag.NOT_SIZED) { + StreamOpFlag.NOT_SORTED | StreamOpFlag.NOT_DISTINCT | StreamOpFlag.NOT_SIZED) { @Override Sink<U> opWrapSink(int flags, Sink<Double> sink) { return new Sink.ChainedReference<U>(sink) { + DoubleConsumer downstreamAsDouble = downstream::accept; public void accept(U u) { - mapper.flattenInto(u, (Sink.OfDouble) downstream); + // We can do better that this too; optimize for depth=0 case and just grab spliterator and forEach it + DoubleStream result = mapper.apply(u); + if (result != null) + result.sequential().forEach(downstreamAsDouble); } }; } @@ -294,15 +304,20 @@ } @Override - public final LongStream flatMapToLong(FlatMapper.ToLong<? super U> mapper) { + public final LongStream flatMapToLong(Function<? super U, ? extends LongStream> mapper) { Objects.requireNonNull(mapper); + // We can do better than this, by polling cancellationRequested when stream is infinite return new LongPipeline.StatelessOp<U>(this, StreamShape.REFERENCE, - StreamOpFlag.NOT_SORTED | StreamOpFlag.NOT_DISTINCT | StreamOpFlag.NOT_SIZED) { + StreamOpFlag.NOT_SORTED | StreamOpFlag.NOT_DISTINCT | StreamOpFlag.NOT_SIZED) { @Override Sink<U> opWrapSink(int flags, Sink<Long> sink) { return new Sink.ChainedReference<U>(sink) { + LongConsumer downstreamAsLong = downstream::accept; public void accept(U u) { - mapper.flattenInto(u, (Sink.OfLong) downstream); + // We can do better that this too; optimize for depth=0 case and just grab spliterator and forEach it + LongStream result = mapper.apply(u); + if (result != null) + result.sequential().forEach(downstreamAsLong); } }; }
--- a/src/share/classes/java/util/stream/Stream.java Tue Apr 09 13:58:43 2013 -0400 +++ b/src/share/classes/java/util/stream/Stream.java Tue Apr 09 15:36:39 2013 -0400 @@ -160,7 +160,9 @@ /** * Produces a stream consisting of the results of replacing each * element of this stream with the contents of the stream produced - * by applying the provided function to each element. + * by applying the provided mapping function to each element. If the result + * of the mapping function is {@code null}, this is treated as if it had + * returned an empty stream. * * <p>This is an <a href="package-summary.html#StreamOps">intermediate * operation</a>. @@ -176,8 +178,6 @@ * orderStream.flatMap(order -> order.getLineItems().stream())... * }</pre> * - * <p>This implementation is likely to be less efficient than the other - * form of {@link #flatMap(FlatMapper)}, and is provided for convenience. * @param mapper A <a href="package-summary.html#NonInterference"> * non-interfering, stateless</a> function to be applied to * each element which produces a stream of new values @@ -186,36 +186,6 @@ <R> Stream<R> flatMap(Function<? super T, ? extends Stream<? extends R>> mapper); /** - * Produces a stream consisting of the results of replacing each - * element of this stream with zero or more transformed values, according - * to the transformation encoded in the provided {@code FlatMapper}. - * - * <p>This is an <a href="package-summary.html#StreamOps">intermediate - * operation</a>. - * @apiNote - * A {@code FlatMapper} is like a function that receives an element to - * transform, and a {@code Consumer} into which it deposits zero or more - * values corresponding to that element. For example, to map a stream of - * strings into a stream of the characters in those strings, you would do: - * <pre>{@code - * stringStream.flatMap((elt, destination) -> { - * for (i=0; i < elt.length(); i++) - * destination.accept(charAt(i)); - * }) - * ... - * }</pre> - * @implNote - * This form of {@code flatMap} is usually less convenient to use than the - * {@link #flatMap(Function)} form, but is often considerably more efficient - * because it eliminates the overhead of stream construction and traversal. - * @param mapper A <a href="package-summary.html#NonInterference"> - * non-interfering, stateless</a> {@code FlatMapper} that - * transforms each element into zero or more resulting values - * @return the new stream - */ - <R> Stream<R> flatMap(FlatMapper<? super T, R> mapper); - - /** * Produces an {@code IntStream} consisting of the results of replacing * each element of this stream with zero or more transformed values, * according to the transformation encoded in the provided @@ -223,18 +193,14 @@ * * <p>This is an <a href="package-summary.html#StreamOps">intermediate * operation</a>. - * @implNote - * This form of {@code flatMap} is usually less convenient to use than the - * {@link #flatMap(Function)} form, but is often considerably more efficient - * because it eliminates the overhead of stream construction and traversal. - * @see #flatMap(FlatMapper) + * * @param mapper A <a href="package-summary.html#NonInterference"> * non-interfering, stateless</a> {@code FlatMapper.ToInt} * that transforms each element into zero or more resulting * values * @return the new stream */ - IntStream flatMapToInt(FlatMapper.ToInt<? super T> mapper); + IntStream flatMapToInt(Function<? super T, ? extends IntStream> mapper); /** * Produces a {@code LongStream} consisting of the results of replacing each @@ -243,18 +209,14 @@ * * <p>This is an <a href="package-summary.html#StreamOps">intermediate * operation</a>. - * @implNote - * This form of {@code flatMap} is usually less convenient to use than the - * {@link #flatMap(Function)} form, but is often considerably more efficient - * because it eliminates the overhead of stream construction and traversal. - * @see #flatMap(FlatMapper) + * * @param mapper A <a href="package-summary.html#NonInterference"> * non-interfering, stateless</a> {@code FlatMapper.ToLong} * that transforms each element into zero or more resulting * values * @return the new stream */ - LongStream flatMapToLong(FlatMapper.ToLong<? super T> mapper); + LongStream flatMapToLong(Function<? super T, ? extends LongStream> mapper); /** * Produces a {@code DoubleStream} consisting of the results of replacing @@ -264,18 +226,14 @@ * * <p>This is an <a href="package-summary.html#StreamOps">intermediate * operation</a>. - * @implNote - * This form of {@code flatMap} is usually less convenient to use than the - * {@link #flatMap(Function)} form, but is often considerably more efficient - * because it eliminates the overhead of stream construction and traversal. - * @see #flatMap(FlatMapper) + * * @param mapper A <a href="package-summary.html#NonInterference"> * non-interfering, stateless</a> {@code FlatMapper.ToDouble} * that transforms each element into zero or more resulting * values * @return the new stream */ - DoubleStream flatMapToDouble(FlatMapper.ToDouble<? super T> mapper); + DoubleStream flatMapToDouble(Function<? super T, ? extends DoubleStream> mapper); /** * Produces a stream consisting of the distinct elements (according to
--- a/test-ng/bootlib/java/util/stream/LambdaTestHelpers.java Tue Apr 09 13:58:43 2013 -0400 +++ b/test-ng/bootlib/java/util/stream/LambdaTestHelpers.java Tue Apr 09 15:36:39 2013 -0400 @@ -69,9 +69,14 @@ public static final Function<Integer, Integer> mZero = x -> 0; public static final Function<Integer, Integer> mId = x -> x; public static final Function<Integer, Integer> mDoubler = x -> x * 2; - public static final FlatMapper<Integer, Integer> mfId = (e, s) -> s.accept(e); - public static final FlatMapper<Integer, Integer> mfNull = (e, s) -> { }; - public static final FlatMapper<Integer, Integer> mfLt = (e, s) -> { for (int i=0; i<e; i++) s.accept(i); }; + public static final Function<Integer, Stream<Integer>> mfId = e -> Collections.singletonList(e).stream(); + public static final Function<Integer, Stream<Integer>> mfNull = e -> Collections.<Integer>emptyList().stream(); + public static final Function<Integer, Stream<Integer>> mfLt = e -> { + List<Integer> l = new ArrayList<>(); + for (int i=0; i<e; i++) + l.add(i); + return l.stream(); + }; public static final ToIntFunction<Integer> imDoubler = x -> x * 2; public static final ToLongFunction<Long> lmDoubler = x -> x * 2; public static final ToDoubleFunction<Double> dmDoubler = x -> x * 2; @@ -111,17 +116,15 @@ public static final IntFunction<Object[]> objectArrayGenerator = s -> new Object[s]; - public static final FlatMapper<String, Character> flattenChars = (String string, Consumer<Character> sink) -> { - for (int i=0; i<string.length(); i++) { - sink.accept(string.charAt(i)); - } + public static final Function<String, Stream<Character>> flattenChars = string -> { + List<Character> l = new ArrayList<>(); + for (int i=0; i<string.length(); i++) + l.add(string.charAt(i)); + return l.stream(); }; - public static final FlatMapper.ToInt<String> flattenInt = (String string, IntConsumer sink) -> { - for (int i=0; i<string.length(); i++) { - sink.accept((int) string.charAt(i)); - } - }; + public static final Function<String, IntStream> flattenInt + = string -> Streams.intRange(0, string.length()).map(string::charAt); public static List<Integer> empty() { ArrayList<Integer> list = new ArrayList<>();
--- a/test-ng/boottests/java/util/stream/SpinedBufferTest.java Tue Apr 09 13:58:43 2013 -0400 +++ b/test-ng/boottests/java/util/stream/SpinedBufferTest.java Tue Apr 09 15:36:39 2013 -0400 @@ -44,13 +44,7 @@ try { sizes = Streams.intRange(0, 16) .map(i -> 1 << i) - .flatMap((i, s) -> { - s.accept(i - 2); - s.accept(i - 1); - s.accept(i); - s.accept(i + 1); - s.accept(i + 2); - }) + .flatMap(i -> Arrays.stream(new int[] { i-2, i-1, i, i+1, i+2 })) .filter(i -> i >= 0) .boxed() .distinct()
--- a/test-ng/tests/org/openjdk/tests/java/util/stream/ExplodeOpTest.java Tue Apr 09 13:58:43 2013 -0400 +++ b/test-ng/tests/org/openjdk/tests/java/util/stream/ExplodeOpTest.java Tue Apr 09 15:36:39 2013 -0400 @@ -28,7 +28,9 @@ import java.util.Arrays; import java.util.Collection; +import java.util.Collections; import java.util.function.BiConsumer; +import java.util.function.Function; import java.util.stream.*; import static java.util.stream.LambdaTestHelpers.*; @@ -41,9 +43,8 @@ @Test public class ExplodeOpTest extends OpTestCase { - static final FlatMapper<Integer, Integer> integerRangeMapper = (e, c) -> { - for (int i = 0; i < e; i++) c.accept(i); - }; + static final Function<Integer, Stream<Integer>> integerRangeMapper + = e -> Streams.intRange(0, e).boxed(); public void testFlatMap() { String[] stringsArray = {"hello", "there", "", "yada"}; @@ -67,9 +68,7 @@ assertEquals(0, result.size()); exerciseOps(data, s -> s.flatMap(mfLt)); - exerciseOps(data, s -> s.flatMap(integerRangeMapper)); - exerciseOps(data, s -> s.flatMap((Integer e) -> Streams.intRange(0, e).boxed().limit(10))); } @@ -77,16 +76,14 @@ @Test(dataProvider = "IntStreamTestData", dataProviderClass = IntStreamTestDataProvider.class) public void testIntOps(String name, IntStreamTestData data) { - Collection<Integer> result = exerciseOps(data, s -> s.flatMap((i, sink) -> sink.accept(i))); + Collection<Integer> result = exerciseOps(data, s -> s.flatMap(i -> Collections.singleton(i).stream().mapToInt(j -> j))); assertEquals(data.size(), result.size()); + assertContents(data, result); - result = exerciseOps(data, s -> s.flatMap((i, sink) -> { })); + result = exerciseOps(data, s -> s.flatMap(i -> Streams.emptyIntStream())); assertEquals(0, result.size()); - exerciseOps(data, s -> s.flatMap((e, sink) -> { - for (int i = 0; i < e; i++) sink.accept(i); - })); - + exerciseOps(data, s -> s.flatMap(e -> Streams.intRange(0, e))); exerciseOps(data, s -> s.flatMap(e -> Streams.intRange(0, e).limit(10))); } @@ -94,16 +91,14 @@ @Test(dataProvider = "LongStreamTestData", dataProviderClass = LongStreamTestDataProvider.class) public void testLongOps(String name, LongStreamTestData data) { - Collection<Long> result = exerciseOps(data, s -> s.flatMap((i, sink) -> sink.accept(i))); + Collection<Long> result = exerciseOps(data, s -> s.flatMap(i -> Collections.singleton(i).stream().mapToLong(j -> j))); assertEquals(data.size(), result.size()); + assertContents(data, result); - result = exerciseOps(data, s -> s.flatMap((i, sink) -> { })); + result = exerciseOps(data, s -> Streams.emptyLongStream()); assertEquals(0, result.size()); - exerciseOps(data, s -> s.flatMap((e, sink) -> { - for (int i = 0; i < e; i++) sink.accept(i); - })); - + exerciseOps(data, s -> s.flatMap(e -> Streams.longRange(0, e))); exerciseOps(data, s -> s.flatMap(e -> Streams.longRange(0, e).limit(10))); } @@ -111,16 +106,14 @@ @Test(dataProvider = "DoubleStreamTestData", dataProviderClass = DoubleStreamTestDataProvider.class) public void testDoubleOps(String name, DoubleStreamTestData data) { - Collection<Double> result = exerciseOps(data, s -> s.flatMap((i, sink) -> sink.accept(i))); + Collection<Double> result = exerciseOps(data, s -> s.flatMap(i -> Collections.singleton(i).stream().mapToDouble(j -> j))); assertEquals(data.size(), result.size()); + assertContents(data, result); - result = exerciseOps(data, s -> s.flatMap((i, sink) -> { })); + result = exerciseOps(data, s -> Streams.emptyDoubleStream()); assertEquals(0, result.size()); - exerciseOps(data, s -> s.flatMap((e, sink) -> { - for (int i = 0; i < e; i++) sink.accept(i); - })); - - exerciseOps(data, s -> s.flatMap(e -> Streams.longRange(0, (long) e).doubles().limit(10))); + exerciseOps(data, s -> s.flatMap(e -> Streams.doubleRange(0, e))); + exerciseOps(data, s -> s.flatMap(e -> Streams.doubleRange(0, e).limit(10))); } }
--- a/test-ng/tests/org/openjdk/tests/java/util/stream/ToArrayOpTest.java Tue Apr 09 13:58:43 2013 -0400 +++ b/test-ng/tests/org/openjdk/tests/java/util/stream/ToArrayOpTest.java Tue Apr 09 15:36:39 2013 -0400 @@ -75,10 +75,7 @@ // Fixed size optimizations will not be used Object[] objects = exerciseTerminalOps(data, - s -> s.flatMap((Integer e, Consumer<Integer> sink) -> { - sink.accept(e); - sink.accept(e); - }), + s -> s.flatMap(e -> Arrays.stream(new Object[] { e, e })), s -> s.toArray()); assertTrue(objects.length == data.size() * 2); } @@ -195,10 +192,7 @@ // Fixed size optimizations will not be used int[] objects = exerciseTerminalOps(data, - s -> s.flatMap((e, sink) -> { - sink.accept(e); - sink.accept(e); - }), + s -> s.flatMap(e -> Arrays.stream(new int[] { e, e })), s -> s.toArray()); assertTrue(objects.length == data.size() * 2); } @@ -271,10 +265,7 @@ // Fixed size optimizations will not be used long[] objects = exerciseTerminalOps(data, - s -> s.flatMap((e, sink) -> { - sink.accept(e); - sink.accept(e); - }), + s -> s.flatMap(e -> Arrays.stream(new long[] { e, e })), s -> s.toArray()); assertTrue(objects.length == data.size() * 2); } @@ -347,10 +338,7 @@ // Fixed size optimizations will not be used double[] objects = exerciseTerminalOps(data, - s -> s.flatMap((e, sink) -> { - sink.accept(e); - sink.accept(e); - }), + s -> s.flatMap(e -> Arrays.stream(new double[] { e, e })), s -> s.toArray()); assertTrue(objects.length == data.size() * 2); }
--- a/test/java/util/LambdaUtilities.java Tue Apr 09 13:58:43 2013 -0400 +++ b/test/java/util/LambdaUtilities.java Tue Apr 09 15:36:39 2013 -0400 @@ -38,7 +38,6 @@ import java.util.function.*; import java.util.stream.IntStream; import java.util.stream.Stream; -import java.util.stream.FlatMapper; public class LambdaUtilities { @@ -121,87 +120,6 @@ return c -> Character.isDigit(c); } - public static FlatMapper<Integer, Integer> genIntegerFlatMapper(int selected) { - switch (selected) { - case 0: - //Generate a empty collection - return ( e, s ) -> { }; - case 1: - return ( e, s ) -> { s.accept(e); }; - case 2: - //Generate a triangle has different value - return ( e, s ) -> { - for (int i = 0; i < e; i++) { - s.accept(e * (e - 1) / 2 + i); - } - }; - case 3: - //Generate a triangle has different value - return ( e, s ) -> { - for (int i = 0; i < e; i++) { - s.accept(e); - } - }; - default: - //Generate 64 folded flat map - return ( e, s ) -> { - for (int i = 0; i < 1 << 6; i++) { - s.accept(e); - } - }; - } - } - - public static FlatMapper.OfIntToInt genIntFlatMapper(int selected) { - switch (selected) { - case 0: - //Generate a empty collection - return ( e, s ) -> { }; - case 1: - return ( e, s ) -> { s.accept(e); }; - case 2: - //Generate a triangle has different value - return ( e, s ) -> { - for (int i = 0; i < e; i++) { - s.accept(e * (e - 1) / 2 + i); - } - }; - case 3: - //Generate a triangle has different value - return ( e, s ) -> { - for (int i = 0; i < e; i++) { - s.accept(e); - } - }; - default: - //Generate 64 folded flat map - return ( e, s ) -> { - for (int i = 0; i < 1 << 6; i++) { - s.accept(e); - } - }; - } - } - - public static FlatMapper<StringBuilder, StringBuilder> genSBFlatMapper(int selected, int unit) { - switch(selected) { - case 0: - //Generate a empty collection - return (e, s) -> { }; - case 1: return (e, s) -> { s.accept(e); }; - case 2: - return (e, s) -> {int step = e.length() / unit + unit -1; - for (int i = 0; i < e.length(); i += step) - s.accept(new StringBuilder(e.substring(i, i + step >= e.length() ? - e.length() - 1 : i + step)));}; - case 3: - default: - //Generate 64 folded flat map - return (e, s) -> {int step = e.length() / unit + unit -1; - for (int i = 0; i < e.length(); i+=step) s.accept(e);}; - } - } - public static Function<Integer, Integer> posIntegerFunction(boolean isHighest) { if (isHighest) { return i -> Integer.valueOf(new StringBuilder().append(i < 0 ? -i : i).reverse().toString()) % 10;
--- a/test/java/util/stream/Stream/EmployeeStreamTest.java Tue Apr 09 13:58:43 2013 -0400 +++ b/test/java/util/stream/Stream/EmployeeStreamTest.java Tue Apr 09 15:36:39 2013 -0400 @@ -37,7 +37,6 @@ import java.util.function.Function; import java.util.function.Predicate; import java.util.stream.Collectors; -import java.util.stream.FlatMapper; import java.util.stream.Stream; import java.util.stream.Streams; import static org.testng.Assert.*; @@ -1010,67 +1009,73 @@ } - public static FlatMapper<Employee, Employee> + public static Function<Employee, Stream<Employee>> genEmployeeFlatMapper(int selected, Employee.Rule rule) { switch (selected) { case 0: //Generate a empty collection - return ( e, s ) -> { }; + return e -> Streams.emptyStream(); case 1: - return ( e, s ) -> { s.accept(e); }; + return e -> Arrays.stream(new Employee[] { e }); case 2: switch (rule) { case AGE: - return ( e, s ) -> { + return e -> { + List<Employee> list = new ArrayList<>(); for (int i = 0; i < e.age; i+= e.age / 10) { Employee employee = e.clone(); employee.id = e.id; employee.age = e.age * (e.age - 1) / 2 + i; - s.accept(employee); + list.add(employee); } + return list.stream(); }; case SALARY: - return ( e, s ) -> { + return e -> { + List<Employee> list = new ArrayList<>(); for (int i = 0; i < (int)e.salary; i+= (int)e.salary / 10) { Employee employee = e.clone(); employee.id = e.id; employee.salary = e.salary * (e.salary - 1) / 2 + i; - s.accept(employee); + list.add(employee); } + return list.stream(); }; case MALE: - return ( e, s ) -> { + return e -> { + List<Employee> list = new ArrayList<>(); Employee employee = e.clone(); employee.male = !e.male; employee.id = e.id; - s.accept(employee); + list.add(employee); + return list.stream(); }; case TITLE: - return ( e, s ) -> { + return e-> { + List<Employee> list = new ArrayList<>(); for (int i = 0; i < e.title.ordinal(); i ++) { Employee employee = e.clone(); employee.title = Employee.Title.values()[i]; employee.id = e.id; - s.accept(employee); + list.add(employee); } + return list.stream(); }; case ID: default: - return ( e, s ) -> { + return e -> { + List<Employee> list = new ArrayList<>(); for (int i = 0; i < e.id.length(); i += 2) { Employee employee = e.clone(); employee.id = e.id; - s.accept(employee); + list.add(employee); } + return list.stream(); }; } case 3: default: - return ( e, s ) -> { - for (int i = 0; i < 10; i++) { - s.accept(e); - } - }; + return e -> Streams.intRange(0, 10).mapToObj(i -> e); } }
--- a/test/java/util/stream/Stream/IntStreamTest.java Tue Apr 09 13:58:43 2013 -0400 +++ b/test/java/util/stream/Stream/IntStreamTest.java Tue Apr 09 15:36:39 2013 -0400 @@ -35,6 +35,7 @@ import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicLong; import java.util.function.BiFunction; +import java.util.function.IntFunction; import java.util.function.IntPredicate; import java.util.stream.IntStream; import java.util.stream.Stream; @@ -346,8 +347,8 @@ : (p == ParallelType.Sequential) ? Arrays.stream(array).sequential() : Arrays.stream(array); int limit = rand.nextInt(ARRAY_SIZE * (ARRAY_SIZE - 1)); - int[] flatArr = stream1.flatMap(LambdaUtilities.genIntFlatMapper(2)).toArray(); - int[] result= stream2.flatMap(LambdaUtilities.genIntFlatMapper(2)).limit(limit).toArray(); + int[] flatArr = stream1.flatMap(genIntFlatMapper(2)).toArray(); + int[] result= stream2.flatMap(genIntFlatMapper(2)).limit(limit).toArray(); if(limit > flatArr.length) assertEquals(flatArr.length,result.length); else { @@ -368,7 +369,7 @@ : (p == ParallelType.Sequential) ? Arrays.stream(array).sequential() : Arrays.stream(array); int selected = rand.nextInt(5); - int[] flatArray = stream.flatMap(LambdaUtilities.genIntFlatMapper(selected)).sorted().toArray(); + int[] flatArray = stream.flatMap(genIntFlatMapper(selected)).sorted().toArray(); verifyMultifunction(array, flatArray, selected); } } @@ -672,13 +673,13 @@ IntStream stream = (p == ParallelType.Parallel) ? Arrays.parallelStream(array1) : (p == ParallelType.Sequential) ? Arrays.stream(array1).sequential() : Arrays.stream(array1); - int[] toArray1 = stream.flatMap(LambdaUtilities.genIntFlatMapper(4)).distinct().toArray(); + int[] toArray1 = stream.flatMap(genIntFlatMapper(4)).distinct().toArray(); assertEquals(toArray1, array1); IntStream emptyStream = (p == ParallelType.Parallel) ? Arrays.parallelStream(new int[0]): (p == ParallelType.Sequential) ? Arrays.stream(new int[0]).sequential() : Arrays.stream(new int[0]); - assertEquals(emptyStream.flatMap(LambdaUtilities.genIntFlatMapper(4)).distinct().toArray().length, 0); + assertEquals(emptyStream.flatMap(genIntFlatMapper(4)).distinct().toArray().length, 0); } } @@ -803,4 +804,24 @@ for(int index = 0; index < array.length - 1; index++) assertTrue(array[index] <= array[index + 1]); } + + + private static IntFunction<IntStream> genIntFlatMapper(int selected) { + switch (selected) { + case 0: + //Generate a empty collection + return e -> Streams.emptyIntStream(); + case 1: + return e -> Arrays.stream(new int[]{ e }); + case 2: + //Generate a triangle has different value + return e -> Streams.intRange(0, e).map(i -> e * (e - 1) / 2 + i); + case 3: + //Generate a triangle has different value + return e -> Streams.intRange(0, e).map(i -> e); + default: + //Generate 64 folded flat map + return e -> Streams.intRange(0, 1 << 6).map(i -> e); + } + } }
--- a/test/java/util/stream/Stream/IntegerStreamTest.java Tue Apr 09 13:58:43 2013 -0400 +++ b/test/java/util/stream/Stream/IntegerStreamTest.java Tue Apr 09 15:36:39 2013 -0400 @@ -35,6 +35,7 @@ import java.util.concurrent.*; import java.util.concurrent.atomic.AtomicInteger; import java.util.function.BiFunction; +import java.util.function.Function; import java.util.function.Predicate; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -423,12 +424,12 @@ Stream<Integer> stream1 = (type == ParallelType.Parallel) ? c.parallelStream(): (type == ParallelType.Sequential) ? c.stream().sequential() : c.stream(); - Collection<Integer> result1 = stream1.flatMap(LambdaUtilities.genIntegerFlatMapper(2)).collect(Collectors.toCollection(LinkedList<Integer>::new)); + Collection<Integer> result1 = stream1.flatMap(genIntegerFlatMapper(2)).collect(Collectors.toCollection(LinkedList<Integer>::new)); Stream<Integer> stream2 = (type == ParallelType.Parallel) ? c.parallelStream(): (type == ParallelType.Sequential) ? c.stream().sequential() : c.stream(); - Collection<Integer> result2 = stream2.flatMap(LambdaUtilities.genIntegerFlatMapper(2)).limit(limit).collect(Collectors.toCollection(LinkedList<Integer>::new)); + Collection<Integer> result2 = stream2.flatMap(genIntegerFlatMapper(2)).limit(limit).collect(Collectors.toCollection(LinkedList<Integer>::new)); if(limit > result1.size()) assertEquals(result1.size(), result2.size()); @@ -456,7 +457,7 @@ Stream<Integer> stream = (type == ParallelType.Parallel) ? c.parallelStream(): (type == ParallelType.Sequential) ? c.stream().sequential() : c.stream(); - List<Integer> result = stream.flatMap(LambdaUtilities.genIntegerFlatMapper(selected)).collect(Collectors.<Integer>toList()); + List<Integer> result = stream.flatMap(genIntegerFlatMapper(selected)).collect(Collectors.<Integer>toList()); verifyMultifunction(c, result, selected); } } @@ -916,7 +917,7 @@ Stream<Integer> stream1 = (type == ParallelType.Parallel) ? c1.parallelStream(): (type == ParallelType.Sequential) ? c1.stream().sequential() : c1.stream(); - List<Integer> list2 = stream1.flatMap(LambdaUtilities.genIntegerFlatMapper(4)).distinct().collect(Collectors.<Integer>toList()); + List<Integer> list2 = stream1.flatMap(genIntegerFlatMapper(4)).distinct().collect(Collectors.<Integer>toList()); assertEquals(set1.size(), list2.size()); assertTrue(set1.containsAll(list2)); } @@ -1130,4 +1131,29 @@ } assertEquals(itOrg.hasNext(), pit.hasNext()); } + + private static Function<Integer, Stream<Integer>> genIntegerFlatMapper(int selected) { + switch (selected) { + case 0: + //Generate a empty collection + return e -> Streams.emptyStream(); + case 1: + return e -> Collections.singletonList(e).stream(); + case 2: + //Generate a triangle has different value + return e -> { + List<Integer> list = new ArrayList<>(); + for (int i = 0; i < e; i++) { + list.add(e * (e - 1) / 2 + i); + } + return list.stream(); + }; + case 3: + //Generate a triangle has different value + return e -> Streams.intRange(0, e).map(i -> e).boxed(); + default: + //Generate 64 folded flat map + return e -> Streams.intRange(0, 1 << 6).map(i -> e).boxed(); + } + } }
--- a/test/java/util/stream/Stream/StringBuilderStreamTest.java Tue Apr 09 13:58:43 2013 -0400 +++ b/test/java/util/stream/Stream/StringBuilderStreamTest.java Tue Apr 09 15:36:39 2013 -0400 @@ -34,6 +34,7 @@ import java.util.concurrent.*; import java.util.concurrent.atomic.AtomicReference; import java.util.function.BiFunction; +import java.util.function.Function; import java.util.function.Predicate; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -383,12 +384,12 @@ Stream<StringBuilder> stream1 = (type == ParallelType.Parallel) ? c.parallelStream(): (type == ParallelType.Sequential) ? c.stream().sequential() : c.stream(); - Collection<StringBuilder> result1 = stream1.flatMap(LambdaUtilities.genSBFlatMapper(2, DATA_SIZE / 10)).collect(Collectors.toCollection(LinkedList<StringBuilder>::new)); + Collection<StringBuilder> result1 = stream1.flatMap(genSBFlatMapper(2, DATA_SIZE / 10)).collect(Collectors.toCollection(LinkedList<StringBuilder>::new)); Stream<StringBuilder> stream2 = (type == ParallelType.Parallel) ? c.parallelStream(): (type == ParallelType.Sequential) ? c.stream().sequential() : c.stream(); - Collection<StringBuilder> result2 = stream2.flatMap(LambdaUtilities.genSBFlatMapper(2, DATA_SIZE / 10)).limit(limit).collect(Collectors.toCollection(LinkedList<StringBuilder>::new)); + Collection<StringBuilder> result2 = stream2.flatMap(genSBFlatMapper(2, DATA_SIZE / 10)).limit(limit).collect(Collectors.toCollection(LinkedList<StringBuilder>::new)); if(limit > result1.size()) assertTrue(result1.size() == result2.size()); @@ -409,7 +410,7 @@ Stream<StringBuilder> stream = (type == ParallelType.Parallel) ? c.parallelStream(): (type == ParallelType.Sequential) ? c.stream().sequential() : c.stream(); - List<StringBuilder> result = stream.flatMap(LambdaUtilities.genSBFlatMapper(selected, DATA_SIZE / 10)).collect(Collectors.<StringBuilder>toList()); + List<StringBuilder> result = stream.flatMap(genSBFlatMapper(selected, DATA_SIZE / 10)).collect(Collectors.<StringBuilder>toList()); verifyFlatBiBlock(c, result, selected, DATA_SIZE / 10); } } @@ -740,7 +741,7 @@ Set<StringBuilder> set1 = new HashSet<>(c1); Stream<StringBuilder> stream1 = (type == ParallelType.Parallel) ? c1.parallelStream() : (type == ParallelType.Sequential) ? c1.stream().sequential() : c1.stream(); - List<StringBuilder> list2 = stream1.flatMap(LambdaUtilities.genSBFlatMapper(3, DATA_SIZE / 10)).distinct().collect(Collectors.<StringBuilder>toList()); + List<StringBuilder> list2 = stream1.flatMap(genSBFlatMapper(3, DATA_SIZE / 10)).distinct().collect(Collectors.<StringBuilder>toList()); assertEquals(set1.size(), list2.size()); assertTrue(set1.containsAll(list2)); } @@ -957,4 +958,32 @@ assertEquals(itOrg.next(), itSliced.next()); } + + private static Function<StringBuilder, Stream<StringBuilder>> genSBFlatMapper(int selected, int unit) { + switch(selected) { + case 0: + //Generate a empty collection + return e -> Streams.emptyStream(); + case 1: return e -> Collections.singletonList(e).stream(); + case 2: + return e -> { + int step = e.length() / unit + unit -1; + List<StringBuilder> results = new ArrayList<>(); + for (int i = 0; i < e.length(); i += step) + results.add(new StringBuilder(e.substring(i, i + step >= e.length() ? + e.length() - 1 : i + step))); + return results.stream(); + }; + case 3: + default: + //Generate 64 folded flat map + return e -> { + int step = e.length() / unit + unit -1; + List<StringBuilder> results = new ArrayList<>(); + for (int i = 0; i < e.length(); i+=step) + results.add(e); + return results.stream(); + }; + } + } }