changeset 7709:3de950fdd0e7

SingletonSpliterator and more Collections default method override
author henryjen
date Thu, 21 Mar 2013 22:29:18 -0700
parents 535ad014c417
children 825b22c34755
files src/share/classes/java/util/Collections.java src/share/classes/java/util/Spliterators.java
diffstat 2 files changed, 365 insertions(+), 2 deletions(-) [+]
line wrap: on
line diff
--- a/src/share/classes/java/util/Collections.java	Thu Mar 21 17:50:48 2013 +0100
+++ b/src/share/classes/java/util/Collections.java	Thu Mar 21 22:29:18 2013 -0700
@@ -35,6 +35,7 @@
 import java.util.function.Predicate;
 import java.util.function.UnaryOperator;
 import java.util.stream.Stream;
+import java.util.stream.Streams;
 
 /**
  * This class consists exclusively of static methods that operate on or return
@@ -2819,6 +2820,11 @@
                     typeCheck(e);
                     i.add(e);
                 }
+
+                @Override
+                public void forEach(Consumer<? super E> action) {
+                    i.forEach(action);
+                }
             };
         }
 
@@ -2842,7 +2848,7 @@
         public List<E> subList(int fromIndex, int toIndex) {
             return new CheckedRandomAccessList<>(
                 list.subList(fromIndex, toIndex), type);
-        }
+            }
     }
 
     /**
@@ -3484,6 +3490,12 @@
             return a;
         }
 
+        // Override default methods in Collection
+        @Override
+        public void forEach(Consumer<? super E> action) {}
+        @Override
+        public Spliterator<E> spliterator() { return Spliterators.emptySpliterator(); }
+
         // Preserves singleton property
         private Object readResolve() {
             return EMPTY_SET;
@@ -3591,6 +3603,12 @@
         public E last() {
             throw new NoSuchElementException();
         }
+
+        // Override default methods in Collection
+        @Override
+        public void forEach(Consumer<? super E> action) {}
+        @Override
+        public Spliterator<E> spliterator() { return Spliterators.emptySpliterator(); }
     }
 
     /**
@@ -3660,6 +3678,12 @@
 
         public int hashCode() { return 1; }
 
+        // Override default methods in Collection
+        @Override
+        public void forEach(Consumer<? super E> action) {}
+        @Override
+        public Spliterator<E> spliterator() { return Spliterators.emptySpliterator(); }
+
         // Preserves singleton property
         private Object readResolve() {
             return EMPTY_LIST;
@@ -3719,6 +3743,64 @@
 
         public int hashCode()                      {return 0;}
 
+        // Override default methods in Map
+        @Override
+        @SuppressWarnings("unchecked")
+        public V getOrDefault(Object k, V defaultValue) {
+            return defaultValue;
+        }
+
+        @Override
+        public void forEach(BiConsumer<? super K, ? super V> action) {}
+
+        @Override
+        public void replaceAll(BiFunction<? super K, ? super V, ? extends V> function) {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public V putIfAbsent(K key, V value) {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public boolean remove(Object key, Object value) {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public boolean replace(K key, V oldValue, V newValue) {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public V replace(K key, V value) {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public V computeIfAbsent(K key, Function<? super K, ? extends V> mappingFunction) {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public V computeIfPresent(K key,
+                        BiFunction<? super K, ? super V, ? extends V> remappingFunction) {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public V compute(K key,
+                        BiFunction<? super K, ? super V, ? extends V> remappingFunction) {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public V merge(K key, V value,
+                        BiFunction<? super V, ? super V, ? extends V> remappingFunction) {
+            throw new UnsupportedOperationException();
+        }
+
         // Preserves singleton property
         private Object readResolve() {
             return EMPTY_MAP;
@@ -3756,7 +3838,10 @@
             }
             @Override
             public void forEach(Consumer<? super E> action) {
-                action.accept(e);
+                if (hasNext) {
+                    action.accept(e);
+                    hasNext = false;
+                }
             }
         };
     }
@@ -3781,6 +3866,17 @@
         public int size() {return 1;}
 
         public boolean contains(Object o) {return eq(o, element);}
+
+        // Override default methods for Collection
+        @Override
+        public void forEach(Consumer<? super E> action) {
+            action.accept(element);
+        }
+
+        @Override
+        public Spliterator<E> spliterator() {
+            return Spliterators.singletonSpliterator(element);
+        }
     }
 
     /**
@@ -3821,6 +3917,17 @@
               throw new IndexOutOfBoundsException("Index: "+index+", Size: 1");
             return element;
         }
+
+        // Override default methods for Collection
+        @Override
+        public void forEach(Consumer<? super E> action) {
+            action.accept(element);
+        }
+
+        @Override
+        public Spliterator<E> spliterator() {
+            return Spliterators.singletonSpliterator(element);
+        }
     }
 
     /**
@@ -3886,6 +3993,64 @@
             return values;
         }
 
+        // Override default methods in Map
+        @Override
+        public V getOrDefault(Object key, V defaultValue) {
+            return eq(key, k) ? v : defaultValue;
+        }
+
+        @Override
+        public void forEach(BiConsumer<? super K, ? super V> action) {
+            action.accept(k, v);
+        }
+
+        @Override
+        public void replaceAll(BiFunction<? super K, ? super V, ? extends V> function) {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public V putIfAbsent(K key, V value) {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public boolean remove(Object key, Object value) {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public boolean replace(K key, V oldValue, V newValue) {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public V replace(K key, V value) {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public V computeIfAbsent(K key, Function<? super K, ? extends V> mappingFunction) {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public V computeIfPresent(K key,
+                        BiFunction<? super K, ? super V, ? extends V> remappingFunction) {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public V compute(K key,
+                        BiFunction<? super K, ? super V, ? extends V> remappingFunction) {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public V merge(K key, V value,
+                        BiFunction<? super V, ? super V, ? extends V> remappingFunction) {
+            throw new UnsupportedOperationException();
+        }
     }
 
     // Miscellaneous
@@ -3985,6 +4150,22 @@
                                                    ") > toIndex(" + toIndex + ")");
             return new CopiesList<>(toIndex - fromIndex, element);
         }
+
+        // Override default methods in Collection
+        @Override
+        public Stream<E> stream() {
+            return Streams.intRange(0, n).map(i -> element);
+        }
+
+        @Override
+        public Stream<E> parallelStream() {
+            return Streams.intRange(0, n).parallel().map(i -> element);
+        }
+
+        @Override
+        public Spliterator<E> spliterator() {
+            return stream().spliterator();
+        }
     }
 
     /**
@@ -4360,6 +4541,20 @@
         public boolean retainAll(Collection<?> c)   {return s.retainAll(c);}
         // addAll is the only inherited implementation
 
+        // Override default methods in Collection
+        @Override
+        public void forEach(Consumer<? super E> action) {s.forEach(action);}
+        @Override
+        public boolean removeAll(Predicate<? super E> filter) {
+            return s.removeAll(filter);
+        }
+        @Override
+        public Spliterator<E> spliterator() {return s.spliterator();}
+        @Override
+        public Stream<E> stream()           {return s.stream();}
+        @Override
+        public Stream<E> parallelStream()   {return s.parallelStream();}
+
         private static final long serialVersionUID = 2454657854757543876L;
 
         private void readObject(java.io.ObjectInputStream stream)
@@ -4418,5 +4613,19 @@
         public boolean removeAll(Collection<?> c)   {return q.removeAll(c);}
         public boolean retainAll(Collection<?> c)   {return q.retainAll(c);}
         // We use inherited addAll; forwarding addAll would be wrong
+
+        // Override default methods in Collection
+        @Override
+        public void forEach(Consumer<? super E> action) {q.forEach(action);}
+        @Override
+        public boolean removeAll(Predicate<? super E> filter) {
+            return q.removeAll(filter);
+        }
+        @Override
+        public Spliterator<E> spliterator() {return q.spliterator();}
+        @Override
+        public Stream<E> stream()           {return q.stream();}
+        @Override
+        public Stream<E> parallelStream()   {return q.parallelStream();}
     }
 }
--- a/src/share/classes/java/util/Spliterators.java	Thu Mar 21 17:50:48 2013 +0100
+++ b/src/share/classes/java/util/Spliterators.java	Thu Mar 21 22:29:18 2013 -0700
@@ -82,6 +82,45 @@
         return new EmptySpliterator.OfDouble();
     }
 
+    // Singleton spliterators
+
+    /**
+     * Creates a {@code Spliterator} with only the specified element
+     *
+     * @param <T> Type of elements
+     * @return A singleton {@code Spliterator}
+     */
+    public static <T> Spliterator<T> singletonSpliterator(T element) {
+        return new SingletonSpliterator<>(element);
+    }
+
+    /**
+     * Creates a {@code Spliterator.OfInt} with only the specified value
+     *
+     * @return A singleton {@code Spliterator.OfInt}
+     */
+    public static Spliterator.OfInt singletonIntSpliterator(int value) {
+        return new SingletonSpliterator.OfInt(value);
+    }
+
+    /**
+     * Creates a {@code Spliterator.OfLong} with only the specified value
+     *
+     * @return A singleton {@code Spliterator.OfLong}
+     */
+    public static Spliterator.OfLong singletonLongSpliterator(long value) {
+        return new SingletonSpliterator.OfLong(value);
+    }
+
+    /**
+     * Creates a {@code Spliterator.OfDouble} with only the specified value
+     *
+     * @return A singleton {@code Spliterator.OfDouble}
+     */
+    public static Spliterator.OfDouble singletonDoubleSpliterator(double value) {
+        return new SingletonSpliterator.OfDouble(value);
+    }
+
     // Array-based spliterators
 
     /**
@@ -606,6 +645,121 @@
         }
     }
 
+    private static class SingletonSpliterator<T> implements Spliterator<T> {
+        private final T element;
+        protected boolean consumed;
+
+        SingletonSpliterator(T element) { this.element = element; }
+
+        @Override
+        public Spliterator<T> trySplit() {
+            return null;
+        }
+
+        @Override
+        public boolean tryAdvance(Consumer<? super T> consumer) {
+            if (!consumed) {
+                consumed = true;
+                consumer.accept(element);
+                return true;
+            }
+            return false;
+        }
+
+        @Override
+        public void forEach(Consumer<? super T> consumer) {
+            tryAdvance(consumer);
+        }
+
+        @Override
+        public long estimateSize() {
+            return 1;
+        }
+
+        @Override
+        public int characteristics() {
+            return Spliterator.SIZED | Spliterator.SUBSIZED;
+        }
+
+        private static final class OfInt extends SingletonSpliterator<Integer> implements Spliterator.OfInt {
+            private final int value;
+
+            OfInt(int v) { super(v); value = v; }
+
+            @Override
+            public Spliterator.OfInt trySplit() {
+                return null;
+            }
+
+            @Override
+            public boolean tryAdvance(IntConsumer consumer) {
+                if (!consumed) {
+                    consumed = true;
+                    consumer.accept(value);
+                    return true;
+                }
+                return false;
+            }
+
+            @Override
+            public void forEach(IntConsumer consumer) {
+                tryAdvance(consumer);
+            }
+        }
+
+        private static final class OfLong extends SingletonSpliterator<Long> implements Spliterator.OfLong {
+            private final long value;
+
+            OfLong(long v) { super(v); value = v; }
+
+            @Override
+            public Spliterator.OfLong trySplit() {
+                return null;
+            }
+
+            @Override
+            public boolean tryAdvance(LongConsumer consumer) {
+                if (!consumed) {
+                    consumed = true;
+                    consumer.accept(value);
+                    return true;
+                }
+                return false;
+            }
+
+            @Override
+            public void forEach(LongConsumer consumer) {
+                tryAdvance(consumer);
+            }
+        }
+
+        private static final class OfDouble extends SingletonSpliterator<Double> implements Spliterator.OfDouble {
+            private final double value;
+
+            OfDouble(double v) { super(v); value = v; }
+
+            @Override
+            public Spliterator.OfDouble trySplit() {
+                return null;
+            }
+
+            @Override
+            public boolean tryAdvance(DoubleConsumer consumer) {
+                if (!consumed) {
+                    consumed = true;
+                    consumer.accept(value);
+                    return true;
+                }
+                return false;
+            }
+
+            @Override
+            public void forEach(DoubleConsumer consumer) {
+                tryAdvance(consumer);
+            }
+        }
+    }
+
     // Array-based spliterators
 
     /**