ArrayList的深入理解(学习)

首先申明一下,此篇文章仅仅是我个人学习ArrayList源码后的学习总结,如果有错误,可以提出来探讨。

1.1    原理



public class ArrayList<E> extends AbstractList<E>
        implements List<E>, RandomAccess, Cloneable, java.io.Serializable
{
    private static final long serialVersionUID = 8683452581122892189L;


    /**
     * The array buffer into which the elements of the ArrayList are stored.
     * The capacity of the ArrayList is the length of this array buffer.
     */
    private transient Object[] elementData;//数组


    public ArrayList(int initialCapacity) {//初始化容器的大小
super();
        if (initialCapacity < 0)
            throw new IllegalArgumentException("Illegal Capacity: "+
                                               initialCapacity);
         this.elementData = new Object[initialCapacity];
    }


    /**
     * Constructs an empty list with an initial capacity of ten.
     */
    public ArrayList() {
this(10);//默认是10
    }

底层是使用数组和自动扩容来实现的。默认容量10,当然也可以自定义初始容量

1.2    结构


public class ArrayList<E> extends AbstractList<E>
        implements List<E>, RandomAccess, Cloneable, java.io.Serializable

public abstract class AbstractList<E> extends AbstractCollection<E> implements List<E> 

public abstract class AbstractCollection<E> implements Collection<E> 

public interface Collection<E> extends Iterable<E> 

AbstractCollection是一个抽象类,它实现Collection接口。主要是对(add,remove)等操作做简单的实现。Collection接口继承Iterable接口, Collection接口主要是对(add,remove)等操作定义抽象方法。Iterable接口,只有一个iterator抽象方法,用来获得对应的迭代器。

(所以ArryList并不直接实现iterator接口,而是实现创建iterator的Iterable接口)。

AbstractList抽象类继承AbstractCollection抽象类,主要是在内部实现迭代器(Itr,ListItr),ArrayList类继承AbstractList抽象类,主要是对(add,remove)等操作的具体实现。

 

1.3    不常用方法:

1.3.1  retainAll(Collection<?>c)

如果list中的值在集合c中不存在,就删除。

1.3.2  trimToSize()

自动扩容会使数组的长度,比实际的数据的长度要大一些,

这时,可以采用此方法使数组的长度和数据的长度一致,减少空间。

1.4    List迭代器

Arrylist并不直接实现迭代器的接口(iterator),它实现了创建迭代器工厂的接口(iterable)。它通过内部类来实现迭代器的接口(iterator);支持对集合(容器)进行多种迭代器(Itr,ListItr),支持同时对容器进行多次遍历(每次遍历都会产生一个新迭代器)。

1.4.1  Itr

这是通用的迭代器。可以通过iterator()获得;主要提供3个方法:hasNext()、netx()、remove();

 

 

源码:

简单的说,在Irt中维护了一个当前指针cursor,通过cursor来遍历数组的。

private class Itrimplements Iterator<E> {

    /**

     * Index of element to bereturned by subsequent call to next.

     */

    int cursor = 0;//遍历数组的指针,

 

    /**

     * Index of elementreturned by most recent call to next or

     * previous.  Reset to -1 if this element is deleted by a call

     * to remove.

     */

    int lastRet = -1;//调用next返回的元素的下标。(正常情况:cursor=lastRet+1);

 

    /**

     * The modCount value thatthe iterator believes that the backing

     * List should have.  If this expectation is violated, the iterator

     * has detected concurrentmodification.

     */

    int expectedModCount = modCount;//线程一致性(如果你在遍历数组时,数组被外部改变了,就会报异常

 

    public boolean hasNext() {

            returncursor != size();

    }

 

    public E next() {

            checkForComodification();//检查数组有没有被外部修改

        try {

       E next = get(cursor);

       lastRet = cursor++;

       return next;

        } catch(IndexOutOfBoundsException e) {

       checkForComodification();

       throw new NoSuchElementException();

        }

    }

 

    public void remove() {

        if (lastRet == -1)

       throw new IllegalStateException();

            checkForComodification();

 

        try {

       AbstractList.this.remove(lastRet);

       if (lastRet <cursor)

           cursor--;

       lastRet = -1;

       expectedModCount = modCount;

        } catch(IndexOutOfBoundsException e) {

       throw new ConcurrentModificationException();

        }

    }

 

    final void checkForComodification() {

        if (modCount !=expectedModCount)

       throw new ConcurrentModificationException();

    }

    }

1.1.1  ListItr

此迭代器是ArrayList扩展的。可以通过listIterator()获得,它除了从前往后遍历外,还能从后往前遍历。

源码:

private class ListItr extends Itrimplements ListIterator<E> {

    ListItr(int index) {//对cursor重新赋值

        cursor = index;

    }

 

    public boolean hasPrevious() {

        returncursor != 0;

    }

 

        public E previous() {//获取前一个值

            checkForComodification();

            try {

                int i =cursor - 1;

                E previous = get(i);

                lastRet = cursor = i;

                return previous;

            } catch (IndexOutOfBoundsException e) {

                checkForComodification();

                throw new NoSuchElementException();

            }

        }

 

    public int nextIndex() {

        returncursor;

    }

 

    public int previousIndex() {

        returncursor-1;

    }

 

    public void set(E e) {

        if (lastRet == -1)

       throw new IllegalStateException();

            checkForComodification();

 

        try {

       AbstractList.this.set(lastRet, e);

       expectedModCount = modCount;

        } catch(IndexOutOfBoundsException ex) {

       throw new ConcurrentModificationException();

        }

    }

 

    public void add(E e) {

            checkForComodification();

 

        try {

       AbstractList.this.add(cursor++, e);

       lastRet = -1;

       expectedModCount = modCount;

        } catch(IndexOutOfBoundsException ex) {

       throw new ConcurrentModificationException();

        }

    }

}

 

从代码上看ListItr是继承Itr,它可以使用Itr所有的方法,同时又加了扩展,

其实也就是让cursor可以重新赋值了。相当于你遍历的初始位置可以自定义(开头,最后,中间的任意位置),同时又提供向前遍历的方法(previous()),比起Itr还多了一些add,set方法。

 


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值