HashMap source code analysis --jdk1.8

JDK1.8

ArrayList source code analysis --jdk1.8
LinkedList source code analysis --jdk1.8
HashMap source code analysis --jdk1.8

HashMap Overview

  1. HashMap expansion arrays can be dynamically, based on a set of arrays, linked lists, red-black tree implementation.
  2. HashMap support for the key value, cloning, sequencing, random elements, key value can not be repeated repetition, can be null.
  3. HashMap initial default length 16, expansion exceeds 2 times, the fill factor 0.75f.
  When 4.HashMap when the list is longer than the array size is greater than 8 and 64, into a red-black tree structure list structure.

HashMap data structure

  The data structure is the essence of a collection of lies, data structures often limit the role and focus of the collection, understand the various data structures we analyze the source code is the only way.
  HashMap data structure follows: Array + + black tree list
HashMap source code analysis --jdk1.8

HashMap source code analysis

/*
 * 用数组+链表+红黑树实现的集合,支持键值对查找
 */
public class HashMap<K,V> extends AbstractMap<K,V>
    implements Map<K,V>, Cloneable, Serializable {

    private static final long serialVersionUID = 362498820763181265L;

    /**
     * 默认初始容量-必须是2的幂
     * 1*2的4次方    默认长度16
     */
    static final int DEFAULT_INITIAL_CAPACITY = 1 << 4;

    /**
     * 最大容量 
     * 1*2的30次方   最大容量1073741824
     */
    static final int MAXIMUM_CAPACITY = 1 << 30;

    /**
     *  默认的填充因子  0.75
     *  负载因子0.75是对空间和时间效率的一个平衡选择,建议大家不要修改,除非在时间和空间比较特殊的情况下,
     *  如果内存空间很多而又对时间效率要求很高,可以降低负载因子Load factor的值;
     *  相反,如果内存空间紧张而对时间效率要求不高,可以增加负载因子loadFactor的值,这个值可以大于1
     */
    static final float DEFAULT_LOAD_FACTOR = 0.75f;

    /**
     * 当桶(bucket)上的节点数大于这个值时会转成红黑树
     */
    static final int TREEIFY_THRESHOLD = 8;

    /**
     * 当桶(bucket)上的节点数小于这个值时树转链表
     */
    static final int UNTREEIFY_THRESHOLD = 6;

    /**
     * 桶中结构转化为红黑树对应的table的最小大小
     */
    static final int MIN_TREEIFY_CAPACITY = 64;

    /**
     * Node是单向链表,它实现了Map.Entry接口
     */
    static class Node<K,V> implements Map.Entry<K,V> {
        final int hash;
        final K key;
        V value;
        Node<K,V> next;
      //构造函数Hash值 键 值 下一个节点
        Node(int hash, K key, V value, Node<K,V> next) {
            this.hash = hash;
            this.key = key;
            this.value = value;
            this.next = next;
        }

        public final K getKey()        { return key; }
        public final V getValue()      { return value; }
        public final String toString() { return key + "=" + value; }

        public final int hashCode() {
            return Objects.hashCode(key) ^ Objects.hashCode(value);
        }

        // 实现接口定义的方法,且该方法不可被重写
        // 设值,返回旧值
        public final V setValue(V newValue) {
            V oldValue = value;
            value = newValue;
            return oldValue;
        }
      //构造函数Hash值 键 值 下一个节点
      /*
       * 重写父类Object的equals方法,且该方法不可被自己的子类再重写
       * 判断相等的依据是,只要是Map.Entry的一个实例,并且键键、值值都相等就返回True
       */
        public final boolean equals(Object o) {
            if (o == this)
                return true;
            if (o instanceof Map.Entry) {
                Map.Entry<?,?> e = (Map.Entry<?,?>)o;
                if (Objects.equals(key, e.getKey()) &&
                    Objects.equals(value, e.getValue()))
                    return true;
            }
            return false;
        }
    }

HashMap inherit and implement analysis

HashMap source code analysis --jdk1.8
   The extends AbstractMap HashMap
   AbstractMap the extends Object
  Java classes inherit all Object, so HashMap inheritance structure as FIG.
   1. AbstractList is an abstract class that implements List <E> interfaces, List <E> List defines the general method, and can have an abstract class AbstractList abstract methods, may also have specific implementations, some of the interfaces implemented AbstractList general method to achieve the basic add / get / indexOf / iterator / subList RandomAccessSubList method, ArrayList and then inherit AbstractList, to get the general basis of the method /, and then himself in the realization of some of their own unique ways, such benefits are: to make the code more concise, inheritance class structure of the bottom of the common methods to reduce duplicate code.
   2.ArrayList implements List <E>, RandomAccess, Cloneable , Serializable Interface
     1) List <E> interface inherits from ArrayList since AbstractList abstract class, and has achieved AbstractList List interface, ArrayList class why they would go to achieve the List interface it? We look down with a question:

