JDK1.8 源码 java.util.ArrayList

前言

本章, 我们来看下集合数据类型java.util.ArrayList.


集合类图解析

在这里插入图片描述
从该类图中可以看到.

  • 集合类基础接口为Collection.
  • 随后衍生出List/Set/Map. 这3类接口.
  • List线
    • Collection <-- AbstractCollection <-- AbstractList/AbstractSet
    • AstractList <-- ArrayList / LinkedList / Vector/ Stack
  • Map线
    • Collection <-- Map <-- AbstractMap
    • AbstractMap <-- HashMap / LinkedHashMap / TreeMap / Hashtable
  • Queue线
    • Collection <-- Queue <-- Dqueue
  • 迭代器接口
    • Collection <-- Iterator <-- ListIterator

本章的ArrayList即属于List的一个具体实现. 继承了AbstractCollection <-- AbstarctList.


正文


总览
  • 主要成员变量
	// 具体存储对象
	transient Object[] elementData; // non-private to simplify nested class access
	// 序列化参数
    private static final long serialVersionUID = 8683452581122892189L;
    // 初始长度 10
    private static final int DEFAULT_CAPACITY = 10;
    // 空集合.
     /**
     * Shared empty array instance used for empty instances.
     */
    private static final Object[] EMPTY_ELEMENTDATA = {};
	 /**
     * Shared empty array instance used for default sized empty instances. We
     * distinguish this from EMPTY_ELEMENTDATA to know how much to inflate when
     * first element is added.
     */
     // 有一段英文注释. 可以看出. 这个是用来进行初始化赋值用的. 我们后面可以看到.
    private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};
    // 数组长度
    private int size;
    // ArrayList 的最大长度
    private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
  • 主要方法
    • public ArrayList()构造函数
    • public ArrayList(int initialCapacity)构造函数
    • public ArrayList(Collection<? extends E> c) 构造函数
    • public boolean add(E e) 增加节点
    • public boolean addAll(Collection<? extends E> c) 批量增加
    • public E remove(int index) 删除节点
    • public boolean removeAll(Collection<?> c) 批量删除
    • public E get(int index) 查询
    • public E set(int index, E element)
  • 其余内部方法
    • public void ensureCapacity(int minCapacity)
    • private void ensureCapacityInternal(int minCapacity)
    • private void ensureExplicitCapacity(int minCapacity)
    • private void grow(int minCapacity) 扩容
    • private void writeObject(java.io.ObjectOutputStream s) 序列化
    • private void readObject(java.io.ObjectInputStream s) 反序列化
    • public Iterator<E> iterator() 迭代器

声明
public class ArrayList<E> extends AbstractList<E>
        implements List<E>, RandomAccess, Cloneable, java.io.Serializable
  • AbstractList
public abstract class AbstractList<E> extends AbstractCollection<E> implements List<E> {
	// 主要维护了2个Iterator
    private class Itr implements Iterator<E> {
    private class ListItr extends Itr implements ListIterator<E> {

