changeset 6009:133fe0c08fa0

additional streams creation options.
author mduigou
date Thu, 13 Sep 2012 18:16:37 -0700
parents 5190b533ef2d
children 257bb5320a2b
files src/share/classes/java/util/streams/Stream.java src/share/classes/java/util/streams/Streams.java
diffstat 2 files changed, 74 insertions(+), 42 deletions(-) [+]
line wrap: on
line diff
--- a/src/share/classes/java/util/streams/Stream.java	Thu Sep 13 10:39:00 2012 -0700
+++ b/src/share/classes/java/util/streams/Stream.java	Thu Sep 13 18:16:37 2012 -0700
@@ -66,6 +66,12 @@
      */
     public static final int FLAG_UNKNOWN_MASK_V1 = ~(FLAG_DISTINCT | FLAG_SORTED | FLAG_SIZED);
 
+    /**
+     * Return the iterator for the elements of this stream. The same iterator
+     * instance is returned for every invocation.
+     *
+     * @return the element iterator for this stream.
+     */
     Iterator<T> iterator();
 
     boolean isParallel();
@@ -85,6 +91,11 @@
 
     Stream<T> cumulate(BinaryOperator<T> operator);
 
+    /**
+     * Apply the provided Block to each element of this stream. The e
+     *
+     * @param block
+     */
     void forEach(Block<? super T> block);
 
     Stream<T> tee(Block<? super T> block);
--- a/src/share/classes/java/util/streams/Streams.java	Thu Sep 13 10:39:00 2012 -0700
+++ b/src/share/classes/java/util/streams/Streams.java	Thu Sep 13 18:16:37 2012 -0700
@@ -37,50 +37,66 @@
         throw new Error("no instances");
     }
 
+    // MapStream
+
+    public static<K,V> MapStream<K,V> stream(SortedMap<K,V> source) {
+        return new MapPipeline<>(new MapTraversableMapStreamAccessor<>(source, true, true, source.size()));
+    }
+
+    public static<K,V> MapStream<K,V> stream(Map<K,V> source) {
+        return new MapPipeline<>(new MapTraversableMapStreamAccessor<>(source, true, false, source.size()));
+    }
+
     public static<K,V> MapStream<K,V> stream(MapTraversable<K,V> source) {
         return new MapPipeline<>(new MapTraversableMapStreamAccessor<>(source));
     }
 