public class Demo1 extends ArrayList {
    public static void main(String[] args) {
                //返回[]
        System.out.println(Arrays.toString(Demo1.class.getInterfaces()));
    }
public class Demo2 implements Serializable {
    public static void main(String[] args) {
                //返回[interface java.io.Serializable]
        System.out.println(Arrays.toString(Demo2.class.getInterfaces()));
    }
public class Test{
    public static void main(String[] args) {
                Serializable c1 = new Demo1();//未显示实现接口
                Serializable c2 = new Demo2();//显示实现接口
                Serializable proxy2 = createProxy(c2);
                proxy2.foo();
                Serializable proxy1 = createProxy(c1);
                proxy1.foo();
 }

private static <T> T createProxy(final T obj) {
        final InvocationHandler handler = new InvocationHandler() {
            @Override
            public Object invoke(Object proxy, Method method, Object[] args)
                    throws Throwable {
                return method.invoke(obj, args);
            }
        };
                //实现接口代理,Demo1报错,Demo2成功
                //java.lang.ClassCastException: $Proxy1 cannot be cast to
                //example.Test$Serializable
        return (T) Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj
                .getClass().getInterfaces(), handler);
    }

In this way we can see this design makes sense, therefore, this is not a mistake, it is likely the author Josh Bloch To facilitate agent and well-designed.
Reference to: develop a collection of Josh says
     2) RandomAccess interface, which is a marker interface, this marker interface is generally used to implement List, to indicate that they support fast (generally constant time) random access, the main purpose of this interface is allow general algorithm to change their behavior in order to be applied to a random or sequential access lists provide good performance achieved if the interface using common for loops to traverse, higher performance, and does not implement this interface, use iterator iterate , so that a higher performance, e.g. linkedList. So the mark of us just to let us know what kind of a way to get better data performance
     3) Cloneable interface, you can use Object.Clone () method.
     4) Serializable interfaces, serial interfaces, indicating that the class can be serialized, what is serialized? Simply put, into a stream of bytes that can be transmitted from the class deserialized, it is to become the original byte stream from the class

ArrayList core analysis methods

1. add method (4 types overload implemented) - increasing    

HashMap source code analysis --jdk1.8

     1) add (E); // default to the element directly to the end

/**
 * 新增元素
 */
public boolean add(E e) {
    //赋值初始长度  或者扩容,新增元素,当前实际size+1的长度
        ensureCapacityInternal(size + 1);  // Increments modCount!!
        //添加元素
        elementData[size++] = e;
        return true;
}
    /**
     * 确保elemenData数组有合适的大小
     * 如果元素为空,则复制长度默认为10 或者更大
    * @author jiaxiaoxian
    * @date 2019年2月12日 
     */
    private void ensureCapacityInternal(int minCapacity) {
            if (elementData == EMPTY_ELEMENTDATA) {//如果数组为空,则从size+1的值和默认值10中取最大的
                    minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
            }
            ensureExplicitCapacity(minCapacity);
    }
/**
* 确保elemenData数组有合适的大小
* @author jiaxiaoxian
* @date 2019年2月12日 
* 如果长度大于元素长度则扩容
 */
private void ensureExplicitCapacity(int minCapacity) {
    //记录修改次数,迭代中不一致会触发fail-fast机制,因此在遍历中删除元素的正确做法应该是使用Iterator.remove()
    modCount++;
    if (minCapacity - elementData.length > 0)
        grow(minCapacity); //扩容
}
/**
 * 扩容
 */
