Java8 ArrayList Source Reading

Source: Internet
Author: User
Tags concurrentmodificationexception

Reprinted from Java8 ArrayList source reading

This article is based on jdk1.8

There are three classes in the Java collection library:list,queue,set

Where list, there are three sub-implementation classes:arraylist,vector,linkedlist

Http://hg.openjdk.java.net/jdk8/jdk8/jdk/file/tip/src/share/classes/java/util/ArrayList.java

Implementation principle
transient Object[] Elementdata;  // an array of elements to store Private int size;  // the number of elements actually stored

The ArrayList layer uses an array of type object to hold the data, and the size variable represents the number of elements that the list actually holds

Add,remove,get,set,contains operation

Both the get and set methods are used to manipulate the data directly by array subscript, and the time Complexity is O (1).

 Public Booleancontains (Object o) {returnIndexOf (o) >= 0;} Public intindexOf (Object o) {//Traverse all elements to find the same element, return the subscript of the element,//if the element is null, the address is directly compared, otherwise the Equals method is used to compare    if(O = =NULL) {         for(inti = 0; i < size; i++)            if(elementdata[i]==NULL)                returni; } Else {         for(inti = 0; i < size; i++)            if(O.equals (Elementdata[i]))returni; }    return-1;}

Add

 Public BooleanAdd (e e) {ensurecapacityinternal (size+ 1);//Expansion Detectionelementdata[size++] = e;//adding new elements to the end    return true;} Public voidAddintindex, E Element)    {Rangecheckforadd (index); Ensurecapacityinternal (Size+ 1);//Expansion Detection//using the System.arraycopy method, move the element behind the index 1 bits backwardsSystem.arraycopy (Elementdata, index, Elementdata, index + 1, size-index); Elementdata[index]= element;//store element to index positionsize++;}

Remove

 PublicE Remove (intindex)  {Rangecheck (index); //cross-border detectionModcount++; E OldValue= Elementdata (index);//Old value    intnummoved = size-index-1;//number of elements that need to be moved    if(nummoved > 0) system.arraycopy (elementdata, index+1, Elementdata, Index, nummoved); elementdata[--size] =NULL;//allows the JVM to perform GC operations to avoid leaks    returnOldValue;}
Scaling strategy

The ArrayList is stored using an array, and the expansion occurs when the array size is not sufficient to hold the new element.

In the add operation, the ArrayList first calls the Ensurecapacityinternal method for the expansion detection.

If the array size is insufficient, the expansion is automatic, and if the size after expansion exceeds the maximum size of the array, an exception is thrown.

Ensurecapacityinternal (size + 1);

ArrayList expansion plan, there are two steps:1. Size detection, 2. Expansion

    • Size detection :

      • Detects if the array size is 0, and if so, uses the default expansion size

      • Detects if expansion is required and expands only if the minimum required size of the array is greater than the current array size

    • expansion : Grow and Hugecapacity

      • Array out-of-bounds judgment

      • Copy the original data into a new array

Private voidEnsurecapacityinternal (intmincapacity) {    //arraylist<integer> a = new arraylist<integer> () or read by serialization, the element size is 0 o'clock, the underlying array is a null array//if the underlying array size is 0, the default capacity size is used    if(Elementdata = =empty_elementdata) {mincapacity=Math.max (default_capacity, mincapacity); } ensureexplicitcapacity (mincapacity);}Private voidEnsureexplicitcapacity (intmincapacity) {    //data structure changes, and fail-fast mechanism, in the use of iterators, only through the method of iterators (such as iterators add,remove, etc.), modify the data structure of the list,//If you use the list method (such as add,remove in list), modifying the data structure of the list will throw Concurrentmodificationexceptionmodcount++; //the Grow method is called when the current array size is insufficient, and automatic expansion    if(Mincapacity-elementdata.length > 0) grow (mincapacity);}Private Static Final intMax_array_size = integer.max_value-8;Private voidGrowintmincapacity) {    //overflow-conscious Code    intOldcapacity =elementdata.length; //new capacity size = 1.5 times times the size of the original capacity    intNewcapacity = oldcapacity + (oldcapacity >> 1); if(Newcapacity-mincapacity < 0)//overflow judgment, such as Mincapacity = INTEGER.MAX_VALUE/2, oldcapacity = minCapacity-1Newcapacity =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 intHugecapacity (intmincapacity) {    if(Mincapacity < 0)//Overflow        Throw NewOutOfMemoryError (); return(Mincapacity > Max_array_size)?Integer.MAX_VALUE:MAX_ARRAY_SIZE;}
Implementation of Fail-fast mechanism

The fail-fast mechanism, also known as the "fast failure" mechanism, is an error detection mechanism in the Java collection.

In the iterative process of the collection, in addition to iterators can be modified on the data structure of the collection, and other changes to the data structure of the collection, will throw concurrentmodificationexception error.

Here, the so-called 进行数据结构上进行修改 , refers to the stored object, the Add,set,remove operation, and then the data changes.

ArrayList, there is a modcount variable, each time add,set,remove and other operations, will be executed modcount++.

When you get an iterator for ArrayList, the Modcount in ArrayList is saved in the iteration.

Each time you perform an operation such as Add,set,remove, a check is performed, the Checkforcomodification method is called, and the Modcount is compared.

If the modcount in the iterator and the Modcount in the list are different, the concurrentmodificationexception is thrown

Final void checkforcomodification () {    if (expectedmodcount! = ArrayList.  This. Modcount)        thrownew  concurrentmodificationexception ();
Usage Scenarios

ArrayList's usage scenarios are mainly considered in terms of their pros and cons:

Advantages:

Get,set, Time complexity O (1)

Add (usually inserted at the end), Time complexity O (1), worst case (insert data to head), Time complexity O (n)

The data store is sequential

Disadvantages:

Remove, time complexity O (n), best case (remove end element), Time complexity O (1)

ArrayList the bottom layer uses arrays to store data, arrays are not automatically expandable, so in the case of expansion, a large number of elements need to be moved.

When the ArrayList size is large, there is a waste of space (you can clear the free space by TrimToSize method)

The size of the array is limited by the JVM and the machine, and ArrayList throws an exception when the expansion exceeds the upper limit.

Insert operations, data volume is small, in order to store, you can consider using ArrayList

In the case of multithreading:

ArrayList all operations are not synchronous, so ArrayList is not thread-safe.

If you consider thread safety, you can use copyonwritearraylist or an external sync ArrayList (List list = Collections.synchronizedlist (new ArrayList (...)); )

Thinking

In the 1.remove method, why is the element corresponding to the array set to NULL?

ArrayList internal use of arrays to implement a set of Management objects mechanism, the remove operation, the number of elements has been-1, ArrayList that the object has been removed, should be recycled by the JVM.

However, for the JVM, the value is still stored in the array, and ArrayList holds a reference to the object, which is not recycled by the JVM when the JVM is in GC, which results in a memory leak.

2. In the method of finding the element (such as indexof), why do I need to determine the null value of the element?

Determine if the object is equal, there are two aspects, 1. The address of the object store; 2. The contents of the object.

= =, is used to compare the address of two objects is equal, generally speaking, the address of two objects is the same, then the two objects can be considered the same object

The Equals method, which is used to compare the contents of an object, can, of course, overload the method and directly compare the object's address; the Equals method of the object is the comparison address.

In general, overloading the Equals method while overloading the Hashcode method with the overloaded Hashcode method must follow 6 principles:

    • Reflexivity: Must return true for any non-null reference value X,x.equals (x)

    • Transitivity: For any non-null reference value x, Y, Z, if X.equals (y) is true, and Y.equals (z) is true, then X.equals (z) must be True

    • Symmetry: For any non-null reference value x, Y, if X.equals (y) is true, then y.equals (x) must be True

    • Non-nullability: x,x.equals (NULL) must be false for any non-null reference value

    • Consistency: For any non-null reference value, x, Y, if you call the Equals method multiple times, if the value of x and Y is not changed, then X.equals (y) will be consistent to return true or false

Why overload the Equals method, typically overloading the Hashcode method?
Overloaded with the Equals method, you can not overload the Hashcode method, but in general, this is not recommended.
Hashcode method, use to find out the object's hash value,
The overloaded Hashcode method is primarily designed to improve the efficiency of some containers (such as hashmap,hashtable) for hashing, and also to avoid errors (such as the operation of HashSet containers).

For the null value of the element to judge, I think mainly for efficiency considerations, if it is a null value, you can directly compare the address, not the null value, you need to compare by the Equals method, because ArrayList is generic,

So its added elements may overload the Equals method, customizing the principle of judgment.

In the 3.grow method, the new capacity size is judged, why is the max_array_size defined?

ArrayList the underlying storage is implemented using arrays, so the size of the ArrayList storage file is bound to be limited by the size of the array, so in the expansion, you can see ArrayList to the new capacity size of the logical judgment.

affect the maximum value of the array:

    • Theoretical maximum value is integer.max_value (2^32-1)

    • Object header limits, different types of elements, the maximum value that can be created for an array is different, byte is 1 bytes, int is 4 bytes

      For example, the JVM available memory is 1m,32 bit machine,

        
      int New int [1024x768 * 1024/4]; byte New byte [1024 * 1024];
    • JVM Available Memory size limit

      For example, the JVM available memory is 1m,32 bit machine,

      byte byte [1024 * 1024]

As for why max_array_size = integer.max_value-8;

Mainly in 64 for the machine, the object of the

Java8 ArrayList Source Reading

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.