Javase basic Review (1) ArrayList in-depth analysis and interpretation of ArrayList source code (JDK1.8.0 _ 92) and javasejdk1.8.0 _ 92

Source: Internet
Author: User
Tags addall

Javase basic Review (1) ArrayList in-depth analysis and interpretation of ArrayList source code (JDK1.8.0 _ 92) and javasejdk1.8.0 _ 92

When learning this part of content, we need to pay attention to the problem that the collection still stores the object reference rather than the object itself.

The List interface extends Collection and declares the features of class sets that store a series of elements. Using a zero-based subscript, elements can be inserted and accessed through their positions in the list. A list can contain duplicate elements. List is an important knowledge point in the collection and is also the most commonly used in development.

We all know that ArrayList is implemented by arrays, but it is very similar to arrays. In addition, with the constant addition of elements to ArrayList, its capacity also increases automatically, after the array is declared, its capacity will not change. It is very important to find out the principles of the analysis. Today, I have rechecked the source code of this piece (JDK1.8.0 _ 92), so I will record and share it here.

1. attributes in the Arraylist class

1 public class ArrayList <E> extends actlist <E> 2 implements List <E>, RandomAccess, Cloneable, java. io. serializable 3 {4 private static final long serialVersionUID = 868345258da-2892189l; 5 6/** 7 * default initial capacity 8 */9 private static final int DEFAULT_CAPACITY = 10; 10 11/** 12 * shared empty array instance used for empty instances 13 */14 private static final Object [] EMPTY_ELEMENTDATA = {}; 15 16/** 17 * Object [] type array, saving the elements added to the ArrayList. The ArrayList capacity is the length of the array of the Object [] type 18 * when the first element is added, elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA in any empty ArrayList will be expanded to DEFAULT_CAPACITY by 19 * (default capacity ). 20 */21 private transient Object [] elementData; 22 23/** 24 * size of the ArrayList (actually the value returned by the size () method) 25*26 * @ serial27 */28 private int size; 29 30 ...... 31 32}
Class attributes

Note the following points:

DEFAULT_CAPACITY refers to the default capacity of ArrayList. In fact, the initial capacity of an Arraylist is 0. After adding one, the capacity becomes 10, this is not the case with JDK 1.6. Next we will introduce them one by one.

The elementData variable is an array, in the source code annotation of JDK1.8.0 _ 92, it is clear that this array is used to cache data in the ArrayList (the data here refers to the reference of the object ), the size of the ArrayList depends on the length of the cached array, it is also pointed out that during initialization, the cached array is an empty array. When it is added for the first time, the length of the cached array will be extended to the above DEFAULT_CAPACITY, that is, 10.

The size variable refers to the size of the cached array, that is, the length of the ArrayList.

2. Constructor

1 // The initial length of the ArrayList when the constructor parameter with parameters is 2 public ArrayList (int initialCapacity) {3 super (); 4 if (initialCapacity <0) 5 throw new IllegalArgumentException ("Illegal Capacity:" + 6 initialCapacity); 7 this. elementData = new Object [initialCapacity]; 8} 9 // a constructor without parameters (the initialization length is 0) is also our most common constructor 10 public ArrayList () {11 super (); 12 this. elementData = EMPTY_ELEMENTDATA; 13} 14 // a constructor with parameters constructs a list of elements containing the specified collection. These elements 15 public ArrayList (collection <? Extends E> c) {16 elementData = c. toArray (); 17 size = elementData. length; 18 // c. toArray might (incorrectly) not return Object [] (see 6260652) 19 if (elementData. getClass ()! = Object []. class) 20 elementData = Arrays. copyOf (elementData, size, Object []. class); 21}
View Code

Note that the implementation mechanism is slightly different in jdk of different versions. As follows:

In jdk1.8.0 _ 45, the constructor without parameters is as follows:

