ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/main/java/util/ArrayList.java
(Generate patch)

Comparing jsr166/src/main/java/util/ArrayList.java (file contents):
Revision 1.65 by jsr166, Sun Nov 11 16:27:28 2018 UTC vs.
Revision 1.71 by jsr166, Fri Jul 24 20:57:26 2020 UTC

# Line 1 | Line 1
1   /*
2 < * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.
2 > * Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved.
3   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4   *
5   * This code is free software; you can redistribute it and/or modify it
# Line 29 | Line 29 | import java.util.function.Consumer;
29   import java.util.function.Predicate;
30   import java.util.function.UnaryOperator;
31   // OPENJDK import jdk.internal.access.SharedSecrets;
32 + import jdk.internal.util.ArraysSupport;
33  
34   /**
35   * Resizable-array implementation of the {@code List} interface.  Implements
# Line 108 | Line 109 | import java.util.function.UnaryOperator;
109   public class ArrayList<E> extends AbstractList<E>
110          implements List<E>, RandomAccess, Cloneable, java.io.Serializable
111   {
112 +    // OPENJDK @java.io.Serial
113      private static final long serialVersionUID = 8683452581122892189L;
114  
115      /**
# Line 176 | Line 178 | public class ArrayList<E> extends Abstra
178       * @throws NullPointerException if the specified collection is null
179       */
180      public ArrayList(Collection<? extends E> c) {
181 <        elementData = c.toArray();
182 <        if ((size = elementData.length) != 0) {
183 <            // defend against c.toArray (incorrectly) not returning Object[]
184 <            // (see e.g. https://bugs.openjdk.java.net/browse/JDK-6260652)
185 <            if (elementData.getClass() != Object[].class)
186 <                elementData = Arrays.copyOf(elementData, size, Object[].class);
181 >        Object[] a = c.toArray();
182 >        if ((size = a.length) != 0) {
183 >            if (c.getClass() == ArrayList.class) {
184 >                elementData = a;
185 >            } else {
186 >                elementData = Arrays.copyOf(a, size, Object[].class);
187 >            }
188          } else {
189              // replace with empty array.
190 <            this.elementData = EMPTY_ELEMENTDATA;
190 >            elementData = EMPTY_ELEMENTDATA;
191          }
192      }
193  
# Line 219 | Line 222 | public class ArrayList<E> extends Abstra
222      }
223  
224      /**
222     * The maximum size of array to allocate (unless necessary).
223     * Some VMs reserve some header words in an array.
224     * Attempts to allocate larger arrays may result in
225     * OutOfMemoryError: Requested array size exceeds VM limit
226     */
227    private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
228
229    /**
225       * Increases the capacity to ensure that it can hold at least the
226       * number of elements specified by the minimum capacity argument.
227       *
# Line 234 | Line 229 | public class ArrayList<E> extends Abstra
229       * @throws OutOfMemoryError if minCapacity is less than zero
230       */
231      private Object[] grow(int minCapacity) {
232 <        return elementData = Arrays.copyOf(elementData,
233 <                                           newCapacity(minCapacity));
232 >        int oldCapacity = elementData.length;
233 >        if (oldCapacity > 0 || elementData != DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
234 >            int newCapacity = ArraysSupport.newLength(oldCapacity,
235 >                    minCapacity - oldCapacity, /* minimum growth */
236 >                    oldCapacity >> 1           /* preferred growth */);
237 >            return elementData = Arrays.copyOf(elementData, newCapacity);
238 >        } else {
239 >            return elementData = new Object[Math.max(DEFAULT_CAPACITY, minCapacity)];
240 >        }
241      }
242  
243      private Object[] grow() {
# Line 243 | Line 245 | public class ArrayList<E> extends Abstra
245      }
246  
247      /**
246     * Returns a capacity at least as large as the given minimum capacity.
247     * Returns the current capacity increased by 50% if that suffices.
248     * Will not return a capacity greater than MAX_ARRAY_SIZE unless
249     * the given minimum capacity is greater than MAX_ARRAY_SIZE.
250     *
251     * @param minCapacity the desired minimum capacity
252     * @throws OutOfMemoryError if minCapacity is less than zero
253     */
254    private int newCapacity(int minCapacity) {
255        // overflow-conscious code
256        int oldCapacity = elementData.length;
257        int newCapacity = oldCapacity + (oldCapacity >> 1);
258        if (newCapacity - minCapacity <= 0) {
259            if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA)
260                return Math.max(DEFAULT_CAPACITY, minCapacity);
261            if (minCapacity < 0) // overflow
262                throw new OutOfMemoryError();
263            return minCapacity;
264        }
265        return (newCapacity - MAX_ARRAY_SIZE <= 0)
266            ? newCapacity
267            : hugeCapacity(minCapacity);
268    }
269
270    private static int hugeCapacity(int minCapacity) {
271        if (minCapacity < 0) // overflow
272            throw new OutOfMemoryError();
273        return (minCapacity > MAX_ARRAY_SIZE)
274            ? Integer.MAX_VALUE
275            : MAX_ARRAY_SIZE;
276    }
277
278    /**
248       * Returns the number of elements in this list.
249       *
250       * @return the number of elements in this list
# Line 571 | Line 540 | public class ArrayList<E> extends Abstra
540          if (to > es.length) {
541              throw new ConcurrentModificationException();
542          }
543 <        Iterator<?> oit = other.iterator();
543 >        var oit = other.iterator();
544          for (; from < to; from++) {
545              if (!oit.hasNext() || !Objects.equals(es[from], oit.next())) {
546                  return false;
# Line 888 | Line 857 | public class ArrayList<E> extends Abstra
857       *             instance is emitted (int), followed by all of its elements
858       *             (each an {@code Object}) in the proper order.
859       */
860 +    // OPENJDK @java.io.Serial
861      private void writeObject(java.io.ObjectOutputStream s)
862          throws java.io.IOException {
863          // Write out element count, and any hidden stuff
# Line 915 | Line 885 | public class ArrayList<E> extends Abstra
885       *         could not be found
886       * @throws java.io.IOException if an I/O error occurs
887       */
888 +    // OPENJDK @java.io.Serial
889      private void readObject(java.io.ObjectInputStream s)
890          throws java.io.IOException, ClassNotFoundException {
891  
# Line 1169 | Line 1140 | public class ArrayList<E> extends Abstra
1140              this.parent = parent;
1141              this.offset = parent.offset + fromIndex;
1142              this.size = toIndex - fromIndex;
1143 <            this.modCount = root.modCount;
1143 >            this.modCount = parent.modCount;
1144          }
1145  
1146          public E set(int index, E element) {
# Line 1322 | Line 1293 | public class ArrayList<E> extends Abstra
1293              return new ListIterator<E>() {
1294                  int cursor = index;
1295                  int lastRet = -1;
1296 <                int expectedModCount = root.modCount;
1296 >                int expectedModCount = SubList.this.modCount;
1297  
1298                  public boolean hasNext() {
1299                      return cursor != SubList.this.size;
# Line 1366 | Line 1337 | public class ArrayList<E> extends Abstra
1337                          final Object[] es = root.elementData;
1338                          if (offset + i >= es.length)
1339                              throw new ConcurrentModificationException();
1340 <                        for (; i < size && modCount == expectedModCount; i++)
1340 >                        for (; i < size && root.modCount == expectedModCount; i++)
1341                              action.accept(elementAt(es, offset + i));
1342                          // update once at end to reduce heap write traffic
1343                          cursor = i;
# Line 1392 | Line 1363 | public class ArrayList<E> extends Abstra
1363                          SubList.this.remove(lastRet);
1364                          cursor = lastRet;
1365                          lastRet = -1;
1366 <                        expectedModCount = root.modCount;
1366 >                        expectedModCount = SubList.this.modCount;
1367                      } catch (IndexOutOfBoundsException ex) {
1368                          throw new ConcurrentModificationException();
1369                      }
# Line 1418 | Line 1389 | public class ArrayList<E> extends Abstra
1389                          SubList.this.add(i, e);
1390                          cursor = i + 1;
1391                          lastRet = -1;
1392 <                        expectedModCount = root.modCount;
1392 >                        expectedModCount = SubList.this.modCount;
1393                      } catch (IndexOutOfBoundsException ex) {
1394                          throw new ConcurrentModificationException();
1395                      }
# Line 1737 | Line 1708 | public class ArrayList<E> extends Abstra
1708      @Override
1709      public void replaceAll(UnaryOperator<E> operator) {
1710          replaceAllRange(operator, 0, size);
1711 +        // TODO(8203662): remove increment of modCount from ...
1712 +        modCount++;
1713      }
1714  
1715      private void replaceAllRange(UnaryOperator<E> operator, int i, int end) {

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines