List接口的三个实现类的源码分析

Array List
private static final int DEFAULT_CAPACITY = 10;//默认大小为10  
protected transient int modCount = 0;//记录修改的次数的变量
//使用数组来存储数据
 public ArrayList(Collection<? extends E> c) {//传入集合类型
        Object[] a = c.toArray();//先转换为数组
        if ((size = a.length) != 0) {//判断传入的集合长度
            if (c.getClass() == ArrayList.class) {//类型相同,直接传
                elementData = a;
            } else {//复制
                elementData = Arrays.copyOf(a, size, Object[].class);
            }
        } else {//返回一个空的
            elementData = EMPTY_ELEMENTDATA;
        }
    }
//生长函数
  private void grow(int minCapacity) {
        int oldCapacity = elementData.length;//获取原来的数据长度
        int newCapacity = oldCapacity + (oldCapacity >> 1);//将长度扩增到原来的1.5倍
        if (newCapacity - minCapacity < 0)//扩增后的长度仍然不够用,就将使用传入长度扩增
            newCapacity = minCapacity;
        if (newCapacity - MAX_ARRAY_SIZE > 0)//判断是否超过了最大的限制
            newCapacity = hugeCapacity(minCapacity);
        elementData = Arrays.copyOf(elementData, newCapacity);
    }

Link List
//使用链表进行数据的存储
transient int size = 0; //初始长度
transient Node<E> first;//首节点
transient Node<E> last;//尾节点
    private static class Node<E> {//使用双向链表
        E item;//存的数据
        Node<E> next;//后一个
        Node<E> prev;//前一个
	   //一个完整的节点
        Node(Node<E> prev, E element, Node<E> next) {
            this.item = element;
            this.next = next;
            this.prev = prev;
        }
    }
//后插法的增加元素
 void linkLast(E e) {
     //先获取最后的指针last,然后让其指向给新节点指向前节点
     //让本节点给last让其指向
        final Node<E> l = last;
        final Node<E> newNode = new Node<>(l, e, null);
        last = newNode;
        if (l == null)//如果last为null,说明里面原本没有元素
            first = newNode;//唯一的元素,frist也指向
        else
            l.next = newNode;//将前一个的节点的next指向新节点
        size++;
        modCount++;
    }
//删除元素--让其无前后指针指向,被内存回收
private E unlinkFirst(Node<E> f) {
        final E element = f.item;//先保存数据
        final Node<E> next = f.next;//获取节点的next
        f.item = null;
        f.next = null; // help GC  将节点的数据和next置为null让GC回收
        first = next;//将frist指向下一个节点
        if (next == null)//判断是否是最后一个元素
            last = null;
        else
            next.prev = null;
        size--;//总数量减少
        modCount++;//修改量+1
        return element;//返回删除的数据
    }
//可以实现栈的结构
//源码中使用前插法
public void push(E e) {
        addFirst(e);
    }
 public E poll() {
        final Node<E> f = first;
        return (f == null) ? null : unlinkFirst(f);
    }
//我认为这里的设计很巧妙,声明私有变量存储size,避免了每次查询链表的长度的时候都要遍历
 public int size() {
        return size;
    }
//删除的时候先判断是否为空,然后通过遍历找到元素
 public boolean remove(Object o) {
        if (o == null) {
            for (Node<E> x = first; x != null; x = x.next) {//链表的遍历
                if (x.item == null) {
                    unlink(x);
                    return true;
                }
            }
        } else {
            for (Node<E> x = first; x != null; x = x.next) {
                if (o.equals(x.item)) {
                    unlink(x);
                    return true;
                }
            }
        }
        return false;
    }
Vector
synchronized //关键字贯穿了这个类,这个类型是线程安全的
protected Object[] elementData;//使用的是数组存储数据
  public Vector() {//默认的长度为10
        this(10);
    }
//可以指定初始的长度和我们的增长系数
 public Vector(int initialCapacity, int capacityIncrement) {
        super();
        if (initialCapacity < 0)
            throw new IllegalArgumentException("Illegal Capacity: "+
                                               initialCapacity);
        this.elementData = new Object[initialCapacity];
        this.capacityIncrement = capacityIncrement;
    }
//增长函数
 private void grow(int minCapacity) {
        // overflow-conscious code
        int oldCapacity = elementData.length;//获取原本的长度
        int newCapacity = oldCapacity + ((capacityIncrement > 0) ?
                                         capacityIncrement : oldCapacity);
     	//如果初始化给定了增长长度,使用初始化长度增加,否则二倍增加
        if (newCapacity - minCapacity < 0)//这里的判断和Arraylist相似
            newCapacity = minCapacity;
        if (newCapacity - MAX_ARRAY_SIZE > 0)
            newCapacity = hugeCapacity(minCapacity);
        elementData = Arrays.copyOf(elementData, newCapacity);
    }

总结

ArrayList默认大小为10,增长倍数为1.5倍,使用数组来存储数据

LinkList初始长度为0,使用双向链表进行存储数据,能够作为栈来使用,使用前插法实现

Vector初始长度为10,可以设置增长长度,默认的增长长度为2倍,使用数组来存储,线程安全

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值