所有示例均在gihub(ssh_base)中====>https://github.com/chengyangyang

ArrayList Vector LinkedList分析

 

  1.创建

  ArrayList 的底层是一个数组。 

     ArrayList<String> list1 = new ArrayList<>();
        list1.add("a");
        ArrayList<String> list2 = new ArrayList<>(list1); // 初始数组 默认的长度为10
        list2.add("A");
        ArrayList<String> list3 = new ArrayList<>(2);   // 初始数组长度

①默认情况,如果没有传递数组的大小,默认使用一个空的数组。如果有,代表使用当前传入长度作为数组,或者数组长度作为数组。

②新增情况下,先要判断数组长度是否够,如果长度不够,需要进行数组的扩增,扩增大小为0.5倍,奇数数舍去。下面为扩增的源码,如果扩增的大小大于integer 最大值,则

使用最大值。在扩增的过程中,需要进行数组的拷贝。这也是新增比较慢的原因,下标新增,也需要后面的数据后移。删除的过程也会涉及到数组的复制。

/**
     * Increases the capacity to ensure that it can hold at least the
     * number of elements specified by the minimum capacity argument.
     *
     * @param minCapacity the desired minimum capacity
     */
    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);
    }

 ③ contains  是遍历数组逐条进行判断。

④clear 清空数据,但是数组的长度并没有变。

 

2. Vector 线程安全的,底层也是使用数组的方式,方法中,安全的都是使用synchronized进行修饰。

3.LinkedList 使用底层链表的方式,也就是需要存储,上一个节点和下一个节点。更占空间,相当于一个节点,多存储了前面和后面的值。

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

采用双向链表的方式进行下标查询,那边近就从哪边开始,没有进行数组的复制,只是更改前面和后面的链表的连接。所以插入和删除比较快。查询遍历的时候,因为根据下标

查询本身就是一个for循环。

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

 

当然当面的线程安全,并不是绝对的线程安全,CopyOnWriteArrayList(是绝对安全的,在新增的过程中,不能进行删除等操作,使用了lock的机制)

public boolean add(E e) {
        final ReentrantLock lock = this.lock;
        lock.lock();
        try {
            Object[] elements = getArray();
            int len = elements.length;
            Object[] newElements = Arrays.copyOf(elements, len + 1);
            newElements[len] = e;
            setArray(newElements);
            return true;
        } finally {
            lock.unlock();
        }
    }

 

posted @ 2019-05-08 12:00  ☞书香门第☜  阅读(158)  评论(0编辑  收藏  举报
http://count.knowsky.com/count1/count.asp?id=434520&sx=1&ys=64"