private void grow(int minCapacity) {
    int oldCapacity = elementData.length; // 旧容量
    int newCapacity = oldCapacity + (oldCapacity >> 1); // 新容量为旧容量的1.5倍
    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);
}
    //如果小于0 就报错,如果大于最大值 则取最大值
private static int hugeCapacity(int minCapacity) {
    if (minCapacity < 0) // overflow
        throw new OutOfMemoryError();
    return (minCapacity > MAX_ARRAY_SIZE) ?
        Integer.MAX_VALUE :
        MAX_ARRAY_SIZE;
}

     2) add (int index, E element); // to the specified index, the additive element

/**
 * 给指定下标,添加元素
 */
public void add(int index, E element) {
    //判断下标是否越界
    rangeCheckForAdd(index);
    //赋值初始长度  或者扩容
    ensureCapacityInternal(size + 1);  // Increments modCount!!
    //将源数组中从index位置开始后的size-index个元素统一后移一位
    System.arraycopy(elementData, index, elementData, index + 1,
                     size - index);
    //赋值
    elementData[index] = element;
    size++;
}
/**
 * 判断下标是否越界
 */
private void rangeCheckForAdd(int index) {
    if (index > size || index < 0)
        throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
}
/**
 *     src:源数组
 *   srcPos:源数组要复制的起始位置
 *   dest:目的数组
 *   destPos:目的数组放置的起始位置
 *   length:复制的长度
 *   注意:src 和 dest都必须是同类型或者可以进行转换类型的数组
 */
public static native void arraycopy(Object src,  int  srcPos,
                                    Object dest, int destPos,
                                    int length);

     3) addAll (Collection c) <extends E?>; // add an element of type Collection

/**
 * 按照指定collection的迭代器所返回的元素顺序,将该collection中的所有元素添加到此列表的尾部
 */
public boolean addAll(Collection<? extends E> c) {
    Object[] a = c.toArray();
    int numNew = a.length;
    ensureCapacityInternal(size + numNew);  // Increments modCount
    //将数组a[0,...,numNew-1]复制到数组elementData[size,...,size+numNew-1]
    System.arraycopy(a, 0, elementData, size, numNew);
    size += numNew;
    return numNew != 0;
}

     4) addAll (int index, Collection c) <extends E?>; // the specified location, the type of element added Collection

/**
 * 从指定的位置开始,将指定collection中的所有元素插入到此列表中,新元素的顺序为指定collection的迭代器所返回的元素顺序
 */
public boolean addAll(int index, Collection<? extends E> c) {
    //判断下标是否越界
    rangeCheckForAdd(index);
    Object[] a = c.toArray();
    int numNew = a.length;
    ensureCapacityInternal(size + numNew);  // Increments modCount
    int numMoved = size - index;
    //先将数组elementData[index,...,index+numMoved-1]复制到elementData[index+numMoved,...,index+2*numMoved-1]
    //即,将源数组中从index位置开始的后numMoved个元素统一后移numNew位
    if (numMoved > 0)
        System.arraycopy(elementData, index, elementData, index + numNew,
                         numMoved);
    System.arraycopy(a, 0, elementData, index, numNew);
    size += numNew;
    return numNew != 0;
}

Summary:
   Under normal circumstances would be 1.5 times the expansion in special cases (new extension has reached the maximum array size) only takes a maximum value.
   

2.remove method (4 types overload implemented) - deleted

HashMap source code analysis --jdk1.8

     1) remove (int index); // delete the element according to the specified index     

/**
 * 根据指定下标 删除元素
 */
public E remove(int index) {
    //判断索引是否越界
    rangeCheck(index);
    modCount++;
    //获取旧元素
    E oldValue = elementData(index);
    //将数组elementData中index位置之后的所有元素向前移一位
    int numMoved = size - index - 1;
    if (numMoved > 0)
        System.arraycopy(elementData, index+1, elementData, index,
                         numMoved);
    //将原数组最后一个位置置为null,由GC清理
    elementData[--size] = null; // clear to let GC do its work
    return oldValue;
}       

     2) remove (Object o); // delete elements in accordance with the specified element 

 /**
 * 移除ArrayList中首次出现的指定元素(如果存在),ArrayList中允许存放重复的元素
 */
