ArrayList
ArrayList is the most common and familiar collection class for every Java developer, as the name implies, ArrayList is a collection of arrays , with a table to see what the basic elements are in ArrayList:
| Elements |
Role |
| Private transient object[] elementdata; |
ArrayList is an array-based implementation, and Elementdata is the underlying array. |
| private int size; |
ArrayList the number of elements inside, it is important to note that size is self-increment or decrement according to the number of times the add, remove methods are called.
So add a null into the arraylist,size will also add 1. |
Source:
/** * The array buffer into which the elements of the ArrayList is 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;
The ArrayList class defines only two private properties, which is easy to understand, Elementdata stores the elements within the ArrayList, and the size represents the number of elements it contains.
There is a key word to explain:transient.
Transient is the Java keyword, the variable modifier, and if an instance variable is declared with transient, its value does not need to be maintained when the object is stored. Java's serialization provides a mechanism for persisting object instances. When persisting an object, there may be a special object data member, and we do not want to use the serialization mechanism to save it. In order to turn off serialization on a domain of a particular object, you can precede the field with the keyword transient. When an object is serialized, the value of the transient variable is not included in the serialized representation, but the non-transient variable is included.
For collections, I think there are four main points of concern:
1, whether to allow empty
2. Whether duplicate data is allowed
3, whether orderly, orderly means to read the order of data and the order of the data stored is consistent
4. is thread safe
Four points of concern on the ArrayList answer
| Focus Point |
Conclusion |
| ArrayList whether NULL is allowed |
Allow |
| ArrayList whether duplicate data is allowed |
Allow |
| Whether the ArrayList is orderly |
Ordered |
| ArrayList is thread safe |
Non-thread safe |
constructor Function
The ArrayList provides three constructors:
ArrayList (): default constructor that provides an empty list with an initial capacity of 10 .
ArrayList (int initialcapacity): Constructs an empty list with the specified initial capacity.
ArrayList (collection<? extends e> c): Constructs a list of elements that contain the specified Collection, arranged in the order in which they are returned by the Collection iterator.
/** * Constructs an empty list with an initial capacity of 10 */public ArrayList () {This (10);} /** * Constructs an empty list with the specified initial capacity. */public ArrayList (int initialcapacity) { super (); if (initialcapacity < 0) throw new IllegalArgumentException ("Illegal capacity:" + initialcapacity); This.elementdata = new object[initialcapacity];} /** * Constructs a list of elements that contain the specified collection, which are arranged in the order in which they are returned by the collection iterator. */public ArrayList (collection<? extends e> c) { elementdata = C.toarray (); size = Elementdata.length; C.toarray might (incorrectly) not return object[] (see 6260652) if (Elementdata.getclass ()! = Object[].class)
elementdata = arrays.copyof (elementdata, size, object[].class);}
adding elements
There is a code like this:
public static void Main (string[] args) { list<string> List = new arraylist<string> (); List.add ("the"); List.add ("111");}
Look at the bottom what will do, into the Add method of the source to look at:
1 public boolean Add (E e) {2 ensurecapacity (size + 1); Increments modcount!! 3 elementdata[size++] = e;4 return true;5}
Do not go to the 2nd line of the Ensurecapacity method, this method is to expand the use of, the underlying actually call the Add method only to a certain location of the Elementdata to add a data, with a picture of the words are:
To say a word, I am so drawing a certain misleading. Elementdata should be stored in the heap in the memory of the elements of the reference, rather than the actual elements, so the painting gives a feeling that the Elementdata array is the actual elements stored inside, this is not very rigorous. But this painting is mainly for convenience, as long as you know the problem is good.
Expansion
Let's look at the default underlying array sizewhen constructing ArrayList:
Public ArrayList () {This (10);}
Then there is a problem, the size of the underlying array is not enough to do? The answer is to expand, which is why always say that the bottom of the ArrayList is based on the implementation of dynamic array , the meaning of the dynamic array is that the underlying array size is not fixed, but based on the size of the added element to make a judgment, not enough words on the dynamic expansion, The code for expansion is in ensurecapacity:
public void ensurecapacity (int mincapacity) { modcount++; int oldcapacity = elementdata.length; if (Mincapacity > Oldcapacity) { Object olddata[] = elementdata; int newcapacity = (oldcapacity * 3)/2 + 1; if (Newcapacity < mincapacity) newcapacity = mincapacity; Mincapacity is usually close to size, so this is a win: Elementdata = arrays.copyof (Elementdata, newcapacity);
}}
When you see the expansion, multiply the element group size by 3, then divide by 2, and then add 1. Maybe some people want to ask why? We can think of:
1, if one-time expansion is too large, will inevitably cause the waste of memory space
2, if the one-time expansion of the expansion is not enough, then the next expansion of the operation will inevitably come, which will reduce the efficiency of the program, to know whether the expansion or cost-effective performance of an operation
So the expansion and expansion of the JDK developers in time, space to do a trade-off, provide a more reasonable value. The last call to arrays's Copyof method is to copy the contents of the element group into the new array:
public static <T,U> t[] CopyOf (u[] original, int newlength, class<? extends t[]> NewType) { t[] copy = ((O bject) 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;}
This is the case with a picture:
inserting elements
Take a look at the insert operation of the ArrayList, and the Add method is called by the insert operation, for example:
1 public static void main (string[] args) 2 {3 list<string> List = new Arraylist<string> (); 4 List.add ("111"); 5 List.add ("222"), 6 list.add ("333"), 7 list.add ("444"), 8 list.add ("555"), 9 list.add ("666"); List.add ("777"), List.add ("888"), List.add (2, "the"), System.out.println (list); 14}
There's a place to be wrong, the Add method in line 12th means inserting an element after the first element, like Line 12th, which inserts a 000 after the second element. A look at the running results also proves this:
[111, 222, 000, 333, 444, 555, 666, 777, 888]
Or look at what you did when you inserted it:
Inserts the specified element into the specified position in this list. //If there are elements in the current position, move the element that is currently at that position and all subsequent elements (index plus 1) to the right. Public void Add (int index, E element) { if (Index > Size | | Index < 0) throw new indexoutofboundsexcept Ion ("Index:" +index+ ", Size:" +size); If the array length is insufficient, the expansion will be done. ensurecapacity (size+1); Increments modcount!! The element that starts in Elementdata from the index position, Size-index, //is copied to the new Elementdata array starting from the subscript index+1 position. //The element that is currently at that location and all subsequent elements move right one position. system.arraycopy (elementdata, index, Elementdata, index + 1, size-index); Elementdata[index] = element; size++;
When you see the insertion, follow the specified position, Take all elements starting from the specified position using the System.arraycopy method to make a whole copy, move backward one position (of course, first to use the Ensurecapacity method to judge, add an element after the array will not be large enough), and then specify the position of the element is set to the element to be inserted, complete the insertion into the operation. The diagram shows that this is the process:
The most fundamental method in this method is the System.arraycopy () method, the fundamental goal of this method is to empty the index position for new data to insert, it is necessary to move the array data right, which is very cumbersome and time-consuming, Therefore, if the specified data collection requires a large number of insertions (intermediate insertions), LinkedListis recommended.
Delete Element
Let's take a look at the deleted action. ArrayList supports two ways to delete:
1. Delete according to subscript
2. Delete by element, which removes the first element in ArrayList that matches the element specified to be deleted
For ArrayList, the two methods of deletion are similar, and are the following piece of code for the call:
int nummoved = size-index-1;if (nummoved > 0) system.arraycopy (Elementdata, index+1, Elementdata, index, nu mmoved); elementdata[--size] = null; Let GC do it work
In fact, the thing to do is two pieces:
1. Use the System.arraycopy method to move all the elements in the back position of the specified element forward one position
2, the element at the last position is specified as NULL, so that the GC can reclaim it
Let's say there's this code:
public static void Main (string[] args) { list<string> List = new arraylist<string> (); List.add ("111"); List.add ("222"); List.add ("333"); List.add ("444"); List.add ("555"); List.add ("666"); List.add ("777"); List.add ("888"); List.remove ("333");}
This is shown in the diagram:
Advantages and disadvantages of ArrayList
Summarize the pros and cons of ArrayList from a few of the above processes. The advantages of ArrayList are as follows:
1, ArrayList the bottom of the array implementation, is a random access pattern, coupled with its implementation of the Randomaccess interface, so the search is called get very fast.
2, ArrayList in order to add an element is very convenient, just add an element to the array.
But ArrayList's shortcomings are also obvious:
1, when deleting elements, involves a copy of the element, if you want to copy a lot of elements, then it will be more expensive performance.
2, when inserting elements, involves a copy of the element, if you want to copy a lot of elements, then it will be more expensive performance.
Therefore,ArrayList is more suitable for sequentially added, randomly accessed scenarios .
The difference between ArrayList and vectors
ArrayList is thread-insecure , which is obvious because all of the methods in ArrayList are not synchronous and there is a certain thread-safety problem in concurrency. So what do we want to do with ArrayList and make it thread safe? One approach is to use the Collections.synchronizedlist method to turn your ArrayList into a thread-safe list, such as:
list<string> synchronizedlist = collections.synchronizedlist (list); Synchronizedlist.add ("AAA"); Synchronizedlist.add ("BBB"); for (int i = 0; i < synchronizedlist.size (); i++) { System.out.println ( Synchronizedlist.get (i));}
Another method is vector, which is the thread-safe version of ArrayList, and its implementation of 90% and ArrayList are exactly the same, the difference is:
1,vector is thread-safe, ArrayList is thread non-security
2, the vector can specify the growth factor, if the growth factor is specified, then each time the new array size will be added to the original array size based on the growth factor, if you do not specify the growth factor, then the original array size * *, the source code is this:
int newcapacity = oldcapacity + ((capacityincrement > 0)? capacityincrement:oldcapacity);
Summarize
ArrayList is based on an array implementation, you can directly find the element at the specified location through the subscript index, so the lookup is efficient, but each time you insert or delete an element, you move the element a lot, and the insertion of the deleted element is inefficient.
ArrayList of the Java collection