-    public static<K,V> MapStream<K,V> stream(Map<K,V> source) {
-        return new MapPipeline<>(new MapTraversableMapStreamAccessor<>(source, source.size()));
+    // Stream
+
+    public static<T> Stream<T> stream(SortedSet<T> source) {
+        return new LinearPipeline<>(new TraversableStreamAccessor<>(source, true, true, source.size()));
+    }
+
+    public static<T> Stream<T> stream(Set<T> source) {
+        return new LinearPipeline<>(new TraversableStreamAccessor<>(source, true, false, source.size()));
     }
 
     public static<T> Stream<T> stream(Collection<T> source) {
-        return new LinearPipeline<>(new TraversableStreamAccessor<>(source, source.size()));
+        return new LinearPipeline<>(new TraversableStreamAccessor<>(source, false, false, source.size()));
+    }
+
+    public static<T> Stream<T> stream(Traversable<T> source, int knownSize) {
+        return new LinearPipeline<>(new TraversableStreamAccessor<>(source, false, false, knownSize));
     }
 
     public static<T> Stream<T> stream(Traversable<T> source) {
         return new LinearPipeline<>(new TraversableStreamAccessor<>(source));
     }
 
-    public static<T> Stream<T> stream(Traversable<T> source, int knownSize) {
-        return new LinearPipeline<>(new TraversableStreamAccessor<>(source, knownSize));
+    public static<T> Stream<T> stream(Iterable<T> source, int knownSize) {
+        return stream(source.iterator(), knownSize);
     }
 
     public static<T> Stream<T> stream(Iterable<T> source) {
         return stream(source.iterator());
     }
 
-    public static<T> Stream<T> stream(Iterable<T> source, int knownSize) {
-        return stream(source.iterator(), knownSize);
+    public static<T> Stream<T> stream(Iterator<T> source, int knownSize) {
+        return new LinearPipeline<>(new IteratorStreamAccessor<>(source, knownSize));
     }
 
     public static<T> Stream<T> stream(Iterator<T> source) {
         return new LinearPipeline<>(new IteratorStreamAccessor<>(source));
     }
 
-    public static<T> Stream<T> stream(Iterator<T> source, int knownSize) {
-        return new LinearPipeline<>(new IteratorStreamAccessor<>(source, knownSize));
+    public static<T> Stream<T> parallel(Spliterator<T> source, int knownSize) {
+        return new LinearPipeline<>(new SpliteratorStreamAccessor<>(source, knownSize));
     }
 
     public static<T> Stream<T> parallel(Spliterator<T> source) {
         return new LinearPipeline<>(new SpliteratorStreamAccessor<>(source));
     }
 
-    public static<T> Stream<T> parallel(Spliterator<T> source, int knownSize) {
-        return new LinearPipeline<>(new SpliteratorStreamAccessor<>(source, knownSize));
-    }
-
     // @@@ Need from(StreamAccessor) methods
 
     public static<T> Spliterator<T> emptySpliterator() {
@@ -121,21 +137,21 @@
     private static class IteratorStreamAccessor<T>
             implements StreamAccessor.ForSequential<T>, Iterator<T> {
         private final Iterator<T> it;
-        private final int size;
+        private final int sizeOrEstimate;
 
         public IteratorStreamAccessor(Iterator<T> it) {
             this.it = it;
-            this.size = -1;
+            this.sizeOrEstimate = Integer.MIN_VALUE;
         }
 
         public IteratorStreamAccessor(Iterator<T> it, int knownSize) {
             this.it = it;
-            this.size = knownSize;
+            this.sizeOrEstimate = knownSize;
         }
 
         @Override
         public void into(Sink<T, ?, ?> sink) {
-            sink.begin(-1);
+            sink.begin(getSizeOrEstimate());
             while (it.hasNext())
                 sink.accept(it.next());
             sink.end();
@@ -158,27 +174,27 @@
 
         @Override
         public int getStreamFlags() {
-            return (size >= 0) ? Stream.FLAG_SIZED : 0;
+            return (sizeOrEstimate >= 0) ? Stream.FLAG_SIZED : 0;
         }
 
         @Override
         public int getSizeOrEstimate() {
-            return (size >= 0) ? size : -1;
+            return sizeOrEstimate;
         }
     }
 
     static class SpliteratorStreamAccessor<T> implements StreamAccessor<T> {
         private final Spliterator<T> spliterator;
-        private final int size;
+        private final int sizeOrEstimate;
 
         public SpliteratorStreamAccessor(Spliterator<T> spliterator) {
             this.spliterator = spliterator;
-            this.size = -1;
+            this.sizeOrEstimate = Integer.MIN_VALUE;
         }
 
-        public SpliteratorStreamAccessor(Spliterator<T> spliterator, int knownSize) {
+        public SpliteratorStreamAccessor(Spliterator<T> spliterator, int sizeOrEstimate) {
             this.spliterator = spliterator;
-            this.size = knownSize;
+            this.sizeOrEstimate = sizeOrEstimate;
         }
 
         @Override
@@ -189,14 +205,14 @@
         @Override
         public int getStreamFlags() {
             int flags = 0;
-            if (size >= 0)
+            if (sizeOrEstimate >= 0)
                 flags |= Stream.FLAG_SIZED;
             return flags;
         }
 
         @Override
         public int getSizeOrEstimate() {
-            return (size >= 0) ? size : -Integer.MAX_VALUE;
+            return sizeOrEstimate;
         }
 
         @Override
@@ -228,17 +244,20 @@
     private static class TraversableStreamAccessor<T>
             implements StreamAccessor.ForSequential<T>, Iterator<T> {
         private final Traversable<T> traversable;
-        private final int size;
+        private final int flags;
+        private final int sizeOrEstimate;
         Iterator<T> iterator = null;
 
         TraversableStreamAccessor(Traversable<T> traversable) {
-            this.traversable = traversable;
-            this.size = -1;
+            this(traversable, false, false, Integer.MIN_VALUE);
         }
 
-        TraversableStreamAccessor(Traversable<T> traversable, int knownSize) {
+        TraversableStreamAccessor(Traversable<T> traversable, boolean sorted, boolean distinct, int sizeOrEstimate) {
             this.traversable = traversable;
-            this.size = knownSize;
+            this.flags = (distinct ? Stream.FLAG_DISTINCT : 0 ) |
+                        (sorted ? Stream.FLAG_SORTED : 0 ) |
+                        (sizeOrEstimate >= 0 ? Stream.FLAG_SIZED : 0);
+            this.sizeOrEstimate = sizeOrEstimate;
         }
 
         public Iterator<T> iterator() {
@@ -249,7 +268,7 @@
 
         @Override
         public void into(Sink<T, ?, ?> sink) {
-            sink.begin(-1);
+            sink.begin(getSizeOrEstimate());
             if (iterator == null) {
                 traversable.forEach(sink);
                 iterator = Collections.emptyIterator();
@@ -273,29 +292,32 @@
 
         @Override
         public int getStreamFlags() {
-            return (size >= 0) ? Stream.FLAG_SIZED : 0;
+            return flags;
         }
 
         @Override
         public int getSizeOrEstimate() {
-            return (size >= 0) ? size : -1;
+            return sizeOrEstimate;
         }
     }
 
     private static class MapTraversableMapStreamAccessor<K,V>
             implements MapStreamAccessor.ForSequential<K,V> {
         private final MapTraversable<K,V> traversable;
-        private final int size;
+        private final int flags;
+        private final int sizeOrEstimate;
         MapIterator<K,V> iterator = null;
 
         MapTraversableMapStreamAccessor(MapTraversable<K,V> traversable) {
-            this.traversable = traversable;
-            this.size = -1;
+            this(traversable, false, false, Integer.MIN_VALUE);
         }
 
-        MapTraversableMapStreamAccessor(MapTraversable<K,V> traversable, int knownSize) {
+        MapTraversableMapStreamAccessor(MapTraversable<K,V> traversable, boolean distinct, boolean sorted, int sizeOrEstimate) {
             this.traversable = traversable;
-            this.size = knownSize;
+            this.flags = (distinct ? Stream.FLAG_DISTINCT : 0 ) |
+                        (sorted ? Stream.FLAG_SORTED : 0 ) |
+                        (sizeOrEstimate >= 0 ? Stream.FLAG_SIZED : 0);
+            this.sizeOrEstimate = sizeOrEstimate;
         }
 
         @Override
@@ -327,8 +349,7 @@
             if (iterator == null) {
                 traversable.forEach(block);
                 iterator = new MapIterator.IteratorAdapter<>(Collections.<Mapping<K,V>>emptyIterator());
-            }
-            else {
+            } else {
                 while (iterator.hasNext()) {
                     block.apply(iterator.nextKey(), iterator.curValue());
                 }
@@ -347,12 +368,12 @@
 
         @Override
         public int getStreamFlags() {
-            return (size >= 0) ? Stream.FLAG_SIZED : 0;
+            return flags;
         }
 
         @Override
         public int getSizeOrEstimate() {
-            return (size >= 0) ? size : -1;
+            return sizeOrEstimate;
         }
 
         @Override