LinkedList,ArrayList,Vector的存储性能和特性

  1. 首先 LinkedList 继承了 AbstractSequentialList,ArrayList 和Vector 都继承了AbstractList

    public class LinkedList<E> extends AbstractSequentialList<E> implements List<E>, Deque<E>
    

    因为所以说LinkedList 具有链表和双向队列的特性。但是他没有实现 RandomAccess, 而ArrayList, Vector 都实现了RandomAcess

    public class ArrayList<E> extends AbstractList<E>
            implements List<E>, RandomAccess
    
    public class Vector<E>
        extends AbstractList<E>
        implements List<E>, RandomAccess
    

    所以ArrayList 和Vector 支持快速随机访问。但是因为内部存储使用的是

    Vector:

    protected Object[] elementData;
    

    ArrayList:

    transient Object[] elementData;
    

    那么为什么Vector 和ArrayList 都 implement java.io.Serializable, 但是Vector 就序列化了数组元素,但是ArrayList 并没有,原因在于elementData是一个缓存数组,他会多余出一些没用的容量,等容量不够时再进行扩充容量,那么这些多余的容量,序列化时,就会产生浪费。ArrayList通过writeObject 和readObject 方法将缓存数组中的元素转换成流来解决这个问题。

  2. 然后我们再看一看他们都有什么方法。

    增加:

    Vector: 利用的数组的那一套,比如插入指定的下标

     public synchronized void insertElementAt(E obj, int index) {
            modCount++;
            if (index > elementCount) {
                throw new ArrayIndexOutOfBoundsException(index
                                                         + " > " + elementCount);
            }
            ensureCapacityHelper(elementCount + 1);
            System.arraycopy(elementData, index, elementData, index + 1, elementCount - index);
            //把对象添加元素下标
            elementData[index] = obj;
            elementCount++;
        }
    

    但是直接如果直接加载后面的话还是挺快捷的

        public synchronized void addElement(E obj) {
            modCount++;
            ensureCapacityHelper(elementCount + 1);
            elementData[elementCount++] = obj;
        }
    

    ArrayList: 直接添加指定下标,跟Vector 一样换汤不换药。

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

    直接在后面添加:

     public boolean add(E e) {
            ensureCapacityInternal(size + 1);  // Increments modCount!!
            elementData[size++] = e;
            return true;
    

    唯一不同的是,他的直接添加的方法有返回值,返回成功失败的结果。

    LinkedList: 添加指定下标会先做判断,判断下标是否与现有的链表的size 相同。

       public void add(int index, E element) {
            checkPositionIndex(index);
    
            if (index == size)
                linkLast(element);
            else
                linkBefore(element, node(index));
        }
    

    LinkedList无需提前指定容量,因为基于链表操作,集合的容量随着元素的加入自动增加。

    删除:删除时, Vector 和ArrayList 基于数组的方式进行删除, 但是Vector 的方法都是加入synchronized关键字的。

    LinkedList: 使用unlink 方法对元素进行移除

     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) {//  如果prev 为空,则给定节点为头节点
                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;
        }
    

    查找 :

    Vector 和 ArrayList 的一个意思, 直接返回数组对应下标

      E elementData(int index) {
            return (E) elementData[index];
        }
    

    LinkedList: 对比Vector,ArrayList 来说,查找没有他们方便。

     public E get(int index) {
            checkElementIndex(index);
            return node(index).item;
        }
        
     Node<E> node(int index) {
            // assert isElementIndex(index);
    
            if (index < (size >> 1)) {
                Node<E> x = first;
                for (int i = 0; i < index; i++)
                    x = x.next;
                return x;
            } else {
                Node<E> x = last;
                for (int i = size - 1; i > index; i--)
                    x = x.prev;
                return x;
            }
        }
    
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值