ArrayList部分源码学习笔记

来源:互联网 发布:安卓防沉迷软件 编辑:程序博客网 时间:2024/06/07 21:56
一、线性表分为顺序表和链表两大类
二、顺序表
1、特点:(1)元素所占的存储空间是连续的 (2)元素在存储空间按逻辑顺序存放。
  (3)查询快,增删慢

2、例如 ArrayList: 基于数组实现,类似于一个动态数组,容量可自增的,所以可通过角标获取指定位置的元素
增加元素: 是创建大容量数组,复制原数组,再进行赋值元素的操作。
删除元素: 复制数组,将已删除位置的元素置null。
数组复制的主要方法:
 @param src
 *            the source array to copy the content. 原数组
 * @param srcPos
 *            the starting index of the content in {@code src}. 原数组要复制的开始位置
 * @param dat
 *            the destination array to copy the data into. 目标数组
 * @param dstPos
 *            the starting index for the copied content in {@code dst}.  目标数组的开始位置
 * @param length
 *            the number of elements to be copied.   要复制的长度
 *  /

public static native void arraycopy(Object src, int srcPos,
    Object dst, int dstPos, int length);



(1)构造:
public class ArrayList<Eextends AbstractList<Eimplements CloneableSerializableRandomAccess {
    /**
     * 最小容量值,Java中为10,android中为12
     */

    private static final int MIN_CAPACITY_INCREMENT = 12;

    /**
     * 数组元素的长度
     */

    int size;

    /**
     * ArrayList是基于数组的方式实现的
     */

    transient Object[] array;

    /**
     * 创建一个指定带容量大小的ArrayList
     */

    public ArrayList(int capacity) {
        if (capacity < 0) {
            throw new IllegalArgumentException("capacity < 0: " + capacity);
        }
        array = (capacity == 0 ? EmptyArray.OBJECT : new Object[capacity]);
    }

    /**
     * 创建一个无参构造的ArrayList
     */

    public ArrayList() {
        array = EmptyArray.OBJECT;
    }

    /**
     * 创建一个包含collection的ArrayList
     */

    public ArrayList(Collection<? extends E> collection) {// java的多态性
        if (collection == null) {
            throw new NullPointerException("collection == null");
        }

        Object[] a = collection.toArray();
        if (a.getClass() != Object[].class) {
            Object[] newArray = new Object[a.length];
            System.arraycopy(a, 0, newArray, 0, a.length);
            a = newArray;
        }
        array = a;
        size = a.length;
    }

(2)添加:
   /**
     * 添加方法,添加到列表的尾部
     * (1、声明一个空间大点的新数组 2、将老数组复制进去 3、将object赋值进去)
     */
   @Override
    public boolean add(E object) {
        Object[] a = array;// 将array赋值给一个局部数组
        int s = size;// 用局部的s获取长度
        if (s == a.length) {// 如果现在的长度等于数组array的长度,那么空间满了,需要声明一个新数组
            Object[] newArray = new Object[s +
                    (s < (MIN_CAPACITY_INCREMENT / 2) ?
                     MIN_CAPACITY_INCREMENT : s >> 1)];// s<6?12:6
            System.arraycopy(a, 0, newArray, 0, s);// 把原来的数组拷贝到新的数组中来
            array = a = newArray;
        }
        a[s] = object;// 把元素添加进来
        size = s + 1;// 长度+1
        modCount++;// 计量器,只要数组中元素动一下,它就+1
        return true;
    }

    /**
     * 添加方法,添加到指定位置
     * (1、声明一个空间大点的新数组 2、将老数组复制进去, 移动位置将index空出来 3、将object赋值进index的位置)
     */
   @Override
    public void add(int index, E object) {
        Object[] a = array;
        int s = size;
        if (index > s || index < 0) {
            throwIndexOutOfBoundsException(index, s);
        }
        // 当数组长度容量足够时,执行System.arraycopy方法实现数组的复制
        if (s < a.length) {
            System.arraycopy(a, index, a, index + 1, s - index);
        } else {// 当数组容量不足时,进行扩容
            // assert s == a.length;
            // 创建新数组
            Object[] newArray = new Object[newCapacity(s)];
            // 将数据拷贝到新数组中,并移动位置
            System.arraycopy(a, 0, newArray, 0, index);
            System.arraycopy(a, index, newArray, index + 1, s - index);
            array = a = newArray;
        }
        a[index] = object;
        size = s + 1;
        modCount++;
    }
    /**
     * 添加方法,将容器中所有元素添加到此列表的尾部
     *(1、声明一个空间大点的新数组 2、将要新增的集合转成数组  3、将两个数组复制到新数组中)
     */
    @Override public boolean addAll(Collection<? extends E> collection) {
        Object[] newPart = collection.toArray();
        int newPartSize = newPart.length;
        if (newPartSize == 0) {
            return false;
        }
        Object[] a = array;
        int s = size;
        int newSize = s + newPartSize; // If add overflows, arraycopy will fail
        if (newSize > a.length) {
            int newCapacity = newCapacity(newSize - 1); // ~33% growth room
            Object[] newArray = new Object[newCapacity];
            System.arraycopy(a, 0, newArray, 0, s);
            array = a = newArray;
        }
        System.arraycopy(newPart, 0, a, s, newPartSize);
        size = newSize;
        modCount++;
        return true;
    }

(3)删除
   /**
     * 删除列表中指定位置上的元素
     * @param index the index of the object to remove.
     * @return the removed object.
     * @throws IndexOutOfBoundsException
     *             when {@code location < 0 || location >= size()}
     */

    @Override public E remove(int index) {
        Object[] a = array;
        int s = size;
        if (index >= s) {
            throwIndexOutOfBoundsException(index, s);
        }
        @SuppressWarnings("unchecked") E result = (E) a[index];
        // 将删除位置之后的元素向前挪动一个位置
        System.arraycopy(a, index + 1, a, index, --s - index);
        // 将数组末尾置空
        a[s] = null
        size = s;
        modCount++;
        return result;
    }
    // 删除列表中首次出现的指定元素(如果存在)
    @Override public boolean remove(Object object) {
        Object[] a = array;
        int s = size;
        if (object != null) {
            for (int i = 0; i < s; i++) {
                if (object.equals(a[i])) {
                    System.arraycopy(a, i + 1, a, i, --s - i);
                    a[s] = null// Prevent memory leak
                    size = s;
                    modCount++;
                    return true;
                }
            }
        } else {
            for (int i = 0; i < s; i++) {
                if (a[i] == null) {
                    System.arraycopy(a, i + 1, a, i, --s - i);
                    a[s] = null// Prevent memory leak
                    size = s;
                    modCount++;
                    return true;
                }
            }
        }
        return false;
    }
(4)查询
     /**
     * 查找是否包含某个元素
     */
    @Override public boolean contains(Object object) {
        Object[] a = array;// 声明一个Object数组
        int s = size;
        if (object != null) {
            for (int i = 0; i < s; i++) {// 全部遍历一遍,找到元素返回true
                if (object.equals(a[i])) {
                    return true;
                }
            }
        } else {// 没找到返回false
            for (int i = 0; i < s; i++) {
                if (a[i] == null) {
                    return true;
                }
            }
        }
        return false;
    }

转自:http://blog.csdn.net/mynameishuangshuai/article/details/52680401

0 0
原创粉丝点击