Explore ArrayList to automatically change size truth

Source: Internet
Author: User
Tags junk collector

Explore ArrayList to automatically change size truth

The list object of ArrayList is actually stored in a referenced array. Some people think that the array has an "auto-increment mechanism" to automatically change the size. Formally speaking, the array cannot be changed.

In fact, it only changes the point of the referenced array. Next, let's take a look at how java implements the ArrayList class. I. essence of the ArrayList class

ArrayList uses an array of the Object type at the underlying layer. When an ArrayList Object is generated using a constructor without parameters,
In fact, an array of the Object type with a length of 10 is generated at the underlying layer.

First, ArrayList defines a private array elementData that is not serialized. It is used to store the list of ArrayList objects (note that only the object list is not initially defined ):
Private transient Object [] elementData;
Second, specify the initial Capacity or convert the specified Collection to a reference array, and then instantiate the elementData array. If not specified, the preset initial Capacity is 10.

Instantiation. The key to automatically changing the size of the ArrayList is to pre-instantiate the private array and overwrite the original Array Using the copyOf method. Some people say that ArrayList is a complex array.

It is better to say that ArrayList is a method combination of array systems.

The source code of the ArrayList constructor is as follows:

// Construct an empty list with the specified initial capacity.

   1:  public ArrayList(int initialCapacity) {
   2:     super();
   3:     if (initialCapacity < 0)
   4:     throw new IllegalArgumentException("Illegal Capacity: "+initialCapacity);
5: this. elementData = new Object [initialCapacity]; // The attribute points to a temporary array with the new length being the initial capacity.
   6:  }
1: // use initial capacity 10 to construct an empty list
   2:  public ArrayList() {
   3:    this(10);
   4:  } 
   5:   
6:/* construct a list of the specified collection elements returned by the collection iterator in sequence
7: * @ param c set, whose elements are used to put in list t
8: * @ throws NullPointerException if the specified set is null
   9:  */
  10:  public ArrayList(Collection<? extends E> c) {
11: elementData = c. toArray (); // use Collection to initialize the array elementData
  12:    size = elementData.length;
  13:    if (elementData.getClass() != Object[].class)
  14:      elementData = Arrays.copyOf(elementData, size, Object[].class);
  15:  } 

Ii. ArrayList implements automatic size Change Mechanism

To implement this mechanism, java introduces the Capacity and size concepts to distinguish the length of an array. To ensure that users add new List objects, java sets the minimum capacity (minCapacity)

In general, it is larger than the number of List objects, so Capactiy is the length of the underlying array, but it is meaningless for end users. Size stores the list

The number of objects is what the end user needs. To prevent incorrect user modification, this attribute is set to privae, but can be obtained through size.

Next, we will analyze the automatic size change mechanism for the initial ArrayList and the addition and deletion of its List objects. 1. Initial Capacity and size values.

From the source code of the ArrayList constructor, we can easily see that the initial Capacity value (initialCapacity) can be directly specified by the user or saved by the Collection set specified by the user.

The number of stored objects is determined. If not specified, the system defaults to 10. The value of size is declared as an int variable. The default value is 0. When you specify a Collection to create an ArrayList, the value of size is equal

InitialCapacity. 2. add () method

The source code of this method is as follows:

Public boolean add (E e ){
EnsureCapacityInternal (size + 1 );
ElementData [size ++] = e; // The auto-increment size when an object is added.
Return true;
}

The ensureCapacityInternal called in the method is mainly used to adjust the capacity and modify the direction of the elementData array. Three methods are called. The core of the method is the grow method:
Private void ensureCapacityInternal (int minCapacity ){
ModCount ++; // defines the parent class javasactlist of ArrayList, which is used to store the number of structural modifications.
// Overflow-conscious code
If (minCapacity-elementData. length> 0)
Grow (minCapacity );
}

Private void grow (int minCapacity ){
// Overflow-conscious code
Int oldCapacity = elementData. length;
Int newCapacity = oldCapacity + (oldCapacity> 1); // The new capacity is increased to 1.5 times of the original capacity, and the first shift to the right is about the original value divided by 2.
If (newCapacity-minCapacity <0)
NewCapacity = minCapacity;
If (newCapacity-MAX_ARRAY_SIZE> 0)
NewCapacity = hugeCapacity (minCapacity );
// MinCapacity is usually close to size, so this is a win:
ElementData = Arrays. copyOf (elementData, newCapacity );
}

Private static int hugeCapacity (int minCapacity ){
If (minCapacity <0) // overflow
Throw new OutOfMemoryError ();
Return (minCapacity> MAX_ARRAY_SIZE )?
Integer. MAX_VALUE:
MAX_ARRAY_SIZE; // MAX_ARRAY_SIZE and Integer. MAX_VALUE are constants. For details, see the annotations below.
}
Through the above code, we can see that the idea of Automatically increasing the ArrayList size in java is: when adding an object to the ArrayList, add 1 to the number of the original object. If the length is greater than the length of the original underlying array, the new length will apply.

Create a copy of the original array, modify the original array, and point to the new array. The original array is automatically discarded (java garbage collection mechanism will automatically recycle ). The size is added to the array, and the value increases by 1.

Note:

// A constant defined in this class to allocate the maximum size of an array. Some VMs retain the header in the array and try to allocate a larger array may cause OutOfMemoryError:

The size exceeds the VM limit.
Private static final int MAX_ARRAY_SIZE = Integer. MAX_VALUE-8;

// In the java. lang. Integer class, constants MIN_VALUE and MAX_VALUE are as follows:
Public static final int MIN_VALUE = 0x80000000; // lower bound of the integer value range:-2147483648
Public static final int MAX_VALUE = 0x7fffffff; // upper bound of integer values: 2147483647

// In java. util. javasactlist, modCount is defined as follows:
Protected transient int modCount = 0; 3. remove () method

The source code of This refactoring method is as follows (the rest will not be described ):
Public E remove (int index ){
RangeCheck (index );

ModCount ++;
E oldValue = elementData (index );

Int numMoved = size-index-1;
If (numMoved> 0)
System. arraycopy (elementData, index + 1, elementData, index,
NumMoved); // move the list object
ElementData [-- size] = null; // The array is moved one by one, and the size is automatically reduced. The empty position is null. The Junk collector is responsible for the destruction of specific objects.
Return oldValue;
}

Private void rangeCheck (int index) {// border check
If (index <0 | index> = this. size)
Throw new IndexOutOfBoundsException (outOfBoundsMsg (index ));
}

E elementData (int index) {// gets the object where the specified index is located
Return (E) elementData [index];
}

By learning the remove () source code, we can easily see that the core of the ArrayList size change method is similar to the add () method, which is the same as the array COPY method.

In addition, if necessary, you can also specify the capacity of the ArrayList instance to effectively reduce the time cost. It is implemented by calling ensureCapacityInternal, source code

As follows:
Public void ensureCapacity (int minCapacity ){
If (minCapacity> 0)
EnsureCapacityInternal (minCapacity );
}

Because the size is private, java provides a method to access it:
Public int size (){
CheckForComodification ();
Return this. size;
}

To sum up, when you append an object to ArrayList, Java always needs to calculate whether Capacity is appropriate. If Capacity is insufficient, copy the original array to

In the new array, and assign a value to the original array variable, pointing to the new array. At the same time, the size is incremented by 1. When deleting an object, you first use the copy method to move the object after the specified index one-bit (if

If yes). Then, set the null location to the Junk collector for destruction. The size is automatically reduced by 1.

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.