  • AbstractCollection<E>
public abstract class AbstractCollection<E> implements Collection<E> {
  • Collection<E>
public interface Collection<E> extends Iterable<E> {
  • Iterable<E>
public interface Iterable<T> {
	Iterator<T> iterator();
    default void forEach(Consumer<? super T> action) {
        Objects.requireNonNull(action);
        for (T t : this) {
            action.accept(t);
        }
    }
   default Spliterator<T> spliterator() {
        return Spliterators.spliteratorUnknownSize(iterator(), 0);
    }
}
  • List<E>
public interface List<E> extends Collection<E> {
    int size();
    boolean isEmpty();
    boolean contains(Object o);
    Iterator<E> iterator();
    Object[] toArray();
    <T> T[] toArray(T[] a);
    boolean add(E e);
    boolean remove(Object o);
    boolean containsAll(Collection<?> c);
    boolean addAll(Collection<? extends E> c);
    boolean addAll(int index, Collection<? extends E> c);
    boolean removeAll(Collection<?> c);
    boolean retainAll(Collection<?> c);
    default void replaceAll(UnaryOperator<E> operator) {
        Objects.requireNonNull(operator);
        final ListIterator<E> li = this.listIterator();
        while (li.hasNext()) {
            li.set(operator.apply(li.next()));
        }
    }
    default void sort(Comparator<? super E> c) {
        Object[] a = this.toArray();
        Arrays.sort(a, (Comparator) c);
        ListIterator<E> i = this.listIterator();
        for (Object e : a) {
            i.next();
            i.set((E) e);
        }
    }
    void clear();
    boolean equals(Object o);
    int hashCode();
    E get(int index);
    E set(int index, E element);
    void add(int index, E element);
    E remove(int index);
    int indexOf(Object o);
    int lastIndexOf(Object o);
    ListIterator<E> listIterator();
    ListIterator<E> listIterator(int index);
    List<E> subList(int fromIndex, int toIndex);
    default Spliterator<E> spliterator() {
        return Spliterators.spliterator(this, Spliterator.ORDERED);
    }        
  • RandomAccess
public interface RandomAccess {
}
  • Cloneable
public interface Cloneable {
}
  • Serializable
public interface Serializable {
}

构造方法
  • 无参构造方法ArrayList()
    public ArrayList() {
        this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
    }
  • ArrayList(int initialCapacity)
    public ArrayList(int initialCapacity) {
        if (initialCapacity > 0) {
        	// 长度>0 声明数组
            this.elementData = new Object[initialCapacity];
        } else if (initialCapacity == 0) {
        	// 长度==0 空
            this.elementData = EMPTY_ELEMENTDATA;
        } else {
            throw new IllegalArgumentException("Illegal Capacity: "+
                                               initialCapacity);
        }
    }
  • ArrayList(Collection<? extends E> c)
    public ArrayList(Collection<? extends E> c) {
        elementData = c.toArray();
        if ((size = elementData.length) != 0) {
            // c.toArray might (incorrectly) not return Object[] (see 6260652)
            if (elementData.getClass() != Object[].class)
                elementData = Arrays.copyOf(elementData, size, Object[].class);
        } else {
            // replace with empty array.
            this.elementData = EMPTY_ELEMENTDATA;
        }
    }

使用Arrays.copyOf()方法


    public boolean add(E e) {
        ensureCapacityInternal(size + 1);  // Increments modCount!!
        elementData[size++] = e;
        return true;
    }
    public void add(int index, E element) {
        rangeCheckForAdd(index);
        ensureCapacityInternal(size + 1);  // Increments modCount!!
        System.arraycopy(elementData, index, elementData, index + 1,
                         size - index);
        elementData[index] = element;
        size++;
    }    

其中有2个方法ensureCapacityInternalrangeCheckForAdd 这是分别用来检测数组边界的.

   private void rangeCheckForAdd(int index) {
        if (index > size || index < 0)
            throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
    }
    private void ensureCapacityInternal(int minCapacity) {
        if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
        	// 设置成默认长度10
            minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
        }
        ensureExplicitCapacity(minCapacity);
    }
    
    private void ensureExplicitCapacity(int minCapacity) {
        modCount++;
        // 数组越界了
        if (minCapacity - elementData.length > 0)
        	// 扩充数组
            grow(minCapacity);
    }
    private void grow(int minCapacity) {
        // overflow-conscious code
        int oldCapacity = elementData.length;
        // 扩充成原来的1.5倍
        int newCapacity = oldCapacity + (oldCapacity >> 1);
        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);
    }    

从增加我们可以看出主要🈶️2个增加元素的方法:

  • 末尾增加元素 add(E e)
  • 在指定位置增加元素add(int index, E element). 注意, 使用此方法需要将数组index之后的每一位都进行移位操作. 效率不高.

   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);
        elementData[--size] = null; // clear to let GC do its work

        return 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;
    }
    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; // clear to let GC do its work
    }

删除操作也同样有2种方法:

  • 删除指定index位置数据.
  • 删除第一个等于Object的对象.

  • get
  public E get(int index) {
        rangeCheck(index);

        return elementData(index);
    }
 E elementData(int index) {
        return (E) elementData[index];
    }

