ArrayList

基本属性

默认初始大小为10。

    /**
     *默认初始大小.
     */
    private static final int DEFAULT_CAPACITY = 10;`

这两个数组用来区别用那种构造器初始化list,无参构造器使用DEFAULTCAPACITY_EMPTY_ELEMENTDATA,有参构造器使用EMPTY_ELEMENTDATA


    /**
     * 用于空实例的共享空数组实例。
     */
    private static final Object[] EMPTY_ELEMENTDATA = {};

    /**
     * 用于默认大小的空实例的共享空数组实例。
     */
    private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};


size数组拥有元素的个数,elementData数组。(elementData.length>=size)


    transient Object[] elementData; // non-private to simplify nested class access
    
    /**
     * The size of the ArrayList (the number of elements it contains).
     *
     * @serial
     */
    private int size;

检验在迭代过程中List对象是否被修改了,如果被修改了则抛出java.util.ConcurrentModificationException异常;

protected transient int modCount = 0;

构造器

无参构造器
把DEFAULTCAPACITY_EMPTY_ELEMENTDATA赋值给elementData


    /**
     * 构造一个初始容量为10的空列表。
     * 此时只是给了一个空数组,当第一次使用add时容量扩大到10
     */
    public ArrayList() {
        this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
    }

指定初始大小的构造器:


    /**
     * 构造一个指定大小的列表
     */
    public ArrayList(int initialCapacity) {
    	//判断参数是否大于0,大于零初始化一个参数大小的数组
        if (initialCapacity > 0) {
            this.elementData = new Object[initialCapacity];
        } else if (initialCapacity == 0) {
        	//如果参数等于0,把EMPTY_ELEMENTDATA赋值给elementData
            this.elementData = EMPTY_ELEMENTDATA;
        } else {
            throw new IllegalArgumentException("Illegal Capacity: "+
                                               initialCapacity);
        }
    }

参数为指定集合元素的列表的构造器


    /**
     * Constructs a list containing the elements of the specified
     * collection, in the order they are returned by the collection's
     * iterator.
     *
     * @param c the collection whose elements are to be placed into this list
     * @throws NullPointerException if the specified collection is null
     */
    public ArrayList(Collection<? extends E> c) {
    	//1.把集合转成数组
        Object[] a = c.toArray();
        //2.判断数组长度是否不为0
        if ((size = a.length) != 0) { 
        	//2.1 判断集合类型是否是Arraylist
            if (c.getClass() == ArrayList.class) {
            	//如果集合是ArrayList类型,把集合赋值给elementData
                elementData = a;
            } else {
            	//如果不是ArrayList类型,用Arrays工具类的copyof()方法转换成
                elementData = Arrays.copyOf(a, size, Object[].class);
            }
        } else {
            // 把空数组EMPTY_ELEMENTDATA赋值给elementData
            elementData = EMPTY_ELEMENTDATA;
        }
    }

主要方法

add方法:


    /**
     * 将指定的元素追加到此列表的末尾。
     */
    public boolean add(E e) {
        ensureCapacityInternal(size + 1);  // Increments modCount!!
        elementData[size++] = e;
        return true;
    }

	/**
	* 保证列表大小足够(是否需要扩容)
	*/
    private void ensureCapacityInternal(int minCapacity) {
        ensureExplicitCapacity(calculateCapacity(elementData, minCapacity));
    }

	/**
	* 计算容量大小
	*/
    private static int calculateCapacity(Object[] elementData, int minCapacity) {
   		//如果elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA,取DEFAULT_CAPACITY和minCapacity的最大值。
   		//所以无参构造器构造的列表初始大小为0,第一次add操作时扩大到10
        if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
            return Math.max(DEFAULT_CAPACITY, minCapacity);
        }
        return minCapacity;
    }

    private void ensureExplicitCapacity(int minCapacity) {
    	//AbstracList中的变量,记录列表在结构上被修改的次数
        modCount++;

        // 判断是否需要扩容
        if (minCapacity - elementData.length > 0)
            grow(minCapacity);
    }


    /**
     * Increases the capacity to ensure that it can hold at least the
     * number of elements specified by the minimum capacity argument.
     *
     * @param minCapacity the desired minimum capacity
     */
    private void grow(int minCapacity) {
        // overflow-conscious code
        int oldCapacity = elementData.length;
        // 扩容,位操作,扩容大小为原来的1.5倍
        int newCapacity = oldCapacity + (oldCapacity >> 1);
        // 如果扩容之后仍小于所需大小,就把minCapacity设置为列表的大小
        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);
    }

	// 内存溢出判断
    private static int hugeCapacity(int minCapacity) {
        if (minCapacity < 0) // overflow
            throw new OutOfMemoryError();
        return (minCapacity > MAX_ARRAY_SIZE) ?
            Integer.MAX_VALUE :
            MAX_ARRAY_SIZE;
    }

指定下标添加元素 add:

    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++;
    }

addAll方法

    public boolean addAll(Collection<? extends E> c) {
        Object[] a = c.toArray();
        int numNew = a.length;
        ensureCapacityInternal(size + numNew);  // Increments modCount
        System.arraycopy(a, 0, elementData, size, numNew);
        size += numNew;
        return numNew != 0;
    }

    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;
        if (numMoved > 0)
            System.arraycopy(elementData, index, elementData, index + numNew,
                             numMoved);

        System.arraycopy(a, 0, elementData, index, numNew);
        size += numNew;
        return numNew != 0;
    }

get方法

	//返回此列表中指定位置的元素。
    public E get(int index) {
    	//校验下标是否越界
        rangeCheck(index);

        return elementData(index);
    }

set方法


    /**
     * 将此列表中指定位置的元素替换为指定的元素。并返回被替换元素。
     */
    public E set(int index, E element) {
    	校验下标是否越界
        rangeCheck(index);
		
		//	获取要被替换的元素
        E oldValue = elementData(index);
        // 为该位置元素重新赋值
        elementData[index] = element;
        return oldValue;
    }

clear方法


    /**
     * 删除所有元素
     */
    public void clear() {    	
    	//AbstracList中的变量,记录列表在结构上被修改的次数
        modCount++;

        // 把元素全部指向null,表明可以被GC回收
        for (int i = 0; i < size; i++)
            elementData[i] = null;
		//列表大小设置成0
        size = 0;
    }

contains方法


    /**
     * 如果此列表包含指定的元素,则返回true
     * More formally, returns <tt>true</tt> if and only if this list contains
     * at least one element <tt>e</tt> such that
     * <tt>(o==null&nbsp;?&nbsp;e==null&nbsp;:&nbsp;o.equals(e))</tt>.
     *
     * @param o element whose presence in this list is to be tested
     * @return <tt>true</tt> if this list contains the specified element
     */
    public boolean contains(Object o) {
        return indexOf(o) >= 0;
    }


    /**
     * 返回此列表中指定元素第一次出现的索引,如果此列表不包含该元素,则返回-1。
     */
    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;
    }

remove方法


    /**
     * 删除此列表中指定位置的元素。将任何后续元素向左移动(从其索引中减去一个)。
     */
    public E remove(int index) {
    	//校验索引合法性
        rangeCheck(index);
        
		//AbstracList中的变量,记录列表在结构上被修改的次数
        modCount++;
        //获取要删除的值
        E oldValue = elementData(index);

        int numMoved = size - index - 1;
        //判断是否为末元素,不是就复制一个列表
        if (numMoved > 0)
            System.arraycopy(elementData, index+1, elementData, index,
                             numMoved);
        //如果是末元素,把它置为null即可,不需要复制列表
        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 remove method that skips bounds checking and does not
     * return the value removed.
     */
    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
    }

Iterator和ListIterator的区别

  • Iterator可用来遍历Set和List集合,但是ListIterator只能用来遍历List。

  • Iterator对集合只能是前向遍历,ListIterator既可以前向也可以后向。

  • ListIterator实现了Iterator接口,并包含其他的功能,比如:增加元素,替换元素,获取前一个和后一个元素的索引,等等。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

是饭七分饱

生活在阴沟,也得仰望星空

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值