First, let's look at the inheritance relationship of ArrayList as follows, and from the surface we can see how it supports abstract objects
public class Arraylist<e> extends abstractlist<e>
implements List<e>, Randomaccess, Cloneable, Java.io.Serializable
Let's see what we've inherited.
Abstractlist an abstract class in which there are some common methods to implement
The list interface must implement the method
Randomaccess is an empty interface that plays an important role in abstractlist that will be useful to you, and this is not discussed here.
Colneable is similar to randomaccess as an empty interface, providing a Object.colne () method
Serializable interface to enable its serialization functionality
ArrayList used two global variables, a little bit more understanding of multithreading, you should be able to know, from here you can see that ArrayList also appear concurrency problems, non-thread-safe class
object[] Elementdata Array type
/**
* 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;
/** * The size of the ArrayList (the number of
elements it contains).
*
* @serial
/private int size;
List List = new ArrayList ()//This is our common way of creating, let's see what happens inside.
The default object property is 10, in the form of an array
/**
* Constructs a empty list with the specified initial capacity.
*
* @param initialcapacity The initial capacity of the list
* @throws illegalargumentexception if the SPE Cified Initial capacity
* is negative/public
ArrayList (int initialcapacity) {
super ();
if (initialcapacity < 0)
throw new IllegalArgumentException ("illegal Capacity:" +
initialcapacity);
This.elementdata = new object[initialcapacity];//<span style= "color: #FF0000;" > Array type </span>
}
/**
* Constructs a empty list with a initial capacity of ten.
* * Public
ArrayList () {this
;//<span style= "color: #FF0000;" > Default 10 elements </span>
}
Then go to the topic and see how it's added
<span style= "FONT-SIZE:14PX;" >/**
* Appends the specified element to the "end of" this list.
*
* @param e element to is appended to this list
* @return <tt>true</tt> (as specified by {@link Colle Ction#add})
*/Public
Boolean add (E e) {
ensurecapacityinternal (size + 1); Increments modcount!!
elementdata[size++] = e;
return true;
} </span>
The point is, we know the initial element number is 10, so what happens if it's full?
<span style= "FONT-SIZE:14PX;" >private void ensurecapacityinternal (int mincapacity) {
modcount++;
Overflow-conscious Code
if (Mincapacity-elementdata.length > 0)
grow (mincapacity);
} </span>
<span style= "FONT-SIZE:14PX;" > </span><pre name= "code" class= "java" ><span style= "FONT-SIZE:14PX;" > private static final int max_array_size = integer.max_value-8;</span>
private void Grow (int mincapacity) {//overflow-conscious code int oldcapacity = elementdata.length; int newcapacity = OL Dcapacity + (oldcapacity >> 1);//increment value, each time if (newcapacity-mincapacity < 0) newcapacity = mincapacity; if (newcapacity-max_array_size > 0) newcapacity = hugecapacity (mincapacity); Mincapacity is usually the close to size, so this is a win:elementdata = arrays.copyof (Elementdata, newcapacity); }
From here we can see that each expansion increment for (1 + 0.5) * oldcapacity, the most greatly
<pre name= "code" class= "java" ><span style= "FONT-SIZE:14PX;" >Integer.MAX_VALUE</span>
And each expansion will recreate an object.
<span style= "FONT-SIZE:14PX;" > Public static <T,U> t[] copyof (u[] original, int newlength, class<? extends t[]> NewType) {
t[] C Opy = ((object) NewType = = (object) object[].class)
? (t[]) new Object[newlength]
: (t[]) array.newinstance (Newtype.getcomponenttype (), newlength);
System.arraycopy (original, 0, copy, 0,
math.min (Original.length, newlength));
return copy;
} </span>
Imagine how many objects will be created if you add 1.001 billion elements at a time by adding an element
The simplest optimization method, when creating a list, is whether we can estimate the number of estimates. Can we estimate the number of elements to be expanded before each element is added?
<span style= "FONT-SIZE:14PX;" >arraylist list = new ArrayList (100);//change default value of
list.ensurecapacity (1000);//Estimated capacity 1000</span>
If there are other good expansion methods, welcome to discuss
Test as follows
public static void Main (string[] args) throws IOException {Runtime run = runtime.getruntime ();
RUN.GC ();
System.out.println ("Time:" + (new Date ());
Gets the memory usage at start long Startmem = Run.totalmemory ()-run.freememory ();
System.out.println ("memory> total:" + run.totalmemory () + "free:" + run.freememory () + "used:" + startmem);
ArrayList list = new ArrayList ();
int size = 10000000; list.ensurecapacity (size);
Whether to enlarge int i = 0;
try {for (; i < size; i++) {list.add (i);
} catch (Throwable e) {e.printstacktrace ();
System.out.println ("i=" + i);
} System.out.println ("Time:" + (new Date ());
Long Endmem = Run.totalmemory ()-run.freememory ();
System.out.println ("memory> total:" + run.totalmemory () + "free:" + run.freememory () + "used:" + endmem); System.out.println ("Memory Difference: "+ (ENDMEM-STARTMEM)); }
Output Memory Difference Result:
A. Non-expansion
Time:tue Aug 16:38:49 CST 2016
memory> total:18350080 free:16858832 used:1491248
Time:tue Aug 16:38:53 CST 2016
memory> total:291962880 free:14030184 used:277932696
Memory difference:276441448
B. Capacity-expansion
Time:tue Aug 16:41:47 CST 2016
memory> total:18612224 free:17107928 used:1504296
Time:tue Aug 16:41:50 CST 2016
memory> total:296026112 free:94840808 used:201185304
Memory difference:199681008