Arraylist source code reading

Source: Internet
Author: User
Arraylist implementation Inheritance relationshipJava. Lang. Object-java. util. abstractcollection <E>-java. util. abstractlist <E>-java. util. arraylist <E> Implementation Interface

Serializable, cloneable, iterable <E>, collection <E>, list <E>, randomaccess

Key attributesPrivate transient object [] elementdata; // The transient modifier is not serialized, but the serializable interface is implemented. The readobject and writeobject methods are rewritten to serialize only the actual size of private int size. // the actual size Common Methods
public boolean add(E e) {ensureCapacity(size + 1);  // Increments modCount!!elementData[size++] = e;return true;}
 public void add(int index, E element) {if (index > size || index < 0)    throw new IndexOutOfBoundsException("Index: "+index+", Size: "+size);ensureCapacity(size+1);  // Increments modCount!!System.arraycopy(elementData, index, elementData, index + 1, size - index); //elementData[index,size) --> elementData[index+1,size+1)elementData[index] = element;size++; }
Ensurecapacity expansion method: you can modify modcount to implement fast-fail iteration.
Public void ensurecapacity (INT mincapacity) {modcount ++; int oldcapacity = elementdata. length; If (mincapacity> oldcapacity) {object olddata [] = elementdata; int newcapacity = (oldcapacity * 3)/2 + 1; // 0.5 times expansion policy if (newcapacity <mincapacity) newcapacity = mincapacity; // mincapacity is usually close to size, so this is a win: elementdata = arrays. copyof (elementdata, newcapacity );}}
Remove Method, move index + 1 and its elements, and set the last element to null to help GC Recycle
 public E remove(int index) {RangeCheck(index);modCount++;E oldValue = (E) elementData[index];int numMoved = size - index - 1;if (numMoved > 0)    System.arraycopy(elementData, index+1, elementData, index,     numMoved); //elementData[index+1,size) -->elementData[index,size-1)elementData[--size] = null; // Let gc do its workreturn oldValue; }
public boolean remove(Object o) {if (o == null) {            for (int index = 0; index < size; index++)if (elementData[index] == null) {    fastRemove(index);    return true;}} else {    for (int index = 0; index < size; index++)if (o.equals(elementData[index])) {    fastRemove(index);    return true;}        }return false;}
Fastremove is a private method and no old value is returned
private void fastRemove(int index) {        modCount++;        int numMoved = size - index - 1;        if (numMoved > 0)            System.arraycopy(elementData, index+1, elementData, index,                             numMoved);        elementData[--size] = null; // Let gc do its work}
Rewrite readobject and writeobject for serialization and deserialization to ensure that only arrays of the actual size are serialized to avoid space waste. We can see that there is a fast fail judgment when writeobject is used.
private void readObject(java.io.ObjectInputStream s)        throws java.io.IOException, ClassNotFoundException {// Read in size, and any hidden stuffs.defaultReadObject();        // Read in array length and allocate array        int arrayLength = s.readInt();        Object[] a = elementData = new Object[arrayLength];// Read in all elements in the proper order.for (int i=0; i<size; i++)            a[i] = s.readObject();}
 private void writeObject(java.io.ObjectOutputStream s)        throws java.io.IOException{// Write out element count, and any hidden stuffint expectedModCount = modCount;s.defaultWriteObject();        // Write out array length        s.writeInt(elementData.length);// Write out all elements in the proper order.for (int i=0; i<size; i++)            s.writeObject(elementData[i]);if (modCount != expectedModCount) {            throw new ConcurrentModificationException();        }}
The arraylist implementation of the iterator supports two types of iterators: IteratorAnd Listiterator(Bidirectional iteration) to implement iterator implementation in javasactlist by using the internal class javasactlist $ itr Itr class definitionPrivate class itr implements iterator <E> Attributes includeInt cursor = 0; // The subscript int lastret =-1 for the current traversal; // The subscript returned by next or previous is recently called. After you call the Remove Method to delete an element, reset to-1int expectedmodcount = modcount; // this parameter is used to detect concurrent modifications during traversal. Important MethodsHasnext and next Methods
public boolean hasNext() {       return cursor != size();}public E next() {       checkForComodification();       try {E next = get(cursor);lastRet = cursor++;return next; } catch (IndexOutOfBoundsException e) {checkForComodification();throw new NoSuchElementException();}}
Remove Method
public void remove() {    if (lastRet == -1)throw new IllegalStateException();            checkForComodification();    try {AbstractList.this.remove(lastRet);if (lastRet < cursor)    cursor--;lastRet = -1;expectedModCount = modCount;    } catch (IndexOutOfBoundsException e) {throw new ConcurrentModificationException();    }}
-Before the next and remove methods, you must call checkforcomodification to check whether the container is modified. If the container is modified, concurrentmodificationexception is thrown. Calling the iterator's own remove method will not cause concurrentmodificationexception. This is because after the element is deleted, expectedmodcount is reset (expectedmodcount = modcount)-You can see that after the delete method is executed, set lastret to-1, and an exception will be thrown in the next call. ListiteratorImplemented through the internal class listitr, which inherits the one-way iterator itr and implements the two-way iterator interface listiterator Listitr class definitionPrivate class listitr extends itr implements listiterator <E> supports specifying the cursor position for Construction
ListItr(int index) {      cursor = index;}
The previous and next methods have different lastret settings. The next method is the value before cursor is not added with 1, while the previous method is the value after cursor minus 1.
public boolean hasPrevious() {    return cursor != 0;}public E previous() {checkForComodification();        try {                int i = cursor - 1;                E previous = get(i);                lastRet = cursor = i;                return previous;        } catch (IndexOutOfBoundsException e) {                checkForComodification();                throw new NoSuchElementException();        }}
The Set Method modifies the value of this element at lastret. The value of the element is cursor-1 when previous is traversed forward, and the value of the element is cursor once traversed backward.
public void set(E e) {    if (lastRet == -1)throw new IllegalStateException();            checkForComodification();    try {AbstractList.this.set(lastRet, e);expectedModCount = modCount;    } catch (IndexOutOfBoundsException ex) {throw new ConcurrentModificationException();    }}
Add the add method to the current cursor position and add the cusor to 1
public void add(E e) {        checkForComodification();try {    AbstractList.this.add(cursor++, e);    lastRet = -1;    expectedModCount = modCount;} catch (IndexOutOfBoundsException ex) {    throw new ConcurrentModificationException();}}
Conclusion 1. arraylist is implemented through an array. It adopts a doubling policy instead of a specified constant for expansion. The complexity of adding an array at a specified position is O (1) 2. the array declared as transient in the arraylist will not be serialized. It will rewrite readobject and writeobject for deserialization and serialization to ensure that only the array elements of the valid size are serialized. 3. The iterator supports fast-fail. concurrentmodificationexception is thrown when an element is added or deleted due to a change in the container structure during the iteration, which is implemented through internal modcount. Calling the Remove Method of the iterator itself and adding and set methods in the two-way iterator does not cause concurrent modification exceptions. 4. in the iterator, you need to call the next or previous internal lastret member to set the remove and set methods to a valid index. After the remove method is called, lastret is reset to-1, it cannot be called repeatedly. Arraylist for openjdk source code reading

Arraylist source code 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.