ArrayList详解

                                       

            1.ArrayList继承AbstractList,该类的父类AbstractCollection实现了Collection接口。

            2.RandomAccess:是一个标识,其内部无任何定义,表名该类支持随机访问。

            3.Cloneable:能被克隆,实现了clone()方法,浅拷贝。

            4.Serializable:支持序列化,能通过序列化去传输。

1.成员变量

//默认初始容量大小
private static final int DEFAULT_CAPACITY = 10;
//共享空数组
private static final Object[] EMPTY_ELEMENTDATA = {};
//有初始容量的共享空数组
private static final Object[] 
DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};
//保存数据的数组
transient Object[] elementData; 
//元素个数
private int size;

2.构造器

//参数为集合的长度
public ArrayList(int initialCapacity) {
        //参数校验
        if (initialCapacity > 0) {
            this.elementData = new Object[initialCapacity];
        } else if (initialCapacity == 0) {
            //长度为0,创建空数组
            this.elementData = EMPTY_ELEMENTDATA;
        } else {
            throw new IllegalArgumentException("Illegal Capacity: "+
                                               initialCapacity);
        }
    }
//无参构造器
public ArrayList() {
        //创建有初始容量的空数组
        this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
}
//参数为Collection或其子类对象
public ArrayList(Collection<? extends E> c) {
        //将集合转为数组
        elementData = c.toArray();
        if ((size = elementData.length) != 0) {
            //判断数组的类型是否为Object
            if (elementData.getClass() != Object[].class)
                //若不是Object将其转为Object类型
                elementData = Arrays.copyOf(elementData, size, Object[].class);
        } else {
        //若集合长度为0,创建空数组
        this.elementData = EMPTY_ELEMENTDATA;
        }
}

3.主要方法

//该方法将数组长度改为集合中存在元素数量
public void trimToSize() {
        modCount++;
        //若当前元素数量小于数组长度:为0则创建空数组,为其他值将数组长度压缩为当前集合中元素的数量。
        if (size < elementData.length) {
            elementData = (size == 0)
              ? EMPTY_ELEMENTDATA
              : Arrays.copyOf(elementData, size);
        }
}

   扩容机制,以添加单个元素为例

public boolean add(E e) {
        modCount++;
        //调用私有方法添加元素
        add(e, elementData, size);
        return true;
}
private void add(E e, Object[] elementData, int s) {
        //若当前元素数量已经与集合长度相同,就进行扩容,调用grow()
        if (s == elementData.length)
            elementData = grow();
        elementData[s] = e;
        size = s + 1;
}
private Object[] grow() {
        return grow(size + 1);
}
private Object[] grow(int minCapacity) {
        int oldCapacity = elementData.length;
        if (oldCapacity > 0 || elementData != DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
            //minCatacity为假若成功添加后元素数量,oldCapacity为当前集合长度,若minCapacity - oldCapacity < oldCapacity >> 1 ,newCapacity = oldCapacity >> 1  + oldCapacity,也就是1.5倍。否则newCapacity = minCapacity + oldCapacity 
            int newCapacity = ArraysSupport.newLength(oldCapacity,
                    minCapacity - oldCapacity, /* minimum growth */
                    oldCapacity >> 1           /* preferred growth */);
            return elementData = Arrays.copyOf(elementData, newCapacity);
        } else {
            //若数组为空,执行下述代码
            return elementData = new Object[Math.max(DEFAULT_CAPACITY, minCapacity)];
        }
}

int size():返回集合中元素的数量

boolean isEmpty():判断集合是否为空

boolean contains(Object o):判断集合是否包含指定元素

int indexOf(Object o):返回集合中首次出现元素o的索引

int lastIndexOf(Object o):返回集合中最后一次出现元素o的索引

Object[] toArray():将结合转为Object类型数组

<T> T[] toArray(T[] a):将集合转为指定类型数组

E get(int index):返回指定索引处元素

E set(int index, E element):用指定元素替换指定索引处的元素

boolean add(E e):在末尾添加元素

void add(int index, E element):在指定位置处添加元素

E remove(int index):移除指定索引处元素并返回该元素

boolean remove(Object o):移除指定元素

void removeRange(int fromIndexint toIndex):移除指定索引范围内元素,左闭右开

void clear():清除集合中的所有元素

boolean addAll(Collection<? extends E> c):将指定集合添加至该集合的尾部

最后:向 ArrayList 添加大量元素之前最好先使用ensureCapacity 方法,以减少增量重新分配的次数。

 

LinkedList:

                                          

              1.AbstractSequentialList:定义了关于链表的一些操作

              2.Deque:双端队列的缩写double ended queue

              所以LinkedList既可作为链表使用,也可作为队列使用。(增删速度快,查询速度慢)

  作为队列:

    入队列:

public boolean add(E e) {
        linkLast(e);
        return true;
}
void linkLast(E e) {
        //l为队列的最后一个节点
        final Node<E> l = last;
        //创建新节点newNode,其前一个节点是l,后一个节点为空
        final Node<E> newNode = new Node<>(l, e, null);
        //更新队列的最后一个节点
        last = newNode;
        //如果l为空,说明此时是一个空队列,更新first节点
        if (l == null)
            first = newNode;
        //LinkedList是双向链表,所以更新l的next的节点使其指向新节点
        else
            l.next = newNode;
        size++;
        modCount++;
}

    出队列

public E poll() {
        final Node<E> f = first;
        //判断队列的首节点是否为空:为空则没有节点可出队列,直接返回空。不为空则删除队列的第一个节点
        return (f == null) ? null : unlinkFirst(f);
}
private E unlinkFirst(Node<E> f) {
        // assert f == first && f != null;
        final E element = f.item;
        //保存首节点的下一节点
        final Node<E> next = f.next;
        f.item = null;
        //让首节点的next域为空
        f.next = null; // help GC
        //更新队列的首节点
        first = next;
        if (next == null)
            last = null;
        else
            next.prev = null;
        size--;
        modCount++;
        return element;
}

  作为栈

    入栈

//始终在头部插入,就能保证第一个节点为刚入栈
public void push(E e) {
        addFirst(e);
}
public void addFirst(E e) {
        linkFirst(e);
}
private void linkFirst(E e) {
        final Node<E> f = first;
        final Node<E> newNode = new Node<>(null, e, f);
        first = newNode;
        if (f == null)
            last = newNode;
        else
            f.prev = newNode;
        size++;
        modCount++;
}

    出栈

//同样的道理:出栈时始终删除第一个元素,可保证先入后出
public E pop() {
        return removeFirst();
}
public E removeFirst() {
        final Node<E> f = first;
        if (f == null)
            throw new NoSuchElementException();
        return unlinkFirst(f);
}
private E unlinkFirst(Node<E> f) {
        // assert f == first && f != null;
        final E element = f.item;
        final Node<E> next = f.next;
        f.item = null;
        f.next = null; // help GC
        first = next;
        if (next == null)
            last = null;
        else
            next.prev = null;
        size--;
        modCount++;
        return element;
}

 

posted @ 2021-02-16 23:11  yr66  阅读(25)  评论(0编辑  收藏  举报