• ArrayList源码分析


    property:
    
    1、private transient Object[] elementData;
    
    ArrayList底层维护的是一个Object[]数组
    
    2、private int size;
    
    维护arrayList的长度
    
    3、modCount
    
    记录数组结构改变的次数(数组容量改变的次数)
    
    方法:
    
    1、public ArrayList(int initialCapacity) {
        super();
            if (initialCapacity < 0)
                throw new IllegalArgumentException("Illegal Capacity: "+
                                                   initialCapacity);
        this.elementData = new Object[initialCapacity];
        }
    
    提供自定义底层数组长度的构造方法
    
    2、 public ArrayList() {
        this(10);
        }
    
    如果不使用自定义底层数组长度的构造方法,那么将底层数组的长度默认设置为10
    
    3public void trimToSize() {
    modCount++;
    int oldCapacity = elementData.length;
    if (size < oldCapacity) {
    elementData = Arrays.copyOf(elementData, size);
    }
    
    这个方法可以将动态扩容后多余的部分减掉
    
    4public void ensureCapacity(int minCapacity) {
    modCount++;
    int oldCapacity = elementData.length;
    if (minCapacity > oldCapacity) {
    Object oldData[] = elementData;
    int newCapacity = (oldCapacity * 3)/2 + 1;//新容量=(旧容量*3)/2+1
    if (newCapacity < minCapacity) //?????????
    newCapacity = minCapacity;
    // minCapacity is usually close to size, so this is a win:
    elementData = Arrays.copyOf(elementData, newCapacity);
    }
    }
    
    保证数组的容量充足(动态扩容的实现)
    
    5public 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;
    }
    
    主要有以下几点:
    
    <1、如果传入的参数为null,那么将返回数组中第一个为null的索引
    
    <2、该方法中使用equals()方法判断是否相等
    
    <3、如果没有则返回-1
    
    6public 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;
    }
    
    与indexOf道理相同
    
    7public Object[] toArray() {
    return Arrays.copyOf(elementData, size);
    }
    
    转化为数组
    
    8private void RangeCheck(int index) {
    if (index >= size)
    throw new IndexOutOfBoundsException(
    "Index: "+index+", Size: "+size);
    }
    
    检查数组下标是否越界
    
    9public E get(int index) {
    RangeCheck(index);
    
    return (E) elementData[index];
    }
    
    获取某个索引下的对象
    
    10public E set(int index, E element) {
    RangeCheck(index);
    
    E oldValue = (E) elementData[index];
    elementData[index] = element;
    return oldValue;
    }
    
    设置对象、并返回原来的对象
    
    11
    
    public boolean add(E e) {
    ensureCapacity(size + 1); // Increments modCount!!
    elementData[size++] = e;
    return true;
    }
    
    加一个对象,并ensureCapacity(size + 1)
    
    12public 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); //使用System.arraycopy将elementData index之后的元素后移,将index索引的位置空出来
    elementData[index] = element;
    size++;
    }
    
    在索引上add
    
    13public 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[--size] = null; // Let gc do its work  gc清理堆内存
    
    return oldValue;
    }
    
    14public 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;
    }
    
    15public 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;
    }
    
    16private void fastRemove(int index) {
    modCount++;
    int numMoved = size - index - 1;
    if (numMoved > 0)
    System.arraycopy(elementData, index+1, elementData, index,
    numMoved);//index后的元素前移
    elementData[--size] = null; // Let gc do its work
    }
    
    17public void clear() {
    modCount++;
    
    // Let gc do its work
    for (int i = 0; i < size; i++)
    elementData[i] = null;
    
    size = 0;
    }
    
    清空list
    
    18public boolean addAll(Collection<? extends E> c) {
    Object[] a = c.toArray();
    int numNew = a.length;
    ensureCapacity(size + numNew); // Increments modCount
    System.arraycopy(a, 0, elementData, size, numNew);
    size += numNew;
    return numNew != 0;
    }
    
    19、序列化
    
    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 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();
    }
    
    }
    
    20、反序列化
    
    private void readObject(java.io.ObjectInputStream s)
    throws java.io.IOException, ClassNotFoundException {
    // Read in size, and any hidden stuff
    s.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();
    }
  • 相关阅读:
    Android Studio学习笔记(1)
    2019全国大学生电子设计大赛总结
    包与常用模块
    模块
    迭代器、生成器与递归调用
    叠加多个装饰器与有参数的装饰器。
    装饰器
    控制指针的移动、函数
    字符编码
    python 数据类型之列表、元组、字典、集合
  • 原文地址:https://www.cnblogs.com/lige-H/p/7351108.html
Copyright © 2020-2023  润新知