您的位置:首页 > 其它

ArrayList部分源码学习笔记

2016-10-13 20:28 309 查看
一、线性表分为顺序表和链表两大类
二、顺序表
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<E> extends AbstractList<E> implements Cloneable, Serializable, RandomAccess {

    /**

     * 最小容量值,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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: