OpenJDK / lambda / lambda / jdk
changeset 5970:685ce67a171b it2-bootstrap
Merge
author | mduigou |
---|---|
date | Tue, 04 Sep 2012 15:29:13 -0700 |
parents | eb56503977d6 6a1eb323c7df |
children | ff45d6cfdffc |
files | src/share/classes/java/util/Spliterator.java src/share/classes/java/util/Splittable.java |
diffstat | 25 files changed, 182 insertions(+), 190 deletions(-) [+] |
line wrap: on
line diff
--- a/make/java/java/FILES_java.gmk Tue Sep 04 14:14:34 2012 -0700 +++ b/make/java/java/FILES_java.gmk Tue Sep 04 15:29:13 2012 -0700 @@ -281,7 +281,6 @@ java/util/TimerTask.java \ java/util/Objects.java \ java/util/UUID.java \ - java/util/Splittable.java \ java/util/concurrent/AbstractExecutorService.java \ java/util/concurrent/ArrayBlockingQueue.java \ java/util/concurrent/BlockingDeque.java \
--- a/src/share/classes/java/util/Arrays.java Tue Sep 04 14:14:34 2012 -0700 +++ b/src/share/classes/java/util/Arrays.java Tue Sep 04 15:29:13 2012 -0700 @@ -26,7 +26,6 @@ package java.util; import java.lang.reflect.*; -import java.util.functions.*; import java.util.streams.*; /** @@ -3737,14 +3736,16 @@ } @Override - public void forEach(Block<? super T> block) { + public void into(Sink<T, ?, ?> sink) { + sink.begin(getRemainingSizeIfKnown()); // Strange-looking way to iterate; reduce heap write traffic if (offset < endOffset) { int wasOffset = offset; offset = endOffset; for (int i=wasOffset; i<endOffset; i++) - block.apply(array[i]); + sink.accept(array[i]); } + sink.end(); } @Override @@ -3754,6 +3755,11 @@ offset += t; return ret; } + + @Override + public Iterator<T> iterator() { + return this; + } } private static class ArrayStreamAccessor<T> @@ -3763,14 +3769,16 @@ } @Override - public void forEach(Block<? super T> block) { + public void into(Sink<T, ?, ?> sink) { + sink.begin(endOffset-offset); // Strange-looking way to iterate; reduce heap write traffic if (offset < endOffset) { int wasOffset = offset; offset = endOffset; for (int i=wasOffset; i<endOffset; i++) - block.apply(array[i]); + sink.accept(array[i]); } + sink.end(); } @Override
--- a/src/share/classes/java/util/Map.java Tue Sep 04 14:14:34 2012 -0700 +++ b/src/share/classes/java/util/Map.java Tue Sep 04 15:29:13 2012 -0700 @@ -26,11 +26,8 @@ package java.util; import java.util.functions.BiBlock; -import java.util.functions.Block; -import java.util.functions.Predicate; import java.util.streams.MapStream; -import java.util.streams.Stream; -import java.util.streams.Streamable; +import java.util.streams.MapStreamable; import java.util.streams.Streams; /** @@ -122,7 +119,7 @@ * @see Set * @since 1.2 */ -public interface Map<K,V> extends Sized, Streamable<Mapping<K,V>>, MapTraversable<K,V>, MapStream.Destination<K,V> { +public interface Map<K,V> extends Sized, MapStreamable<K,V>, MapTraversable<K,V>, MapStream.Destination<K,V> { // Query Operations @@ -492,8 +489,14 @@ } @Override - Stream<Mapping<K,V>> stream() default { - return Streams.stream(this, size()); + void forEach(BiBlock<? super K, ? super V> block) default { + for (Map.Entry<K, V> entry : entrySet()) + block.apply(entry.getKey(), entry.getValue()); + } + + @Override + MapStream<K,V> stream() default { + return Streams.stream(this); } @Override
--- a/src/share/classes/java/util/MapTraversable.java Tue Sep 04 14:14:34 2012 -0700 +++ b/src/share/classes/java/util/MapTraversable.java Tue Sep 04 15:29:13 2012 -0700 @@ -35,18 +35,13 @@ * * @author Brian Goetz */ -public interface MapTraversable<K,V> extends Traversable<Mapping<K,V>> { +public interface MapTraversable<K,V> { /** * Each element of the object will be provided to the specified Sink. * * @param block The Sink to which elements will be provided. */ - void forEach(BiBlock<? super K, ? super V> block) default { - for (Mapping<K,V> m : this) { - block.apply(m.getKey(), m.getValue()); - } - } + void forEach(BiBlock<? super K, ? super V> block); - @Override MapIterator<K,V> iterator(); }
--- a/src/share/classes/java/util/Spliterator.java Tue Sep 04 14:14:34 2012 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,66 +0,0 @@ -/* - * Copyright (c) 2012, 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; - -import java.util.functions.Block; - -/** - * Spliterator - * - * @author Brian Goetz - * @author Doug Lea - */ -public interface Spliterator<T> extends Iterator<T> { - /** - * Returns a Spliterator covering approximately half of the - * elements, guaranteed not to overlap with those subsequently - * returned by this spliterator. After invoking this method, - * the current Spliterator will <em>not</em> cover the - * elements of the returned Spliterator. - * - * @return a Spliterator covering the associated elements - * @throws IllegalStateException if this Spliterator has - * already commenced traversing elements. - */ - Spliterator<T> split(); - - /** Process the remaining elements sequentially. */ - void forEach(Block<? super T> sink); - - /** - * Return the number of elements remaining to be processed, if the count can - * be computed exactly and cheaply. Otherwise, return -1. - * - * @return The number of remaining elements, or negative value if unknown - */ - int getRemainingSizeIfKnown() default { return -1; } - - /** - * Return {@code true} if this spliterator returns symmetric splits. - * - * @return {@code true} if this spliterator returns symmetric splits. - */ - boolean isPredictableSplits() default { return false; } -}
--- a/src/share/classes/java/util/Splittable.java Tue Sep 04 14:14:34 2012 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,10 +0,0 @@ -package java.util; - -/** - * A decomposable container for elements. - * - * @param <T> the type of elements returned by the sequential iterator - */ -public interface Splittable<T> extends Iterable<T> { - Spliterator<T> spliterator(); -}
--- a/src/share/classes/java/util/streams/AbstractPipeline.java Tue Sep 04 14:14:34 2012 -0700 +++ b/src/share/classes/java/util/streams/AbstractPipeline.java Tue Sep 04 15:29:13 2012 -0700 @@ -148,18 +148,14 @@ else { // Push traversal StatefulSink<U, V> terminalSink = terminal.sink(); - Sink sink = wrapSink(ops, terminalSink); - sink.begin(-1); // @@@ supply size if known - source.forEach(sink); - sink.end(); + source.into(wrapSink(ops, terminalSink)); return terminalSink.getAndClearState(); } } private static Sink wrapSink(IntermediateOp[] ops, Sink sink) { for (int i=ops.length-1; i >= 0; i--) { - IntermediateOp op = ops[i]; - sink = op.sink(sink); + sink = ops[i].sink(sink); } return sink; } @@ -202,7 +198,7 @@ public Iterator<U> iterator() { if (iterator == null) { - iterator = (Iterator) ((op == null) ? source : op.iterator(upstream.iterator())); + iterator = (Iterator) ((op == null) ? source.iterator() : op.iterator(upstream.iterator())); } return iterator; }
--- a/src/share/classes/java/util/streams/AbstractSequentialMapStreamAccessor.java Tue Sep 04 14:14:34 2012 -0700 +++ b/src/share/classes/java/util/streams/AbstractSequentialMapStreamAccessor.java Tue Sep 04 15:29:13 2012 -0700 @@ -25,7 +25,6 @@ package java.util.streams; import java.util.Mapping; -import java.util.Spliterator; /** * AbstractSequentialMapStreamAccessor
--- a/src/share/classes/java/util/streams/AbstractSequentialStreamAccessor.java Tue Sep 04 14:14:34 2012 -0700 +++ b/src/share/classes/java/util/streams/AbstractSequentialStreamAccessor.java Tue Sep 04 15:29:13 2012 -0700 @@ -24,8 +24,6 @@ */ package java.util.streams; -import java.util.Spliterator; - /** * AbstractSequentialStreamAccessor *
--- a/src/share/classes/java/util/streams/MapStream.java Tue Sep 04 14:14:34 2012 -0700 +++ b/src/share/classes/java/util/streams/MapStream.java Tue Sep 04 15:29:13 2012 -0700 @@ -35,7 +35,7 @@ * * @author Brian Goetz */ -public interface MapStream<K, V> extends MapTraversable<K, V> { +public interface MapStream<K, V> { MapIterator<K, V> iterator(); boolean isParallel();
--- a/src/share/classes/java/util/streams/MapStreamable.java Tue Sep 04 14:14:34 2012 -0700 +++ b/src/share/classes/java/util/streams/MapStreamable.java Tue Sep 04 15:29:13 2012 -0700 @@ -24,13 +24,10 @@ */ package java.util.streams; -import java.util.Mapping; - /** * MapStreamable * - * @param <T> Type of stream elements. - * + * @author Brian Goetz */ public interface MapStreamable<K,V> { MapStream<K,V> stream();
--- a/src/share/classes/java/util/streams/Sink.java Tue Sep 04 14:14:34 2012 -0700 +++ b/src/share/classes/java/util/streams/Sink.java Tue Sep 04 15:29:13 2012 -0700 @@ -26,6 +26,7 @@ import java.util.Mapping; import java.util.Objects; +import java.util.functions.BiBlock; import java.util.functions.Block; /** @@ -33,7 +34,7 @@ * * @author Brian Goetz */ -public interface Sink<T, K, V> extends Block<T> { +public interface Sink<T, K, V> extends Block<T>, BiBlock<K,V> { void accept(T t); void accept(K k, V v) default { throw new IllegalStateException(); } @@ -60,6 +61,8 @@ @Override void apply(T t) default { accept(t); } + @Override + void apply(K k, V v) default { accept(k, v); } public interface OfLinear<T> extends Sink<T, Object, Object> { @Override
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/classes/java/util/streams/Spliterator.java Tue Sep 04 15:29:13 2012 -0700 @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2012, 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.streams; + +import java.util.Iterator; + +/** + * Spliterator + * + * @author Brian Goetz + * @author Doug Lea + */ +public interface Spliterator<T> { + /** + * Returns a Spliterator covering approximately half of the + * elements, guaranteed not to overlap with those subsequently + * returned by this spliterator. After invoking this method, + * the current Spliterator will <em>not</em> cover the + * elements of the returned Spliterator. + * + * @return a Spliterator covering the associated elements + * @throws IllegalStateException if this Spliterator has + * already commenced traversing elements. + */ + Spliterator<T> split(); + + /** + * Return an Iterator covering the remaining elements + */ + Iterator<T> iterator(); + + /** Send the remaining elements sequentially into the specified sink */ + void into(Sink<T, ?, ?> sink); + + /** + * Return the number of elements remaining to be processed, if the count can + * be computed exactly and cheaply. Otherwise, return -1. + * + * @return The number of remaining elements, or negative value if unknown + */ + int getRemainingSizeIfKnown() default { return -1; } + + /** + * Return {@code true} if this spliterator returns symmetric splits. + * + * @return {@code true} if this spliterator returns symmetric splits. + */ + boolean isPredictableSplits() default { return false; } +}
--- a/src/share/classes/java/util/streams/Stream.java Tue Sep 04 14:14:34 2012 -0700 +++ b/src/share/classes/java/util/streams/Stream.java Tue Sep 04 15:29:13 2012 -0700 @@ -35,7 +35,7 @@ * * @author Brian Goetz */ -public interface Stream<T> extends Traversable<T> { +public interface Stream<T> { public enum Shape { LINEAR { @Override @@ -131,7 +131,7 @@ /** - * An aggregate that supports an {@code add(T)} operation. + * An aggregate that supports an {@code addAll(Stream)} operation. * * @param <T> Type of aggregate elements. */
--- a/src/share/classes/java/util/streams/StreamAccessor.java Tue Sep 04 14:14:34 2012 -0700 +++ b/src/share/classes/java/util/streams/StreamAccessor.java Tue Sep 04 15:29:13 2012 -0700 @@ -25,8 +25,6 @@ package java.util.streams; import java.util.Iterator; -import java.util.Spliterator; -import java.util.functions.Block; /** * StreamAccessor @@ -36,7 +34,7 @@ * @author Brian Goetz */ public interface StreamAccessor<T> { - void forEach(Block<? super T> sink); + void into(Sink<T, ?, ?> sink); Iterator<T> iterator();
--- a/src/share/classes/java/util/streams/Streams.java Tue Sep 04 14:14:34 2012 -0700 +++ b/src/share/classes/java/util/streams/Streams.java Tue Sep 04 15:29:13 2012 -0700 @@ -26,7 +26,6 @@ import java.util.*; import java.util.functions.BiBlock; -import java.util.functions.Block; /** * Streams @@ -92,7 +91,15 @@ } @Override - public void forEach(Block<? super T> block) { } + public Iterator<T> iterator() { + return Collections.emptyIterator(); + } + + @Override + public void into(Sink<T, ?, ?> sink) { + sink.begin(0); + sink.end(); + } @Override public int getRemainingSizeIfKnown() { @@ -103,16 +110,6 @@ public boolean isPredictableSplits() { return true; } - - @Override - public boolean hasNext() { - return false; - } - - @Override - public T next() { - throw new NoSuchElementException(); - } }; } @@ -133,9 +130,11 @@ } @Override - public void forEach(Block<? super T> block) { + public void into(Sink<T, ?, ?> sink) { + sink.begin(-1); while (it.hasNext()) - block.apply(it.next()); + sink.accept(it.next()); + sink.end(); } @Override @@ -182,8 +181,8 @@ } @Override - public void forEach(Block<? super T> block) { - spliterator.forEach(block); + public void into(Sink<T, ?, ?> sink) { + spliterator.into(sink); } @Override @@ -201,7 +200,7 @@ @Override public Iterator<T> iterator() { - return spliterator; + return spliterator.iterator(); } @Override @@ -248,15 +247,17 @@ } @Override - public void forEach(Block<? super T> block) { + public void into(Sink<T, ?, ?> sink) { + sink.begin(-1); if (iterator == null) { - traversable.forEach(block); + traversable.forEach(sink); iterator = Collections.emptyIterator(); } else { while (iterator.hasNext()) - block.apply(iterator.next()); + sink.accept(iterator.next()); } + sink.end(); } @Override @@ -309,14 +310,17 @@ } @Override - public void forEach(final Block<? super Mapping<K,V>> block) { + public void into(final Sink<Mapping<K,V>, ?, ?> sink) { + Sink<Mapping<K, V>, K, V> castSink = (Sink<Mapping<K, V>, K, V>) sink; if (iterator == null) { - traversable.forEach(block); + traversable.forEach(castSink); iterator = new MapIterator.IteratorAdapter<>(Collections.<Mapping<K,V>>emptyIterator()); } else { while (iterator.hasNext()) { - block.apply(iterator.next()); + K k = iterator.nextKey(); + V v = iterator.curValue(); + castSink.accept(k, v); } } }
--- a/src/share/classes/java/util/streams/ops/CumulateOp.java Tue Sep 04 14:14:34 2012 -0700 +++ b/src/share/classes/java/util/streams/ops/CumulateOp.java Tue Sep 04 15:29:13 2012 -0700 @@ -26,7 +26,7 @@ import java.util.Iterator; import java.util.Objects; -import java.util.Spliterator; +import java.util.streams.Spliterator; import java.util.concurrent.RecursiveTask; import java.util.functions.BinaryOperator; import java.util.streams.*; @@ -180,10 +180,7 @@ else { leafData = StreamBuilders.make(); StatefulSink<T, T> terminalSink = sink(leafData); - Sink<V, ?, ?> sink = problem.helper.sink(terminalSink); - sink.begin(-1); - source.forEach(sink); - sink.end(); + source.into(problem.helper.sink(terminalSink)); upward = terminalSink.getAndClearState(); // Special case -- if problem.depth == 0, just wrap the result and be done if (isRoot())
--- a/src/share/classes/java/util/streams/ops/FoldOp.java Tue Sep 04 14:14:34 2012 -0700 +++ b/src/share/classes/java/util/streams/ops/FoldOp.java Tue Sep 04 15:29:13 2012 -0700 @@ -24,10 +24,9 @@ */ package java.util.streams.ops; -import java.util.Spliterator; +import java.util.streams.Spliterator; import java.util.concurrent.RecursiveTask; import java.util.functions.*; -import java.util.streams.Sink; import java.util.streams.StatefulSink; /** @@ -108,10 +107,7 @@ } else { final StatefulSink<T, U> reduceStage = op.sink(); - final Sink<V, ?, ?> chain = helper.sink(reduceStage); - chain.begin(-1); - source.forEach(chain); - chain.end(); + source.into(helper.sink(reduceStage)); return reduceStage.getAndClearState(); } }
--- a/src/share/classes/java/util/streams/ops/ForEachOp.java Tue Sep 04 14:14:34 2012 -0700 +++ b/src/share/classes/java/util/streams/ops/ForEachOp.java Tue Sep 04 15:29:13 2012 -0700 @@ -26,7 +26,7 @@ import java.util.Mapping; import java.util.Objects; -import java.util.Spliterator; +import java.util.streams.Spliterator; import java.util.concurrent.RecursiveAction; import java.util.functions.BiBlock; import java.util.functions.Block; @@ -90,7 +90,7 @@ Sink<V, ?, ?> compoundSink = helper.sink(sink); Spliterator<V> spliterator = helper.spliterator(); if (depth == 0) { - spliterator.forEach(compoundSink); + spliterator.into(compoundSink); } else { helper.invoke(new ForEachTask<>(depth, spliterator, compoundSink)); } @@ -111,7 +111,7 @@ @Override protected void compute() { if (depth == 0) { - spliterator.forEach(sink); + spliterator.into(sink); } else { ForEachTask<T> left = new ForEachTask<>(depth - 1, spliterator.split(), sink); ForEachTask<T> right = new ForEachTask<>(depth - 1, spliterator, sink);
--- a/src/share/classes/java/util/streams/ops/ParallelOp.java Tue Sep 04 14:14:34 2012 -0700 +++ b/src/share/classes/java/util/streams/ops/ParallelOp.java Tue Sep 04 15:29:13 2012 -0700 @@ -25,7 +25,7 @@ package java.util.streams.ops; import java.util.Iterator; -import java.util.Spliterator; +import java.util.streams.Spliterator; import java.util.concurrent.ForkJoinTask; import java.util.streams.Sink;
--- a/src/share/classes/java/util/streams/ops/StatefulOp.java Tue Sep 04 14:14:34 2012 -0700 +++ b/src/share/classes/java/util/streams/ops/StatefulOp.java Tue Sep 04 15:29:13 2012 -0700 @@ -25,11 +25,7 @@ <Z> TreeUtils.Node<U> computeParallel(ParallelOpHelper<T, Z> helper) default { // dumb default serial implementation final StreamBuilder<U> sb = StreamBuilders.make(); - Sink<Z, ?, ?> sink = helper.sink(sink(sb)); - Spliterator<Z> spliterator = helper.spliterator(); - sink.begin(spliterator.getRemainingSizeIfKnown()); - spliterator.forEach(sink); - sink.end(); + helper.spliterator().into(helper.sink(sink(sb))); return TreeUtils.node(sb); } }
--- a/src/share/classes/java/util/streams/ops/TerminalOp.java Tue Sep 04 14:14:34 2012 -0700 +++ b/src/share/classes/java/util/streams/ops/TerminalOp.java Tue Sep 04 15:29:13 2012 -0700 @@ -25,8 +25,6 @@ package java.util.streams.ops; import java.util.Iterator; -import java.util.Spliterator; -import java.util.streams.Sink; import java.util.streams.StatefulSink; /** @@ -59,11 +57,7 @@ <V> U computeParallel(ParallelOpHelper<T, V> helper) default { // dumb default serial version StatefulSink<T, U> toArraySink = sink(); - Sink<V, ?, ?> sink = helper.sink(toArraySink); - Spliterator<V> spliterator = helper.spliterator(); - sink.begin(spliterator.getRemainingSizeIfKnown()); - spliterator.forEach(sink); - sink.end(); + helper.spliterator().into(helper.sink(toArraySink)); return toArraySink.getAndClearState(); } }
--- a/src/share/classes/java/util/streams/ops/ToArrayOp.java Tue Sep 04 14:14:34 2012 -0700 +++ b/src/share/classes/java/util/streams/ops/ToArrayOp.java Tue Sep 04 15:29:13 2012 -0700 @@ -35,6 +35,7 @@ public class ToArrayOp<T> implements TerminalOp<T, Object[]> { private final static ToArrayOp<?> INSTANCE = new ToArrayOp<>(); + private final static Object[] EMPTY_ARRAY = new Object[0]; @SuppressWarnings("unchecked") public static <T> ToArrayOp<T> singleton() { @@ -47,7 +48,7 @@ return new StatefulSink<T, Object[]>() { private static final int DEFAULT_CHUNK = 16; Object[] elements; - int count; + int count = 0; @Override public void begin(int size) { @@ -67,11 +68,16 @@ @Override public Object[] getAndClearState() { - Object[] result = (count == elements.length) - ? elements - : Arrays.copyOf(elements, count); - elements = null; - return result; + if (count == 0) + return EMPTY_ARRAY; + else { + Object[] result = (count == elements.length) + ? elements + : Arrays.copyOf(elements, count); + elements = null; + count = 0; + return result; + } } }; }
--- a/src/share/classes/java/util/streams/ops/TreeUtils.java Tue Sep 04 14:14:34 2012 -0700 +++ b/src/share/classes/java/util/streams/ops/TreeUtils.java Tue Sep 04 15:29:13 2012 -0700 @@ -53,18 +53,12 @@ // Need to account for SIZED flag from pipeline if (size != -1 && splitSizesKnown) { builder = StreamBuilders.makeFixed(size); - Sink sink = helper.sink(builder); - sink.begin(spliterator.getRemainingSizeIfKnown()); - spliterator.forEach(sink); - sink.end(); + spliterator.into(helper.sink(builder)); return node((T[]) builder.toArray()); } else { builder = StreamBuilders.make(); - Sink sink = helper.sink(builder); - sink.begin(spliterator.getRemainingSizeIfKnown()); - spliterator.forEach(sink); - sink.end(); + spliterator.into(helper.sink(builder)); return node(builder); } } @@ -122,7 +116,7 @@ if (depth == 0) { // @@@ Usual comment about using fixed stream builders if we know enough to do so StreamBuilder<U> builder = StreamBuilders.make(); - spliterator.forEach(helper.sink(builder)); + spliterator.into(helper.sink(builder)); return node(builder); } else { @@ -156,7 +150,7 @@ @Override protected void compute() { if (depth == 0) { - spliterator.forEach(helper.sink(Arrays.sink(array, offset, length))); + spliterator.into(helper.sink(Arrays.sink(array, offset, length))); } else { Spliterator<T> split = spliterator.split(); @@ -199,8 +193,10 @@ } } - public static interface Node<T> extends Traversable<T>, Streamable<T>, Splittable<T>, Sized { + public static interface Node<T> extends Traversable<T>, Streamable<T>, Sized, Iterable<T> { void copyTo(T[] array, int offset); + + Spliterator<T> spliterator(); } public static interface InternalNode<T> extends Node<T> { @@ -370,7 +366,7 @@ return String.format("IntNode[%s,%s]", left.toString(), right.toString()); } - private static class InternalNodeSpliterator<T> implements Spliterator<T> { + private static class InternalNodeSpliterator<T> implements Spliterator<T>, Iterator<T> { private Node<T> cur; private Iterator<T> iterator; @@ -378,7 +374,7 @@ this.cur = cur; } - private Iterator<T> iterator() { + public Iterator<T> iterator() { if (iterator == null) iterator = cur.iterator(); return iterator; @@ -399,15 +395,17 @@ } @Override - public void forEach(Block<? super T> block) { + public void into(Sink<T, ?, ?> sink) { + sink.begin(getRemainingSizeIfKnown()); if (iterator == null) { - cur.forEach(block); + cur.forEach(sink); iterator = Collections.emptyIterator(); } else { while (iterator.hasNext()) - block.apply(iterator.next()); + sink.accept(iterator.next()); } + sink.end(); } @Override
--- a/test-ng/tests/org/openjdk/tests/java/util/streams/ops/StreamOpTestCase.java Tue Sep 04 14:14:34 2012 -0700 +++ b/test-ng/tests/org/openjdk/tests/java/util/streams/ops/StreamOpTestCase.java Tue Sep 04 15:29:13 2012 -0700 @@ -516,7 +516,17 @@ @Override public void forEach(Block<? super Mapping<K,V>> block) { - map.forEach(block); + map.forEach((k, v) -> block.apply(new Mapping.AbstractMapping<K,V>() { + @Override + public K getKey() { + return k; + } + + @Override + public V getValue() { + return v; + } + })); } public void forEach(BiBlock<? super K, ? super V> block) {