public boolean remove(Object o) {
    // 由于ArrayList中允许存放null,因此下面通过两种情况来分别处理。
    if (o == null) {
        for (int index = 0; index < size; index++)
            if (elementData[index] == null) {
                //私有的移除方法,跳过index参数的边界检查以及不返回任何值
                fastRemove(index);
                return true;
            }
    } else {
        for (int index = 0; index < size; index++)
            if (o.equals(elementData[index])) {
                fastRemove(index);
                return true;
            }
    }
    return false;
}   
/*
 * 根据下标快速删除元素
 */
private void fastRemove(int index) {
    modCount++;
    //将数组elementData中index位置之后的所有元素向前移一位
    int numMoved = size - index - 1;
    if (numMoved > 0)
        System.arraycopy(elementData, index+1, elementData, index,
                         numMoved);
    elementData[--size] = null; // clear to let GC do its work
}
 /**
 * 清空ArrayList,将全部的元素设为null,等待垃圾回收将这个给回收掉,所以叫clear
 */
public void clear() {
    modCount++;
    // clear to let GC do its work
    for (int i = 0; i < size; i++)
        elementData[i] = null;
    size = 0;
}

     3) removeAll (Collection c) <?>; // delete contained in the specified container c of all the elements 

/**
 * 删除ArrayList中包含在指定容器c中的所有元素
 */
public boolean removeAll(Collection<?> c) {
    //检查指定的对象c是否为空
    Objects.requireNonNull(c);
    return batchRemove(c, false);
}
 /**
 * 删除全部
* @author jiaxiaoxian
* @date 2019年2月12日 
 */
private boolean batchRemove(Collection<?> c, boolean complement) {
    final Object[] elementData = this.elementData;
    int r = 0, w = 0; //读写双指针
    boolean modified = false;
    try {
        for (; r < size; r++)
            if (c.contains(elementData[r]) == complement) //判断指定容器c中是否含有elementData[r]元素
                elementData[w++] = elementData[r];
    } finally {
        // Preserve behavioral compatibility with AbstractCollection,
        // even if c.contains() throws.
        if (r != size) {
            System.arraycopy(elementData, r,
                             elementData, w,
                             size - r);
            w += size - r;
        }
        if (w != size) {
            // clear to let GC do its work
            for (int i = w; i < size; i++)
                elementData[i] = null;
            modCount += size - w;
            size = w;
            modified = true;
        }
    }
    return modified;
}

     4) removeIf (Predicate filter) <super E?>; // filter element (deletion) set according to certain rules 

/**
 * 按照一定规则过滤(删除)集合中的元素
 * 如:idList.removeIf(id -> id == nul);
    *   去掉 List idList 集合中id 为 null 的
 * @param filter
 * @return
 */
@Override
public boolean removeIf(Predicate<? super E> filter) {
    Objects.requireNonNull(filter);
    // figure out which elements are to be removed
    // any exception thrown from the filter predicate at this stage
    // will leave the collection unmodified
    int removeCount = 0;
    final BitSet removeSet = new BitSet(size);
    final int expectedModCount = modCount;
    final int size = this.size;
    for (int i=0; modCount == expectedModCount && i < size; i++) {
        @SuppressWarnings("unchecked")
        final E element = (E) elementData[i];
        if (filter.test(element)) {
            removeSet.set(i);
            removeCount++;
        }
    }
    if (modCount != expectedModCount) {
        throw new ConcurrentModificationException();
    }

    // shift surviving elements left over the spaces left by removed elements
    final boolean anyToRemove = removeCount > 0;
    if (anyToRemove) {
        final int newSize = size - removeCount;
        for (int i=0, j=0; (i < size) && (j < newSize); i++, j++) {
            i = removeSet.nextClearBit(i);
            elementData[j] = elementData[i];
        }
        for (int k=newSize; k < size; k++) {
            elementData[k] = null;  // Let gc do its work
        }
        this.size = newSize;
        if (modCount != expectedModCount) {
            throw new ConcurrentModificationException();
        }
        modCount++;
    }

    return anyToRemove;
}

Summary:
   Remove the specified function of the user removes the target element, will at this time to the end of the specified index of the array element is moved forward by one unit, and the last element of the array will be set to null, then this is to facilitate the entire array is not when used, will be GC, it can be used as a small trick.

