List

作者: Joker____ | 来源:发表于2018-03-26 14:25 被阅读0次

    简述

    List的实现主要有如下几种

    • ArrayList
    • LinkedList
    • Vector

    ArrayList

    继承自AbstractList,实现List


    image.png
     /**
         * 默认初始化数组值
         */
        private static final int DEFAULT_CAPACITY = 10;
    
        /**
         * 空数组
         */
        private static final Object[] EMPTY_ELEMENTDATA = {};
    
        /**
         * 默认空数组
         */
        private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};
    
        /**
         * 真正数组
         */
        transient Object[] elementData; // non-private to simplify nested class access
    
        /**
         * The size of the ArrayList (the number of elements it contains).
         *
         * @serial
         */
        private int size;
    

    若用户定义数组大小则根据用户的值进行设置数组大小。

    public ArrayList(int initialCapacity) {
            if (initialCapacity > 0) {
                this.elementData = new Object[initialCapacity];
            } else if (initialCapacity == 0) {
                this.elementData = EMPTY_ELEMENTDATA;
            } else {
                throw new IllegalArgumentException("Illegal Capacity: "+
                                                   initialCapacity);
            }
        }
    

    若无入参,ArrayList使用延迟初始化的方式,在构造的时候没有初始化数组,在真正使用的时候才加载,避免用户不良的创建来构造过多的数组。

    public ArrayList() {
            this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
        }
    
     public boolean add(E e) {
            ensureCapacityInternal(size + 1);  // Increments modCount!!
            elementData[size++] = e;
            return true;
        }
    private void ensureCapacityInternal(int minCapacity) {
            if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
                minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
            }
    
            ensureExplicitCapacity(minCapacity);
        }
    
    

    扩容

    private void ensureCapacityInternal(int minCapacity) {
            if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
                minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
            }
    
            ensureExplicitCapacity(minCapacity);
        }
    
        private void ensureExplicitCapacity(int minCapacity) {
            modCount++;
    
            // overflow-conscious code
            if (minCapacity - elementData.length > 0)
                grow(minCapacity);
        }
    private void grow(int minCapacity) {
            // overflow-conscious code
            int oldCapacity = elementData.length;
            //通常情况是通过移位运算将数组增加了0.5倍
            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);
        }
    

    数组增大0.5倍并进行数组的拷贝。可以进行优化。

    为什么AbstractList已经实现了List,ArrayList仍然需要实现List?

    ArrayList只使用Abstract的某些方法,不完全使用。所以需要专门实现List接口。


    LinkedList

    LinkedList是一个双向链表实现的一个List。


    image.png
    transient int size = 0;
    
       //链表头节点
        transient Node<E> first;
    
        //链表尾节点
        transient Node<E> last;
    

    Node节点

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

    add

    public boolean add(E e) {
            linkLast(e);
            return true;
    }
    /**
    *使用尾插法,新插入的节点设为尾部
    */
    void linkLast(E e) {
            final Node<E> l = last;
            final Node<E> newNode = new Node<>(l, e, null);
            last = newNode;
            if (l == null)
                first = newNode;
            else
                l.next = newNode;
            size++;
            modCount++;
    }
    

    remove

    public E remove() {
            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;
        }
    

    还有其他一些链表的操作不做说明。中间插入、中间删除等。

    相关文章

      网友评论

          本文标题:List

          本文链接:https://www.haomeiwen.com/subject/nilrcftx.html