提交 7e850df0 编写于 作者: M mduigou

8035584: ArrayList(c) should avoid inflation if c is empty

Reviewed-by: martin
上级 3ec1c1d7
...@@ -118,11 +118,18 @@ public class ArrayList<E> extends AbstractList<E> ...@@ -118,11 +118,18 @@ public class ArrayList<E> extends AbstractList<E>
*/ */
private static final Object[] EMPTY_ELEMENTDATA = {}; private static final Object[] EMPTY_ELEMENTDATA = {};
/**
* Shared empty array instance used for default sized empty instances. We
* distinguish this from EMPTY_ELEMENTDATA to know how much to inflate when
* first element is added.
*/
private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};
/** /**
* The array buffer into which the elements of the ArrayList are stored. * The array buffer into which the elements of the ArrayList are stored.
* The capacity of the ArrayList is the length of this array buffer. Any * The capacity of the ArrayList is the length of this array buffer. Any
* empty ArrayList with elementData == EMPTY_ELEMENTDATA will be expanded to * empty ArrayList with elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA
* DEFAULT_CAPACITY when the first element is added. * will be expanded to DEFAULT_CAPACITY when the first element is added.
*/ */
transient Object[] elementData; // non-private to simplify nested class access transient Object[] elementData; // non-private to simplify nested class access
...@@ -141,19 +148,21 @@ public class ArrayList<E> extends AbstractList<E> ...@@ -141,19 +148,21 @@ public class ArrayList<E> extends AbstractList<E>
* is negative * is negative
*/ */
public ArrayList(int initialCapacity) { public ArrayList(int initialCapacity) {
super(); if (initialCapacity > 0) {
if (initialCapacity < 0) this.elementData = new Object[initialCapacity];
} else if (initialCapacity == 0) {
this.elementData = EMPTY_ELEMENTDATA;
} else {
throw new IllegalArgumentException("Illegal Capacity: "+ throw new IllegalArgumentException("Illegal Capacity: "+
initialCapacity); initialCapacity);
this.elementData = new Object[initialCapacity]; }
} }
/** /**
* Constructs an empty list with an initial capacity of ten. * Constructs an empty list with an initial capacity of ten.
*/ */
public ArrayList() { public ArrayList() {
super(); this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
this.elementData = EMPTY_ELEMENTDATA;
} }
/** /**
...@@ -166,10 +175,14 @@ public class ArrayList<E> extends AbstractList<E> ...@@ -166,10 +175,14 @@ public class ArrayList<E> extends AbstractList<E>
*/ */
public ArrayList(Collection<? extends E> c) { public ArrayList(Collection<? extends E> c) {
elementData = c.toArray(); elementData = c.toArray();
size = elementData.length; if ((size = elementData.length) != 0) {
// c.toArray might (incorrectly) not return Object[] (see 6260652) // c.toArray might (incorrectly) not return Object[] (see 6260652)
if (elementData.getClass() != Object[].class) if (elementData.getClass() != Object[].class)
elementData = Arrays.copyOf(elementData, size, Object[].class); elementData = Arrays.copyOf(elementData, size, Object[].class);
} else {
// replace with empty array.
this.elementData = EMPTY_ELEMENTDATA;
}
} }
/** /**
...@@ -180,7 +193,9 @@ public class ArrayList<E> extends AbstractList<E> ...@@ -180,7 +193,9 @@ public class ArrayList<E> extends AbstractList<E>
public void trimToSize() { public void trimToSize() {
modCount++; modCount++;
if (size < elementData.length) { if (size < elementData.length) {
elementData = Arrays.copyOf(elementData, size); elementData = (size == 0)
? EMPTY_ELEMENTDATA
: Arrays.copyOf(elementData, size);
} }
} }
...@@ -192,11 +207,11 @@ public class ArrayList<E> extends AbstractList<E> ...@@ -192,11 +207,11 @@ public class ArrayList<E> extends AbstractList<E>
* @param minCapacity the desired minimum capacity * @param minCapacity the desired minimum capacity
*/ */
public void ensureCapacity(int minCapacity) { public void ensureCapacity(int minCapacity) {
int minExpand = (elementData != EMPTY_ELEMENTDATA) int minExpand = (elementData != DEFAULTCAPACITY_EMPTY_ELEMENTDATA)
// any size if real element table // any size if not default element table
? 0 ? 0
// larger than default for empty table. It's already supposed to be // larger than default for default empty table. It's already
// at default size. // supposed to be at default size.
: DEFAULT_CAPACITY; : DEFAULT_CAPACITY;
if (minCapacity > minExpand) { if (minCapacity > minExpand) {
...@@ -205,7 +220,7 @@ public class ArrayList<E> extends AbstractList<E> ...@@ -205,7 +220,7 @@ public class ArrayList<E> extends AbstractList<E>
} }
private void ensureCapacityInternal(int minCapacity) { private void ensureCapacityInternal(int minCapacity) {
if (elementData == EMPTY_ELEMENTDATA) { if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity); minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册