3.set method - change

/**
 * 覆盖指定下标元素
 */
public E set(int index, E element) {
    //判断索引是否越界
    rangeCheck(index);
    //获取旧元素
    E oldValue = elementData(index);
    //覆盖为新元素
    elementData[index] = element;
    //返回旧元素
    return oldValue;
}
/**
 * 判断下标是否越界
 */
private void rangeCheck(int index) {
    if (index >= size)
        throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
}

4.get method - check

 /**
 * 返回指定索引的值
 */
public E get(int index) {
    //判断索引是否越界
    rangeCheck(index);
    return elementData(index);
}
/**
* @author jiaxiaoxian
* @date 2019年2月12日 
* 返回下标元素的 值
 */
@SuppressWarnings("unchecked")
E elementData(int index) {
    return (E) elementData[index];
}

5.indexOf method - Find subscript

/**
 * 查找下标, 如果为null,直接和null比较,返回下标
 */
public int indexOf(Object o) {
    if (o == null) {
        for (int i = 0; i < size; i++)
            if (elementData[i]==null)
                return i;
    } else {
        for (int i = 0; i < size; i++)
            if (o.equals(elementData[i]))
                return i;
    }
    return -1;
}
/**
 * 查找最后出现的下标,从大往下循环查找
 */
public int lastIndexOf(Object o) {
    if (o == null) {
        for (int i = size-1; i >= 0; i--)
            if (elementData[i]==null)
                return i;
    } else {
        for (int i = size-1; i >= 0; i--)
            if (o.equals(elementData[i]))
                return i;
    }
    return -1;
}

Method 6.clone - Cloning

 /**
 * 复制,返回此ArrayList 的浅拷贝
 */
public Object clone() {
    try {
        ArrayList<?> v = (ArrayList<?>) super.clone();
        v.elementData = Arrays.copyOf(elementData, size);
        v.modCount = 0;
        return v;
    } catch (CloneNotSupportedException e) {
        // this shouldn't happen, since we are Cloneable
        throw new InternalError(e);
    }
}

7.trimToSize - Remove redundant capacity

/**
 * 判断数据实际容量大小,删除自动增长后冗余的容量
 * 该方法用于回收多余的内存。也就是说一旦我们确定集合不在添加多余的元素之后,调用 trimToSize() 方法会将实现集合的数组大小刚好调整为集合元素的大小。
 *   注意:该方法会花时间来复制数组元素,所以应该在确定不会添加元素之后在调用
 */
public void trimToSize() {
    modCount++;
    if (size < elementData.length) {
        elementData = Arrays.copyOf(elementData, size);
    }
}

8.Itr inner classes - similar Iterator, can help us to traverse List, CRUD etc.

/**
 * 实例化一个Itr对象,并返回
 */
public Iterator<E> iterator() {
    return new Itr();
}

/**
 * 内部类,类似Iterator,可以帮我们对List进行遍历,增删改查等
 */
private class Itr implements Iterator<E> {
    int cursor;       // index of next element to return 下一个元素
    int lastRet = -1; // index of last element returned; -1 if no such 当前元素
    int expectedModCount = modCount; //modCount,就是为了判断是否有多个线程访问修改

    public boolean hasNext() {
        return cursor != size;
    }

    @SuppressWarnings("unchecked")
    public E next() {
        checkForComodification();
        int i = cursor;
        if (i >= size)
            throw new NoSuchElementException();
        Object[] elementData = ArrayList.this.elementData;
        if (i >= elementData.length)
            throw new ConcurrentModificationException();
        cursor = i + 1;
        return (E) elementData[lastRet = i];
    }

    public void remove() {
        if (lastRet < 0)
            throw new IllegalStateException();
        checkForComodification();

        try {
            ArrayList.this.remove(lastRet);
            cursor = lastRet;
            lastRet = -1;
            expectedModCount = modCount;
        } catch (IndexOutOfBoundsException ex) {
            throw new ConcurrentModificationException();
        }
    }

