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.54 by jsr166, Sun Oct 22 17:44:03 2017 UTC vs.
Revision 1.69 by jsr166, Fri Aug 30 18:05:39 2019 UTC

# Line 1 | Line 1
1   /*
2 < * Copyright (c) 1997, 2017, 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 28 | Line 28 | package java.util;
28   import java.util.function.Consumer;
29   import java.util.function.Predicate;
30   import java.util.function.UnaryOperator;
31 < import jdk.internal.misc.SharedSecrets;
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 92 | Line 93 | import jdk.internal.misc.SharedSecrets;
93   * should be used only to detect bugs.</i>
94   *
95   * <p>This class is a member of the
96 < * <a href="{@docRoot}/java/util/package-summary.html#CollectionsFramework">
96 > * <a href="{@docRoot}/java.base/java/util/package-summary.html#CollectionsFramework">
97   * Java Collections Framework</a>.
98   *
99   * @param <E> the type of elements in this list
# Line 108 | Line 109 | import jdk.internal.misc.SharedSecrets;
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 219 | Line 221 | public class ArrayList<E> extends Abstra
221      }
222  
223      /**
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    /**
224       * Increases the capacity to ensure that it can hold at least the
225       * number of elements specified by the minimum capacity argument.
226       *
# Line 234 | Line 228 | public class ArrayList<E> extends Abstra
228       * @throws OutOfMemoryError if minCapacity is less than zero
229       */
230      private Object[] grow(int minCapacity) {
231 <        return elementData = Arrays.copyOf(elementData,
232 <                                           newCapacity(minCapacity));
231 >        int oldCapacity = elementData.length;
232 >        if (oldCapacity > 0 || elementData != DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
233 >            int newCapacity = ArraysSupport.newLength(oldCapacity,
234 >                    minCapacity - oldCapacity, /* minimum growth */
235 >                    oldCapacity >> 1           /* preferred growth */);
236 >            return elementData = Arrays.copyOf(elementData, newCapacity);
237 >        } else {
238 >            return elementData = new Object[Math.max(DEFAULT_CAPACITY, minCapacity)];
239 >        }
240      }
241  
242      private Object[] grow() {
# Line 243 | Line 244 | public class ArrayList<E> extends Abstra
244      }
245  
246      /**
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    /**
247       * Returns the number of elements in this list.
248       *
249       * @return the number of elements in this list
# Line 314 | Line 282 | public class ArrayList<E> extends Abstra
282       * or -1 if there is no such index.
283       */
284      public int indexOf(Object o) {
285 +        return indexOfRange(o, 0, size);
286 +    }
287 +
288 +    int indexOfRange(Object o, int start, int end) {
289 +        Object[] es = elementData;
290          if (o == null) {
291 <            for (int i = 0; i < size; i++)
292 <                if (elementData[i]==null)
291 >            for (int i = start; i < end; i++) {
292 >                if (es[i] == null) {
293                      return i;
294 +                }
295 +            }
296          } else {
297 <            for (int i = 0; i < size; i++)
298 <                if (o.equals(elementData[i]))
297 >            for (int i = start; i < end; i++) {
298 >                if (o.equals(es[i])) {
299                      return i;
300 +                }
301 +            }
302          }
303          return -1;
304      }
# Line 334 | Line 311 | public class ArrayList<E> extends Abstra
311       * or -1 if there is no such index.
312       */
313      public int lastIndexOf(Object o) {
314 +        return lastIndexOfRange(o, 0, size);
315 +    }
316 +
317 +    int lastIndexOfRange(Object o, int start, int end) {
318 +        Object[] es = elementData;
319          if (o == null) {
320 <            for (int i = size-1; i >= 0; i--)
321 <                if (elementData[i]==null)
320 >            for (int i = end - 1; i >= start; i--) {
321 >                if (es[i] == null) {
322                      return i;
323 +                }
324 +            }
325          } else {
326 <            for (int i = size-1; i >= 0; i--)
327 <                if (o.equals(elementData[i]))
326 >            for (int i = end - 1; i >= start; i--) {
327 >                if (o.equals(es[i])) {
328                      return i;
329 +                }
330 +            }
331          }
332          return -1;
333      }
# Line 526 | Line 512 | public class ArrayList<E> extends Abstra
512      }
513  
514      /**
515 +     * {@inheritDoc}
516 +     */
517 +    public boolean equals(Object o) {
518 +        if (o == this) {
519 +            return true;
520 +        }
521 +
522 +        if (!(o instanceof List)) {
523 +            return false;
524 +        }
525 +
526 +        final int expectedModCount = modCount;
527 +        // ArrayList can be subclassed and given arbitrary behavior, but we can
528 +        // still deal with the common case where o is ArrayList precisely
529 +        boolean equal = (o.getClass() == ArrayList.class)
530 +            ? equalsArrayList((ArrayList<?>) o)
531 +            : equalsRange((List<?>) o, 0, size);
532 +
533 +        checkForComodification(expectedModCount);
534 +        return equal;
535 +    }
536 +
537 +    boolean equalsRange(List<?> other, int from, int to) {
538 +        final Object[] es = elementData;
539 +        if (to > es.length) {
540 +            throw new ConcurrentModificationException();
541 +        }
542 +        var oit = other.iterator();
543 +        for (; from < to; from++) {
544 +            if (!oit.hasNext() || !Objects.equals(es[from], oit.next())) {
545 +                return false;
546 +            }
547 +        }
548 +        return !oit.hasNext();
549 +    }
550 +
551 +    private boolean equalsArrayList(ArrayList<?> other) {
552 +        final int otherModCount = other.modCount;
553 +        final int s = size;
554 +        boolean equal;
555 +        if (equal = (s == other.size)) {
556 +            final Object[] otherEs = other.elementData;
557 +            final Object[] es = elementData;
558 +            if (s > es.length || s > otherEs.length) {
559 +                throw new ConcurrentModificationException();
560 +            }
561 +            for (int i = 0; i < s; i++) {
562 +                if (!Objects.equals(es[i], otherEs[i])) {
563 +                    equal = false;
564 +                    break;
565 +                }
566 +            }
567 +        }
568 +        other.checkForComodification(otherModCount);
569 +        return equal;
570 +    }
571 +
572 +    private void checkForComodification(final int expectedModCount) {
573 +        if (modCount != expectedModCount) {
574 +            throw new ConcurrentModificationException();
575 +        }
576 +    }
577 +
578 +    /**
579 +     * {@inheritDoc}
580 +     */
581 +    public int hashCode() {
582 +        int expectedModCount = modCount;
583 +        int hash = hashCodeRange(0, size);
584 +        checkForComodification(expectedModCount);
585 +        return hash;
586 +    }
587 +
588 +    int hashCodeRange(int from, int to) {
589 +        final Object[] es = elementData;
590 +        if (to > es.length) {
591 +            throw new ConcurrentModificationException();
592 +        }
593 +        int hashCode = 1;
594 +        for (int i = from; i < to; i++) {
595 +            Object e = es[i];
596 +            hashCode = 31 * hashCode + (e == null ? 0 : e.hashCode());
597 +        }
598 +        return hashCode;
599 +    }
600 +
601 +    /**
602       * Removes the first occurrence of the specified element from this list,
603       * if it is present.  If the list does not contain the element, it is
604       * unchanged.  More formally, removes the element with the lowest index
# Line 783 | Line 856 | public class ArrayList<E> extends Abstra
856       *             instance is emitted (int), followed by all of its elements
857       *             (each an {@code Object}) in the proper order.
858       */
859 +    // OPENJDK @java.io.Serial
860      private void writeObject(java.io.ObjectOutputStream s)
861          throws java.io.IOException {
862          // Write out element count, and any hidden stuff
# Line 810 | Line 884 | public class ArrayList<E> extends Abstra
884       *         could not be found
885       * @throws java.io.IOException if an I/O error occurs
886       */
887 +    // OPENJDK @java.io.Serial
888      private void readObject(java.io.ObjectInputStream s)
889          throws java.io.IOException, ClassNotFoundException {
890  
# Line 821 | Line 896 | public class ArrayList<E> extends Abstra
896  
897          if (size > 0) {
898              // like clone(), allocate array based upon size not capacity
899 <            SharedSecrets.getJavaObjectInputStreamAccess().checkArray(s, Object[].class, size);
899 >            jsr166.Platform.checkArray(s, Object[].class, size);
900              Object[] elements = new Object[size];
901  
902              // Read in all elements in the proper order.
# Line 1122 | Line 1197 | public class ArrayList<E> extends Abstra
1197              return true;
1198          }
1199  
1200 +        public void replaceAll(UnaryOperator<E> operator) {
1201 +            root.replaceAllRange(operator, offset, offset + size);
1202 +        }
1203 +
1204          public boolean removeAll(Collection<?> c) {
1205              return batchRemove(c, false);
1206          }
# Line 1149 | Line 1228 | public class ArrayList<E> extends Abstra
1228              return modified;
1229          }
1230  
1231 +        public Object[] toArray() {
1232 +            checkForComodification();
1233 +            return Arrays.copyOfRange(root.elementData, offset, offset + size);
1234 +        }
1235 +
1236 +        @SuppressWarnings("unchecked")
1237 +        public <T> T[] toArray(T[] a) {
1238 +            checkForComodification();
1239 +            if (a.length < size)
1240 +                return (T[]) Arrays.copyOfRange(
1241 +                        root.elementData, offset, offset + size, a.getClass());
1242 +            System.arraycopy(root.elementData, offset, a, 0, size);
1243 +            if (a.length > size)
1244 +                a[size] = null;
1245 +            return a;
1246 +        }
1247 +
1248 +        public boolean equals(Object o) {
1249 +            if (o == this) {
1250 +                return true;
1251 +            }
1252 +
1253 +            if (!(o instanceof List)) {
1254 +                return false;
1255 +            }
1256 +
1257 +            boolean equal = root.equalsRange((List<?>)o, offset, offset + size);
1258 +            checkForComodification();
1259 +            return equal;
1260 +        }
1261 +
1262 +        public int hashCode() {
1263 +            int hash = root.hashCodeRange(offset, offset + size);
1264 +            checkForComodification();
1265 +            return hash;
1266 +        }
1267 +
1268 +        public int indexOf(Object o) {
1269 +            int index = root.indexOfRange(o, offset, offset + size);
1270 +            checkForComodification();
1271 +            return index >= 0 ? index - offset : -1;
1272 +        }
1273 +
1274 +        public int lastIndexOf(Object o) {
1275 +            int index = root.lastIndexOfRange(o, offset, offset + size);
1276 +            checkForComodification();
1277 +            return index >= 0 ? index - offset : -1;
1278 +        }
1279 +
1280 +        public boolean contains(Object o) {
1281 +            return indexOf(o) >= 0;
1282 +        }
1283 +
1284          public Iterator<E> iterator() {
1285              return listIterator();
1286          }
# Line 1556 | Line 1688 | public class ArrayList<E> extends Abstra
1688                      setBit(deathRow, i - beg);
1689              if (modCount != expectedModCount)
1690                  throw new ConcurrentModificationException();
1559            expectedModCount++;
1691              modCount++;
1692              int w = beg;
1693              for (i = beg; i < end; i++)
# Line 1575 | Line 1706 | public class ArrayList<E> extends Abstra
1706  
1707      @Override
1708      public void replaceAll(UnaryOperator<E> operator) {
1709 +        replaceAllRange(operator, 0, size);
1710 +        // TODO(8203662): remove increment of modCount from ...
1711 +        modCount++;
1712 +    }
1713 +
1714 +    private void replaceAllRange(UnaryOperator<E> operator, int i, int end) {
1715          Objects.requireNonNull(operator);
1716          final int expectedModCount = modCount;
1717          final Object[] es = elementData;
1718 <        final int size = this.size;
1582 <        for (int i = 0; modCount == expectedModCount && i < size; i++)
1718 >        for (; modCount == expectedModCount && i < end; i++)
1719              es[i] = operator.apply(elementAt(es, i));
1720          if (modCount != expectedModCount)
1721              throw new ConcurrentModificationException();
1586        modCount++;
1722          // checkInvariants();
1723      }
1724  

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines