changeset 7747:1803c6e666dc

update default collection methods and their overrides
author akhil
date Tue, 26 Mar 2013 15:24:54 -0700
parents 88741a0bec11
children f5b67786b6c9
files src/share/classes/java/util/ArrayList.java src/share/classes/java/util/Collection.java src/share/classes/java/util/Collections.java src/share/classes/java/util/List.java src/share/classes/java/util/Vector.java src/share/classes/java/util/concurrent/CopyOnWriteArrayList.java
diffstat 6 files changed, 85 insertions(+), 42 deletions(-) [+]
line wrap: on
line diff
--- a/src/share/classes/java/util/ArrayList.java	Tue Mar 26 21:55:39 2013 +0100
+++ b/src/share/classes/java/util/ArrayList.java	Tue Mar 26 15:24:54 2013 -0700
@@ -1162,29 +1162,35 @@
     }
 
     @Override
-    public void forEach(Consumer<? super E> consumer) {
-        int expectedModCount = modCount;
+    public void forEach(Consumer<? super E> action) {
+        Objects.requireNonNull(action);
+        final int expectedModCount = modCount;
         @SuppressWarnings("unchecked")
-        E[] elementData = (E[]) this.elementData;
-        int size = this.size;
-        for (int i=0; modCount == expectedModCount && i<size; i++)
-            consumer.accept(elementData[i]);
+        final E[] elementData = (E[]) this.elementData;
+        final int size = this.size;
+        for (int i=0; modCount == expectedModCount && i < size; i++) {
+            action.accept(elementData[i]);
+        }
         if (modCount != expectedModCount)
             throw new ConcurrentModificationException();
     }
 
     @Override
     public boolean removeAll(Predicate<? super E> filter) {
+        Objects.requireNonNull(filter);
         // figure out which elements are to be removed
         // any exception thrown from the filter predicate at this stage
         // will leave the collection unmodified
+        int removeCount = 0;
         final BitSet removeSet = new BitSet(size);
         final int expectedModCount = modCount;
+        final int size = this.size;
         for (int i=0; modCount == expectedModCount && i < size; i++) {
             @SuppressWarnings("unchecked")
             final E element = (E) elementData[i];
             if (filter.test(element)) {
                 removeSet.set(i);
+                removeCount++;
             }
         }
 
@@ -1193,17 +1199,18 @@
         }
 
         // shift surviving elements left over the spaces left by removed elements
-        final boolean anyToRemove = (removeSet != null) && !removeSet.isEmpty();
+        final boolean anyToRemove = removeCount > 0;
         if (anyToRemove) {
-            final int newSize = size - removeSet.cardinality();
-            for (int i=0, j=0; (i < size) && (j < newSize); i++, j++) {
+            final int newSize = size - removeCount;
+            for (int i=0, j=0; modCount == expectedModCount &&
+                    (i < size) && (j < newSize); i++, j++) {
                 i = removeSet.nextClearBit(i);
                 elementData[j] = elementData[i];
             }
-            for (int k=newSize; k < size; k++) {
+            for (int k=newSize; modCount == expectedModCount && k < size; k++) {
                 elementData[k] = null;  // Let gc do its work
             }
-            size = newSize;
+            this.size = newSize;
             if (modCount != expectedModCount) {
                 throw new ConcurrentModificationException();
             }
@@ -1218,6 +1225,7 @@
     public void replaceAll(UnaryOperator<E> operator) {
         Objects.requireNonNull(operator);
         final int expectedModCount = modCount;
+        final int size = this.size;
         for (int i=0; modCount == expectedModCount && i < size; i++) {
             elementData[i] = operator.apply((E) elementData[i]);
         }
--- a/src/share/classes/java/util/Collection.java	Tue Mar 26 21:55:39 2013 +0100
+++ b/src/share/classes/java/util/Collection.java	Tue Mar 26 15:24:54 2013 -0700
@@ -390,20 +390,21 @@
      * @param filter a predicate which returns {@code true} for elements to be
      *        removed
      * @return {@code true} if any elements were removed
+     * @throws NullPointerException if the specified filter is null
      * @throws UnsupportedOperationException if the <code>removeAll</code>
      *         method is not supported by this collection
      * @since 1.8
      */
     default boolean removeAll(Predicate<? super E> filter) {
+        Objects.requireNonNull(filter);
         boolean removed = false;
-        Iterator<E> each = iterator();
+        final Iterator<E> each = iterator();
         while (each.hasNext()) {
             if (filter.test(each.next())) {
                 each.remove();
                 removed = true;
             }
         }
-
         return removed;
     }
 
--- a/src/share/classes/java/util/Collections.java	Tue Mar 26 21:55:39 2013 +0100
+++ b/src/share/classes/java/util/Collections.java	Tue Mar 26 15:24:54 2013 -0700
@@ -1266,6 +1266,12 @@
         public boolean addAll(int index, Collection<? extends E> c) {
             throw new UnsupportedOperationException();
         }
+        public void replaceAll(UnaryOperator<E> operator) {
+            throw new UnsupportedOperationException();
+        }
+        public void sort(Comparator<? super E> c) {
+            throw new UnsupportedOperationException();
+        }
         public ListIterator<E> listIterator()   {return listIterator(0);}
 
         public ListIterator<E> listIterator(final int index) {
--- a/src/share/classes/java/util/List.java	Tue Mar 26 21:55:39 2013 +0100
+++ b/src/share/classes/java/util/List.java	Tue Mar 26 15:24:54 2013 -0700
@@ -396,12 +396,14 @@
      * @param operator the operator to apply to each element
      * @throws UnsupportedOperationException if the <code>replaceAll</code>
      *         operation is not supported by this list
+     * @throws NullPointerException if the specified operator is null
      * @throws NullPointerException if the an element is replaced with a null
-     *         value this list does not permit null elements
+     *         value and this list does not permit null elements
      * (<a href="Collection.html#optional-restrictions">optional</a>)
      * @since 1.8
      */
     default void replaceAll(UnaryOperator<E> operator) {
+        Objects.requireNonNull(operator);
         final ListIterator<E> li = this.listIterator();
         while (li.hasNext()) {
             li.set(operator.apply(li.next()));
@@ -417,6 +419,7 @@
      *
      * @param c the {@code Comparator} used to compare list elements
      * @since 1.8
+     * @throws NullPointerException if the specified comparator is null
      * @throws ClassCastException if the list contains elements that are not
      *         <i>mutually comparable</i> using the specified comparator.
      * @throws UnsupportedOperationException if the list's list-iterator does
@@ -425,6 +428,7 @@
      *         found to violate the {@link Comparator} contract
      */
     default void sort(Comparator<? super E> c) {
+        Objects.requireNonNull(c);
         Collections.sort(this, c);
     }
 
--- a/src/share/classes/java/util/Vector.java	Tue Mar 26 21:55:39 2013 +0100
+++ b/src/share/classes/java/util/Vector.java	Tue Mar 26 15:24:54 2013 -0700
@@ -1237,11 +1237,15 @@
     }
 
     @Override
-    public synchronized void forEach(Consumer<? super E> consumer) {
-        E[] elementData = (E[]) this.elementData;
-        int expectedModCount = modCount;
-        for (int i=0; modCount == expectedModCount && i<elementCount; i++)
-            consumer.accept(elementData[i]);
+    public synchronized void forEach(Consumer<? super E> action) {
+        Objects.requireNonNull(action);
+        final int expectedModCount = modCount;
+        @SuppressWarnings("unchecked")
+        final E[] elementData = (E[]) this.elementData;
+        final int elementCount = this.elementCount;
+        for (int i=0; modCount == expectedModCount && i < elementCount; i++) {
+            action.accept(elementData[i]);
+        }
         if (modCount != expectedModCount)
             throw new ConcurrentModificationException();
     }
@@ -1249,22 +1253,20 @@
     @Override
     @SuppressWarnings("unchecked")
     public synchronized boolean removeAll(Predicate<? super E> filter) {
-        // cannot use BitSet to save removed indices
-        // because of circular class dependencies
-
+        Objects.requireNonNull(filter);
+        // figure out which elements are to be removed
         // any exception thrown from the filter predicate at this stage
         // will leave the collection unmodified
-        final Object[] newElementData = new Object[elementCount];
+        int removeCount = 0;
+        final int size = elementCount;
+        final BitSet removeSet = new BitSet(size);
         final int expectedModCount = modCount;
-        boolean removed = false;
-        int j = 0;
-        for (int i=0; modCount == expectedModCount && i < elementCount; i++) {
+        for (int i=0; modCount == expectedModCount && i < size; i++) {
             @SuppressWarnings("unchecked")
             final E element = (E) elementData[i];
             if (filter.test(element)) {
-                removed = true;
-            } else {
-                newElementData[j++] = element;
+                removeSet.set(i);
+                removeCount++;
             }
         }
 
@@ -1272,13 +1274,26 @@
             throw new ConcurrentModificationException();
         }
 
-        if (removed) {
-            elementData = newElementData;
-            setSize(j);
+        // shift surviving elements left over the spaces left by removed elements
+        final boolean anyToRemove = removeCount > 0;
+        if (anyToRemove) {
+            final int newSize = size - removeCount;
+            for (int i=0, j=0; modCount == expectedModCount &&
+                    (i < size) && (j < newSize); i++, j++) {
+                i = removeSet.nextClearBit(i);
+                elementData[j] = elementData[i];
+            }
+            for (int k=newSize; modCount == expectedModCount && k < size; k++) {
+                elementData[k] = null;  // Let gc do its work
+            }
+            elementCount = newSize;
+            if (modCount != expectedModCount) {
+                throw new ConcurrentModificationException();
+            }
             modCount++;
         }
 
-        return removed;
+        return anyToRemove;
     }
 
     @Override
--- a/src/share/classes/java/util/concurrent/CopyOnWriteArrayList.java	Tue Mar 26 21:55:39 2013 +0100
+++ b/src/share/classes/java/util/concurrent/CopyOnWriteArrayList.java	Tue Mar 26 15:24:54 2013 -0700
@@ -54,6 +54,7 @@
 import java.util.List;
 import java.util.ListIterator;
 import java.util.NoSuchElementException;
+import java.util.Objects;
 import java.util.RandomAccess;
 import java.util.Spliterator;
 import java.util.Spliterators;
@@ -1377,21 +1378,24 @@
     }
 
     @SuppressWarnings("unchecked")
-    public void forEach(Consumer<? super E> consumer) {
+    @Override
+    public void forEach(Consumer<? super E> action) {
+        Objects.requireNonNull(action);
         final Object[] elements = getArray();
         for (final Object element : elements) {
-            consumer.accept((E) element);
+            action.accept((E) element);
         }
     }
 
     @Override
     public void sort(Comparator<? super E> c) {
+        Objects.requireNonNull(c);
         final ReentrantLock lock = this.lock;
         lock.lock();
         try {
             @SuppressWarnings("unchecked")
-            E[] elements = (E[]) getArray();
-            E[] newElements = Arrays.copyOf(elements, elements.length);
+            final E[] elements = (E[]) getArray();
+            final E[] newElements = Arrays.copyOf(elements, elements.length);
             Arrays.sort(newElements, c);
             setArray(newElements);
         } finally {
@@ -1401,29 +1405,33 @@
 
     @Override
     public boolean removeAll(Predicate<? super E> filter) {
+        Objects.requireNonNull(filter);
         final ReentrantLock lock = this.lock;
         lock.lock();
         try {
             @SuppressWarnings("unchecked")
             final E[] elements = (E[]) getArray();
+            final int size = elements.length;
 
             // figure out which elements are to be removed
             // any exception thrown from the filter predicate at this stage
             // will leave the collection unmodified
-            final BitSet removeSet = new BitSet(elements.length);
-            for (int i=0; i < elements.length; i++) {
+            int removeCount = 0;
+            final BitSet removeSet = new BitSet(size);
+            for (int i=0; i < size; i++) {
                 final E element = elements[i];
                 if (filter.test(element)) {
                     removeSet.set(i);
+                    removeCount++;
                 }
             }
 
             // copy surviving elements into a new array
-            final boolean anyToRemove = (removeSet != null) && !removeSet.isEmpty();
+            final boolean anyToRemove = removeCount > 0;
             if (anyToRemove) {
-                final int newSize = elements.length - removeSet.cardinality();
+                final int newSize = elements.length - removeCount;
                 final Object[] newElements = new Object[newSize];
-                for (int i=0, j=0; (i < elements.length) && (j < newSize); i++, j++) {
+                for (int i=0, j=0; (i < size) && (j < newSize); i++, j++) {
                     i = removeSet.nextClearBit(i);
                     newElements[j] = elements[i];
                 }
@@ -1438,6 +1446,7 @@
 
     @Override
     public void replaceAll(UnaryOperator<E> operator) {
+        Objects.requireNonNull(operator);
         final ReentrantLock lock = this.lock;
         lock.lock();
         try {