    @Override
    @SuppressWarnings("unchecked")
    public void forEachRemaining(Consumer<? super E> consumer) {
        Objects.requireNonNull(consumer);
        final int size = ArrayList.this.size;
        int i = cursor;
        if (i >= size) {
            return;
        }
        final Object[] elementData = ArrayList.this.elementData;
        if (i >= elementData.length) {
            throw new ConcurrentModificationException();
        }
        while (i != size && modCount == expectedModCount) {
            consumer.accept((E) elementData[i++]);
        }
        // update once at end of iteration to reduce heap write traffic
        cursor = i;
        lastRet = i - 1;
        checkForComodification();
    }

    final void checkForComodification() {
        if (modCount != expectedModCount)
            throw new ConcurrentModificationException();
    }
}   

9.ListItr inner class - class inherits internal Itr, increasing the forward traversal is still based on this, adding elements, change the element content and other functions

/**
 * 这个类继承了内部类Itr
 * 除了拥有上一个类的功能,还增加了向前遍历,增加元素,更改元素内容等功能
 */
private class ListItr extends Itr implements ListIterator<E> {
    ListItr(int index) {
        super();
        cursor = index;
    }

    public boolean hasPrevious() {
        return cursor != 0;
    }

    public int nextIndex() {
        return cursor;
    }

    public int previousIndex() {
        return cursor - 1;
    }

    @SuppressWarnings("unchecked")
    public E previous() {
        checkForComodification();
        int i = cursor - 1;
        if (i < 0)
            throw new NoSuchElementException();
        Object[] elementData = ArrayList.this.elementData;
        if (i >= elementData.length)
            throw new ConcurrentModificationException();
        cursor = i;
        return (E) elementData[lastRet = i];
    }

    public void set(E e) {
        if (lastRet < 0)
            throw new IllegalStateException();
        checkForComodification();

        try {
            ArrayList.this.set(lastRet, e);
        } catch (IndexOutOfBoundsException ex) {
            throw new ConcurrentModificationException();
        }
    }

    public void add(E e) {
        checkForComodification();

        try {
            int i = cursor;
            ArrayList.this.add(i, e);
            cursor = i + 1;
            lastRet = -1;
            expectedModCount = modCount;
        } catch (IndexOutOfBoundsException ex) {
            throw new ConcurrentModificationException();
        }
    }
}   

10.SubList inner classes - ArrayList built based on a subset of the class

/**
 * 虽然这个类很长,其实里面的大部分方法调用都是ArrayList中的
 * ListIterator在这个类中采用匿名内部类做了一点更改,不过也很类似
 * 毕竟这个类就是根据ArrayList建一个子集类,就不赘述了
 */
private class SubList extends AbstractList<E> implements RandomAccess {
    private final AbstractList<E> parent;
    private final int parentOffset;
    private final int offset;
    int size;

    SubList(AbstractList<E> parent,
            int offset, int fromIndex, int toIndex) {
        this.parent = parent;
        this.parentOffset = fromIndex;
        this.offset = offset + fromIndex;
        this.size = toIndex - fromIndex;
        this.modCount = ArrayList.this.modCount;
    }

    public E set(int index, E e) {
         // 检验索引是否合法
        rangeCheck(index);
        //实现fail-fast机制  (迭代中不允许操作增删改)
        checkForComodification();
        // 旧值
        E oldValue = ArrayList.this.elementData(offset + index);
        // 赋新值
        ArrayList.this.elementData[offset + index] = e;
        return oldValue;
    }

    public E get(int index) {
         // 检验索引是否合法
        rangeCheck(index);
        //实现fail-fast机制  (迭代中不允许操作增删改)
        checkForComodification();
        return ArrayList.this.elementData(offset + index);
    }

    public int size() {
        checkForComodification();
        return this.size;
    }

    public void add(int index, E e) {
        rangeCheckForAdd(index);
        checkForComodification();
        parent.add(parentOffset + index, e);
        this.modCount = parent.modCount;
        this.size++;
    }

    public E remove(int index) {
        rangeCheck(index);
        checkForComodification();
        E result = parent.remove(parentOffset + index);
        this.modCount = parent.modCount;
        this.size--;
        return result;
    }

    protected void removeRange(int fromIndex, int toIndex) {
        checkForComodification();
        parent.removeRange(parentOffset + fromIndex,
                           parentOffset + toIndex);
        this.modCount = parent.modCount;
        this.size -= toIndex - fromIndex;
    }