  • indexOf()
    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;
    }
  • lastIndexOf()
    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;
    }

  • set(int index, E element)
   public E set(int index, E element) {
        rangeCheck(index);

        E oldValue = elementData(index);
        elementData[index] = element;
        return oldValue;
    }

equals & hashCode & toString

这3个方法是在AbstractList<E>内进行实现的.

  • equals
    public boolean equals(Object o) {
        if (o == this)
            return true;
        if (!(o instanceof List))
            return false;

        ListIterator<E> e1 = listIterator();
        ListIterator<?> e2 = ((List<?>) o).listIterator();
        while (e1.hasNext() && e2.hasNext()) {
            E o1 = e1.next();
            Object o2 = e2.next();
            if (!(o1==null ? o2==null : o1.equals(o2)))
                return false;
        }
        return !(e1.hasNext() || e2.hasNext());
    }

依次比较两个集合的所有元素. 全部相等才算相等.

  • hashCode
    public int hashCode() {
        int hashCode = 1;
        for (E e : this)
            hashCode = 31*hashCode + (e==null ? 0 : e.hashCode());
        return hashCode;
    }

算法为31*每个元素hashCode

  • toString()
  public String toString() {
        Iterator<E> it = iterator();
        if (! it.hasNext())
            return "[]";

        StringBuilder sb = new StringBuilder();
        sb.append('[');
        for (;;) {
            E e = it.next();
            sb.append(e == this ? "(this Collection)" : e);
            if (! it.hasNext())
                return sb.append(']').toString();
            sb.append(',').append(' ');
        }
    }

toString方法是在AbstractCollection<E>方法内进行实现的. 输出为[], 中间分别填写各个子类的toString()方法.


Others
  • size
  public int size() {
        return size;
    }
  • isEmpty
    public boolean isEmpty() {
        return size == 0;
    }
  • contains
    public boolean contains(Object o) {
        return indexOf(o) >= 0;
    }
  • toArray
    public Object[] toArray() {
        return Arrays.copyOf(elementData, size);
    }
    public <T> T[] toArray(T[] a) {
        if (a.length < size)
            // Make a new array of a's runtime type, but my contents:
            return (T[]) Arrays.copyOf(elementData, size, a.getClass());
        System.arraycopy(elementData, 0, a, 0, size);
        if (a.length > size)
            a[size] = null;
        return a;
    }
  • clear
    public void clear() {
        modCount++;

        // clear to let GC do its work
        for (int i = 0; i < size; i++)
            elementData[i] = null;

        size = 0;
    }
  • subList
  public List<E> subList(int fromIndex, int toIndex) {
        subListRangeCheck(fromIndex, toIndex, size);
        return new SubList(this, 0, fromIndex, toIndex);
    }
  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;
        }
    }
  • sort
    public void sort(Comparator<? super E> c) {
        final int expectedModCount = modCount;
        Arrays.sort((E[]) elementData, 0, size, c);
        if (modCount != expectedModCount) {
            throw new ConcurrentModificationException();
        }
        modCount++;
    }

排序使用的是Arrays.sort()方法进行排序.

  • writeObject
  private void writeObject(java.io.ObjectOutputStream s)
        throws java.io.IOException{
        // Write out element count, and any hidden stuff
        int expectedModCount = modCount;
        s.defaultWriteObject();

        // Write out size as capacity for behavioural compatibility with clone()
        s.writeInt(size);

        // 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();
        }
    }
  • readObject
    private void readObject(java.io.ObjectInputStream s)
        throws java.io.IOException, ClassNotFoundException {
        elementData = EMPTY_ELEMENTDATA;

        // Read in size, and any hidden stuff
        s.defaultReadObject();

        // Read in capacity
        s.readInt(); // ignored

        if (size > 0) {
            // be like clone(), allocate array based upon size not capacity
            ensureCapacityInternal(size);

            Object[] a = elementData;
            // Read in all elements in the proper order.
            for (int i=0; i<size; i++) {
                a[i] = s.readObject();
            }
        }
    }

Reference

[1]. JDK1.8源码(五)——java.util.ArrayList 类

©️2020 CSDN 皮肤主题: Age of Ai 设计师:meimeiellie 返回首页