1 public ArrayList() {2   this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;  //DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {}3 }
View Code

JDK1.6 does not contain parameters:

1 public ArrayList () {2 this (10); // this. elementData = new Object [initialCapacity] in public ArrayList (int initialCapacity); 3}
View Code

Although the Code in JDK1.8.0 _ 92 and jdk1.8.0 _ 45 is slightly different, their implementation mechanism is the same, all are the first to declare an empty array. The length of the array is extended to 10 when it is added, and the length of the array declared at JDK1.6 is 10. This is also a step-by-step optimization.

When is the array length extended? Let's look at it below.

3. Add Elements

1 // add the specified Element (E) to the end of this list 2 public boolean add (e E) {3 ensureCapacityInternal (size + 1); // Increments modCount !! 4 elementData [size ++] = e; 5 return true; 6} 7 8 // Insert the specified Element (E) to the specified position (index) of the list) 9 public void add (int index, E element) {10 rangeCheckForAdd (index); // judge whether the index parameter IndexOutOfBoundsException11 12 ensureCapacityInternal (size + 1); // Increments modCount !! If the array length is insufficient, 13 System will be resized. arraycopy (elementData, index, elementData, index + 1, 14 size-index ); // move the size-index elements starting from the index position in the source array to the same position and then shift the value of 15 elementData [index] = element; 16 size ++; 17} 18 19/** 20 * according to the order of the elements returned by the iterator of the specified collection, add all the elements in the collection to the end of the list 21 * @ throws NullPointerException if the specified collection is null22 */23 public boolean addAll (Collection <? Extends E> c) {24 Object [] a = c. toArray (); 25 int numNew =. length; 26 ensureCapacityInternal (size + numNew); // Increments modCount27 // convert the array a [0 ,..., numNew-1] copies to array elementData [size ,..., size + numNew-1] 28 System. arraycopy (a, 0, elementData, size, numNew); 29 size + = numNew; 30 return numNew! = 0; 31} 32 33/** 34 * Insert all elements in the specified collection to this list starting from the specified position, the order of the new elements is 35 * @ throws IndexOutOfBoundsException {@ inheritDoc} 36 * @ throws NullPointerException if the specified collection is null37 */38 public boolean addAll (int index, collection <? Extends E> c) {39 rangeCheckForAdd (index); // determines whether the index parameter is IndexOutOfBoundsException40 41 Object [] a = c. toArray (); 42 int numNew =. length; 43 ensureCapacityInternal (size + numNew); // Increments modCount44 45 int numMoved = size-index; 46 if (numMoved> 0) 47 // first convert the array elementData [index ,..., index + numMoved-1] copies to elementData [index + numMoved ,..., index + 2 * numMoved-1] 48 // that is, unify the following numMoved elements from the index position in the source array and then move numNe W-bit 49 System. arraycopy (elementData, index, elementData, index + numNew, 50 numMoved); 51 // convert array a [0 ,..., numNew-1] copies to array elementData [index ,..., index + numNew-1] 52 System. arraycopy (a, 0, elementData, index, numNew); 53 size + = numNew; 54 return numNew! = 0; 55}
View Code

The specific implementation methods in the above add methods are not listed above and I will put them below

Specific implementation methods:

1/** 2 * public method, allowing users to manually set the ArrayList capacity 3 * @ param minCapacity the expected minimum capacity 4 */5 public void ensureCapacity (int minCapacity) {6 int minExpand = (elementData! = Defacapcapacity_empty_elementdata) 7 // any size if not default element table 8? 0 9 // larger than default for default empty table. it's already10 // supposed to be at default size.11: DEFAULT_CAPACITY; 12 13 if (minCapacity> minExpand) {14 ensureExplicitCapacity (minCapacity ); 15} 16} 17 18 private void ensureCapacityInternal (int minCapacity) {19 // when elementData is empty, the minimum initial capacity of ArrayList is DEFAULT_CAPACITY (10) 20 if (elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {21 minCapacity = M Ath. max (DEFAULT_CAPACITY, minCapacity); 22} 23 ensureExplicitCapacity (minCapacity); 24} 25 26 private void ensureExplicitCapacity (int minCapacity) {27 modCount ++; 28 // overflow-conscious code29 if (minCapacity-elementData. length> 0) 30 grow (minCapacity); 31} 32 33 // maximum capacity that can be allocated to the array; when the required array size exceeds the VM limit, this may cause OutOfMemoryError34 private static final int MAX_ARRAY_SIZE = Integer. MAX_VALUE-8; 35 36/** 37 * add an array Make sure that it can accommodate at least the specified minimum capacity of the elements 38 * @ param minCapacity expected minimum capacity 39 */40 private void grow (int minCapacity) {41 // overflow-conscious code42 int oldCapacity = elementData. length; 43 // note that the way to expand capacity is to shift it to the right and add the original number, in fact, it is expanded by 1.5 times. 44 int newCapacity = oldCapacity + (oldCapacity> 1); 45 if (newCapacity-minCapacity <0) 46 newCapacity = minCapacity; 47 if (newCapacity-MAX_ARRAY_SIZE> 0) 48 newCapacity = hugeCa Pacity (minCapacity); // you can specify the maximum allocated capacity of the array. 49 // minCapacity is usually close to size, so this is a win: 50 elementData = Arrays. copyOf (elementData, newCapacity); 51} 52 53 private static int hugeCapacity (int minCapacity) {54 if (minCapacity <0) // overflow55 throw new OutOfMemoryError (); 56 return (minCapacity> MAX_ARRAY_SIZE )? 57 Integer. MAX_VALUE: 58 MAX_ARRAY_SIZE; 59}
View Code

It is worth noting that> 1 in the grow () method is equivalent to dividing by 2. For example:

1010 decimal: 10 original number number10100 decimal: 20 shifts one digit left number = number <1; 1010 decimal: 10 shifts one digit number = number> 1;

Therefore, when we follow the add (E) method, we will know that when we perform the add operation on the ArrayList, we will first enter the add () method and then execute the ensureCapacityInternal () method, follow up here elementData = EMPTY_ELEMENTDATA is true, so minCapacity = 10. Then minCapacity-elementData. length> 0 is true. The grow () method is executed. Every time the grow () method is executed, a new array is generated and the length is 1.5 times the length of the original array, however, in either case, the first point is that when the length of the newly generated array is less than 10, the length of the newly generated array is changed to 10, that is, grow () the code in the first if statement of the method (that is, it ensures that the length of the ArrayList is 10 when the number of elements to be added is smaller than 8 ), the second point is when the length of the newly generated array is greater than Integer. when MAX_VALUE-8 is used, the array length is adjusted to avoid going out of bounds (this is what the code in the second if statement of the grow () method does ). This is the basic principle of automatic expansion of ArrayList capacity.

I have seen the implementation method of JDK 1.5 here, which is slightly different but also generates a new array with a length of times that of the original array. As for why it is 1.5 times, I think it may be that the Daniel got such an optimal solution through his own experience or scientific derivation. I don't know. I would like to add it to my guess.

There are many methods in ArrayList, such as deleting elements, modifying elements, and searching elements, which are easy to understand.

We have a general understanding of the basic principles of ArrayList, and then we can easily understand the features of ArrayList. Compared with the shortlist, ArrayList is more suitable for search operations, and the shortlist is more suitable for insert or delete operations. Because ArrayList applies to array implementation, the data stored in the memory is continuous, so it is easy to locate from one element to another, and the sorted list is different, when using a two-chain table, the sequence list must be one by one to see if it is the element to be searched. However, the efficiency of the sequence list insert or delete operations during execution is very high.

In eclipse, the commonly used shortcut keys for viewing source code are Alt + left and right arrow keys, which can be used to jump to the cursor before.

Check for missing information!

 

OutOfMemoryError

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.