    public boolean addAll(Collection<? extends E> c) {
        return addAll(this.size, c);
    }

    public boolean addAll(int index, Collection<? extends E> c) {
        rangeCheckForAdd(index);
        int cSize = c.size();
        if (cSize==0)
            return false;

        checkForComodification();
        parent.addAll(parentOffset + index, c);
        this.modCount = parent.modCount;
        this.size += cSize;
        return true;
    }

    public Iterator<E> iterator() {
        return listIterator();
    }

    public ListIterator<E> listIterator(final int index) {
        checkForComodification();
        rangeCheckForAdd(index);
        final int offset = this.offset;

        return new ListIterator<E>() {
            int cursor = index;
            int lastRet = -1;
            int expectedModCount = ArrayList.this.modCount;

            public boolean hasNext() {
                return cursor != SubList.this.size;
            }

            @SuppressWarnings("unchecked")
            public E next() {
                checkForComodification();
                int i = cursor;
                if (i >= SubList.this.size)
                    throw new NoSuchElementException();
                Object[] elementData = ArrayList.this.elementData;
                if (offset + i >= elementData.length)
                    throw new ConcurrentModificationException();
                cursor = i + 1;
                return (E) elementData[offset + (lastRet = i)];
            }

            public boolean hasPrevious() {
                return cursor != 0;
            }

            @SuppressWarnings("unchecked")
            public E previous() {
                checkForComodification();
                int i = cursor - 1;
                if (i < 0)
                    throw new NoSuchElementException();
                Object[] elementData = ArrayList.this.elementData;
                if (offset + i >= elementData.length)
                    throw new ConcurrentModificationException();
                cursor = i;
                return (E) elementData[offset + (lastRet = i)];
            }

            @SuppressWarnings("unchecked")
            public void forEachRemaining(Consumer<? super E> consumer) {
                Objects.requireNonNull(consumer);
                final int size = SubList.this.size;
                int i = cursor;
                if (i >= size) {
                    return;
                }
                final Object[] elementData = ArrayList.this.elementData;
                if (offset + i >= elementData.length) {
                    throw new ConcurrentModificationException();
                }
                while (i != size && modCount == expectedModCount) {
                    consumer.accept((E) elementData[offset + (i++)]);
                }
                // update once at end of iteration to reduce heap write traffic
                lastRet = cursor = i;
                checkForComodification();
            }

            public int nextIndex() {
                return cursor;
            }

            public int previousIndex() {
                return cursor - 1;
            }

            public void remove() {
                if (lastRet < 0)
                    throw new IllegalStateException();
                checkForComodification();

                try {
                    SubList.this.remove(lastRet);
                    cursor = lastRet;
                    lastRet = -1;
                    expectedModCount = ArrayList.this.modCount;
                } catch (IndexOutOfBoundsException ex) {
                    throw new ConcurrentModificationException();
                }
            }

            public void set(E e) {
                if (lastRet < 0)
                    throw new IllegalStateException();
                checkForComodification();

                try {
                    ArrayList.this.set(offset + lastRet, e);
                } catch (IndexOutOfBoundsException ex) {
                    throw new ConcurrentModificationException();
                }
            }

            public void add(E e) {
                checkForComodification();

                try {
                    int i = cursor;
                    SubList.this.add(i, e);
                    cursor = i + 1;
                    lastRet = -1;
                    expectedModCount = ArrayList.this.modCount;
                } catch (IndexOutOfBoundsException ex) {
                    throw new ConcurrentModificationException();
                }
            }

            final void checkForComodification() {
                if (expectedModCount != ArrayList.this.modCount)
                    throw new ConcurrentModificationException();
            }
        };
    }

    public List<E> subList(int fromIndex, int toIndex) {
        subListRangeCheck(fromIndex, toIndex, size);
        return new SubList(this, offset, fromIndex, toIndex);
    }

    private void rangeCheck(int index) {
        if (index < 0 || index >= this.size)
            throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
    }

    private void rangeCheckForAdd(int index) {
        if (index < 0 || index > this.size)
            throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
    }

    private String outOfBoundsMsg(int index) {
        return "Index: "+index+", Size: "+this.size;
    }

