src/share/classes/java/util/ArrayList.java
Print this page
rev 6816 : 80111200: (coll) Optimize empty HashMap and ArrayList
Reviewed-by: mduigou
Contributed-by: Sergey Linetskiy <sergey.linetskiy@oracle.com>, John Rose <john.rose@oracle.com>, Mike Duigou <mike.duigou@oracle.com>
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
@@ -103,10 +103,15 @@
implements List<E>, RandomAccess, Cloneable, java.io.Serializable
{
private static final long serialVersionUID = 8683452581122892189L;
/**
+ * Shared empty array instance used for empty instances.
+ */
+ private static final Object EMPTY_ELEMENTDATA[] = new Object[0];
+
+ /**
* The array buffer into which the elements of the ArrayList are stored.
* The capacity of the ArrayList is the length of this array buffer.
*/
private transient Object[] elementData;
@@ -134,11 +139,12 @@
/**
* Constructs an empty list with an initial capacity of ten.
*/
public ArrayList() {
- this(10);
+ super();
+ this.elementData = EMPTY_ELEMENTDATA;
}
/**
* Constructs a list containing the elements of the specified
* collection, in the order they are returned by the collection's
@@ -160,12 +166,11 @@
* list's current size. An application can use this operation to minimize
* the storage of an <tt>ArrayList</tt> instance.
*/
public void trimToSize() {
modCount++;
- int oldCapacity = elementData.length;
- if (size < oldCapacity) {
+ if (size < elementData.length) {
elementData = Arrays.copyOf(elementData, size);
}
}
/**
@@ -175,15 +180,24 @@
*
* @param minCapacity the desired minimum capacity
*/
public void ensureCapacity(int minCapacity) {
if (minCapacity > 0)
- ensureCapacityInternal(minCapacity);
+ ensureExplicitCapacity(minCapacity);
}
private void ensureCapacityInternal(int minCapacity) {
+ if(elementData == EMPTY_ELEMENTDATA) {
+ minCapacity = Math.max(10, minCapacity);
+ }
+
+ ensureExplicitCapacity(minCapacity);
+ }
+
+ private void ensureExplicitCapacity(int minCapacity) {
modCount++;
+
// overflow-conscious code
if (minCapacity - elementData.length > 0)
grow(minCapacity);
}
@@ -504,12 +518,11 @@
*/
public void clear() {
modCount++;
// Let gc do its work
- for (int i = 0; i < size; i++)
- elementData[i] = null;
+ Arrays.fill(elementData, null);
size = 0;
}
/**
@@ -586,12 +599,12 @@
System.arraycopy(elementData, toIndex, elementData, fromIndex,
numMoved);
// Let gc do its work
int newSize = size - (toIndex-fromIndex);
- while (size != newSize)
- elementData[--size] = null;
+ Arrays.fill(elementData, newSize, size, null);
+ size = newSize;
}
/**
* Checks if the given index is in range. If not, throws an appropriate
* runtime exception. This method does *not* check if the index is
@@ -675,12 +688,12 @@
elementData, w,
size - r);
w += size - r;
}
if (w != size) {
- for (int i = w; i < size; i++)
- elementData[i] = null;
+ // Let gc do its work
+ Arrays.fill(elementData, w, size, null);
modCount += size - w;
size = w;
modified = true;
}
}
@@ -700,20 +713,19 @@
// Write out element count, and any hidden stuff
int expectedModCount = modCount;
s.defaultWriteObject();
// Write out array length
- s.writeInt(elementData.length);
+ s.writeInt((elementData == EMPTY_ELEMENTDATA) ? 10 : elementData.length);
// Write out all elements in the proper order.
for (int i=0; i<size; i++)
s.writeObject(elementData[i]);
if (modCount != expectedModCount) {
throw new ConcurrentModificationException();
}
-
}
/**
* Reconstitute the <tt>ArrayList</tt> instance from a stream (that is,
* deserialize it).
@@ -721,14 +733,20 @@
private void readObject(java.io.ObjectInputStream s)
throws java.io.IOException, ClassNotFoundException {
// Read in size, and any hidden stuff
s.defaultReadObject();
- // Read in array length and allocate array
- int arrayLength = s.readInt();
- Object[] a = elementData = new Object[arrayLength];
+ // Read in array length
+ int initialCapacity = s.readInt();
+ elementData = EMPTY_ELEMENTDATA;
+
+ if((size > 0) || (initialCapacity != 10)) {
+ // allocate array based upon size.
+ ensureCapacityInternal(size);
+ }
+ Object[] a = elementData;
// Read in all elements in the proper order.
for (int i=0; i<size; i++)
a[i] = s.readObject();
}