src/share/classes/java/util/ArrayList.java
Print this page
rev 6789 : 7143928: 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 ****
/*
! * Copyright (c) 1997, 2012, 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
--- 1,7 ----
/*
! * 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
*** 102,118 ****
--- 102,125 ----
public class ArrayList<E> extends AbstractList<E>
implements List<E>, RandomAccess, Cloneable, java.io.Serializable
{
private static final long serialVersionUID = 8683452581122892189L;
+ 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;
/**
+ * initial capacity.
+ */
+ private transient int initialCapacity;
+
+ /**
* The size of the ArrayList (the number of elements it contains).
*
* @serial
*/
private int size;
*** 127,137 ****
public ArrayList(int initialCapacity) {
super();
if (initialCapacity < 0)
throw new IllegalArgumentException("Illegal Capacity: "+
initialCapacity);
! this.elementData = new Object[initialCapacity];
}
/**
* Constructs an empty list with an initial capacity of ten.
*/
--- 134,145 ----
public ArrayList(int initialCapacity) {
super();
if (initialCapacity < 0)
throw new IllegalArgumentException("Illegal Capacity: "+
initialCapacity);
! this.initialCapacity = initialCapacity;
! elementData = EMPTY_ELEMENTDATA;
}
/**
* Constructs an empty list with an initial capacity of ten.
*/
*** 160,171 ****
* 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) {
elementData = Arrays.copyOf(elementData, size);
}
}
/**
--- 168,178 ----
* list's current size. An application can use this operation to minimize
* the storage of an <tt>ArrayList</tt> instance.
*/
public void trimToSize() {
modCount++;
! if (size < elementData.length) {
elementData = Arrays.copyOf(elementData, size);
}
}
/**
*** 174,189 ****
--- 181,205 ----
* specified by the minimum capacity argument.
*
* @param minCapacity the desired minimum capacity
*/
public void ensureCapacity(int minCapacity) {
+ if(elementData != EMPTY_ELEMENTDATA) {
if (minCapacity > 0)
ensureCapacityInternal(minCapacity);
+ } else {
+ // adjust eventual capacity if requested capacity is larger.
+ initialCapacity = Math.max(initialCapacity, minCapacity);
+ }
}
private void ensureCapacityInternal(int minCapacity) {
modCount++;
+ if(elementData == EMPTY_ELEMENTDATA) {
+ minCapacity = Math.max(initialCapacity, minCapacity);
+ }
+
// overflow-conscious code
if (minCapacity - elementData.length > 0)
grow(minCapacity);
}
*** 700,719 ****
// Write out element count, and any hidden stuff
int expectedModCount = modCount;
s.defaultWriteObject();
// Write out array length
! s.writeInt(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).
--- 716,734 ----
// Write out element count, and any hidden stuff
int expectedModCount = modCount;
s.defaultWriteObject();
// Write out array length
! s.writeInt((elementData == EMPTY_ELEMENTDATA) ? initialCapacity : 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,735 ****
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 all elements in the proper order.
for (int i=0; i<size; i++)
a[i] = s.readObject();
}
/**
--- 736,754 ----
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
! initialCapacity = s.readInt();
! elementData = EMPTY_ELEMENTDATA;
!
! // allocate array based upon size.
! ensureCapacityInternal(size);
! Object[] a = elementData;
! // Read in all elements the proper order.
for (int i=0; i<size; i++)
a[i] = s.readObject();
}
/**