    /**
     * 实现fail-fast机制 
     * 线程不安全    迭代中不允许修改
    * @author jiaxiaoxian
    * @date 2019年2月12日 
     */
    private void checkForComodification() {
        if (ArrayList.this.modCount != this.modCount)
            throw new ConcurrentModificationException();
    }

    public Spliterator<E> spliterator() {
        checkForComodification();
        return new ArrayListSpliterator<E>(ArrayList.this, offset,
                                           offset + this.size, this.modCount);
    }
}

11.ArrayListSpliterator inner classes - Parallel iteration, based on an index of binary fission, lazy initialization Spliterator

/**
 * @since 1.8
 * 实例化一个ArrayListSpliterator对象,并返回
 */
@Override
public Spliterator<E> spliterator() {
    return new ArrayListSpliterator<>(this, 0, -1, 0);
}

/**
 * Index-based split-by-two, lazily initialized Spliterator
 * 并行迭代
 * 基于索引的二分裂,懒惰初始化的Spliterator
 * */
static final class ArrayListSpliterator<E> implements Spliterator<E> {

    private final ArrayList<E> list;
    private int index; // current index, modified on advance/split
    private int fence; // -1 until used; then one past last index
    private int expectedModCount; // initialized when fence set

    /** Create new spliterator covering the given  range */
    ArrayListSpliterator(ArrayList<E> list, int origin, int fence,
                         int expectedModCount) {
        this.list = list; // OK if null unless traversed
        this.index = origin;
        this.fence = fence;
        this.expectedModCount = expectedModCount;
    }

    private int getFence() { // initialize fence to size on first use
        int hi; // (a specialized variant appears in method forEach)
        ArrayList<E> lst;
        if ((hi = fence) < 0) {
            if ((lst = list) == null)
                hi = fence = 0;
            else {
                expectedModCount = lst.modCount;
                hi = fence = lst.size;
            }
        }
        return hi;
    }

    public ArrayListSpliterator<E> trySplit() {
        int hi = getFence(), lo = index, mid = (lo + hi) >>> 1;
        return (lo >= mid) ? null : // divide range in half unless too small
            new ArrayListSpliterator<E>(list, lo, index = mid,
                                        expectedModCount);
    }

    public boolean tryAdvance(Consumer<? super E> action) {
        if (action == null)
            throw new NullPointerException();
        int hi = getFence(), i = index;
        if (i < hi) {
            index = i + 1;
            @SuppressWarnings("unchecked") E e = (E)list.elementData[i];
            action.accept(e);
            if (list.modCount != expectedModCount)
                throw new ConcurrentModificationException();
            return true;
        }
        return false;
    }

    public void forEachRemaining(Consumer<? super E> action) {
        int i, hi, mc; // hoist accesses and checks from loop
        ArrayList<E> lst; Object[] a;
        if (action == null)
            throw new NullPointerException();
        if ((lst = list) != null && (a = lst.elementData) != null) {
            if ((hi = fence) < 0) {
                mc = lst.modCount;
                hi = lst.size;
            }
            else
                mc = expectedModCount;
            if ((i = index) >= 0 && (index = hi) <= a.length) {
                for (; i < hi; ++i) {
                    @SuppressWarnings("unchecked") E e = (E) a[i];
                    action.accept(e);
                }
                if (lst.modCount == mc)
                    return;
            }
        }
        throw new ConcurrentModificationException();
    }

    public long estimateSize() {
        return (long) (getFence() - index);
    }

    public int characteristics() {
        return Spliterator.ORDERED | Spliterator.SIZED | Spliterator.SUBSIZED;
    }
}

ArrayList summary

1)arrayList可以存放null,本质是Object[]类型的数组。
2)arrayList区别于数组的地方在于能够自动扩展大小,其中关键的方法就是gorw()方法。
3)arrayList由于本质是数组,所以它在数据的查询方面会很快,而在插入删除这些方面,性能下降很多,有移动很多数据才能达到应有的效果,而LinkedList则相反。
4)arrayList实现了RandomAccess,所以在遍历它的时候推荐使用for循环。
5)初始化数组时推荐给初始长度,反复扩容会增加时耗,影响性能效率。

Guess you like

Origin blog.51cto.com/hackerxian/2427207