ArrayList、Vector、LinkedList底层的一些不同

1、关于ArrayList
(1)ArrayList的初始化
public ArrayList() {
    super();
        this.elementData = EMPTY_ELEMENTDATA;
}
会为elementData赋值一个空的Object数组,长度为0
public ArrayList(int initialCapacity) {
        super();
        if (initialCapacity < 0)
            throw new IllegalArgumentException("Illegal Capacity: "+
                                               initialCapacity);
        this.elementData = new Object[initialCapacity];
}
如果传一个参数的时候就是设置初始的容量,不能小于0
(2)添加
添加第一个
public boolean add(E e) {
        ensureCapacityInternal(size + 1);  // Increments modCount!!
        elementData[size++] = e;
        return true;
}
private void ensureCapacityInternal(int minCapacity) {
        if (elementData == EMPTY_ELEMENTDATA) {
            minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
        }

        ensureExplicitCapacity(minCapacity);
}
 private void ensureExplicitCapacity(int minCapacity) {
        modCount++;  //暂且不管是什么意思
    //这个minCapacity是元素下标+1,即当前存在元素的数量
        // overflow-conscious code
        if (minCapacity - elementData.length > 0)
            grow(minCapacity);
}
如果添加元素时,是默认没有初始化容量的ArrayList,就会初始化为容量为10
然后在新添加的元素添加之后,如果超出容量范围的话,就会进行扩容
 private void grow(int minCapacity) {
        // overflow-conscious code
        int oldCapacity = elementData.length;
        int newCapacity = oldCapacity + (oldCapacity >> 1);
        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);
}
这里对数组进行扩容,新的容量是原来容量的1.5倍
这个时候对数组进行扩容,即把原来数组的内容复制到一个新的容量为newCapacity的数组中
(3)删除:remove(Object obj) 和remove(index)
public E remove(int index) {
        rangeCheck(index);//判断下标是否合法

        modCount++;
        E oldValue = elementData(index);//把elementData数组相应下标的值找出来

        int numMoved = size - index - 1;//确定要移动多少个,即被删除掉的元素后的所有元素
        if (numMoved > 0)//其实等于0的时候,相当于删除掉了最后一个的元素
            System.arraycopy(elementData, index+1, elementData, index,
                             numMoved);//对数组本身进行操作,把第index+1之后的值,都移动到index处,即向前移动了一个
        elementData[--size] = null; // clear to let GC do its work 把最后一个值赋值为null

        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;
}
与remove相应坐标的不同是,无非是判断每一个值,看哪一个值一样
但其实只能删除掉第一个相同的值
(4)获取:get(index)
public E get(int index) {
        rangeCheck(index);

        return elementData(index);
}
private void rangeCheck(int index) {
        if (index >= size)
            throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
}

会判断该index是否合法,然后返回数组相应index的位置即可


2、关于Vector
其实经过仔细的观察之后,发现Vector与ArrayList在实际的操作上几乎是一样的
但是我发现Vector的方法都有synchronized修饰的,表示这是线程安全的

其他的区别就是在初始化的时候不一样,请看我的分析
public Vector() {
        this(10);
}
public Vector(int initialCapacity) {
        this(initialCapacity, 0);
}
public Vector(int initialCapacity, int capacityIncrement) {
        super();
        if (initialCapacity < 0)
            throw new IllegalArgumentException("Illegal Capacity: "+
                                               initialCapacity);
        this.elementData = new Object[initialCapacity];
        this.capacityIncrement = capacityIncrement;
}
如果没有初始化时的参数,会默认给一个10,我很惊讶
如果给定了初始化的参数,就按给定的值进行初始化;
还有第二个参数,控制的是每次扩容时候的增加的值;
扩容的方法与ArrayList是相似的,只不过ArrayList是扩容1.5倍,
而Vector是按照指定的扩容值扩容的;如果不设置的话,其实就是增加二倍


3、关于LinkedList
(1)初始化
构造方法里竟然什么都没有,我惊呆了。。。
(2)添加
 public boolean add(E e) {
        linkLast(e);
        return true;
}
void linkLast(E e) {
        final Node<E> l = last; //把last的值赋给l,last初始为null,会根据添加的情况改变
        final Node<E> newNode = new Node<>(l, e, null);//新建一个节点,其实新节点都是最后一个节点,所以next是null
        last = newNode;//这个时候last就是这个新添加的节点了,以供下一个节点添加的使用
        if (l == null)//如果last是null的话,这个节点很明显就是第一个节点
            first = newNode;
        else //如果不是第一个节点的话,那么它的前一个节点的next就是这个节点了
            l.next = newNode;
        size++;//大小++
        modCount++;
}
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;
        }
}
(3)删除
 public E remove(int index) {
        checkElementIndex(index);
        return unlink(node(index));
}
private void checkElementIndex(int index) {
        if (!isElementIndex(index))
            throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
}
E unlink(Node<E> x) {
        // assert x != null;
        final E element = x.item;
        final Node<E> next = x.next;
        final Node<E> prev = x.prev;

        if (prev == null) {
            first = next;
        } else {
            prev.next = next;
            x.prev = null;
        }

        if (next == null) {
            last = prev;
        } else {
            next.prev = prev;
            x.next = null;
        }

        x.item = null;
        size--;
        modCount++;
        return element;
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值