jdk Collection和concurrent包 --第一篇

java.util 的各个 Collection

https://blog.csdn.net/anyoneking/article/details/1567808
https://www.cnblogs.com/myseries/p/7508110.html

ArrayList 底层是数组,

public ArrayList() {
        this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
    }
/**
     * Appends the specified element to the end of this list.
     *
     * @param e element to be appended to this list
     * @return <tt>true</tt> (as specified by {@link Collection#add})
     */
    public boolean add(E e) {
        ensureCapacityInternal(size + 1);  // Increments modCount!!
        elementData[size++] = e;
        return true;
    }

ArrayList 每增加一个元素,都是下标加1的地方 赋值为 该元素。

public E get(int index) {
        rangeCheck(index);

        return elementData(index);
    }

每查询一个元素,都是传入下标,然后直接到 数组里面找 元素。

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

每删除一个元素,需要操作的数据比较多;如果删除的是ArrayList的第一个元素,那么所有后面的元素 都需要移动位置(向前移动一格)。

public E remove(int index) {
        rangeCheck(index);

        modCount++;
        E oldValue = elementData(index);

        int numMoved = size - index - 1;
        if (numMoved > 0)
            System.arraycopy(elementData, index+1, elementData, index,
                             numMoved);
        elementData[--size] = null; // clear to let GC do its work

        return oldValue;
    }
     * @param      src      the source array.
     * @param      srcPos   starting position in the source array.
     * @param      dest     the destination array.
     * @param      destPos  starting position in the destination data.
     * @param      length   the number of array elements to be copied.
     * @exception  IndexOutOfBoundsException  if copying would cause
     *               access of data outside array bounds.
     * @exception  ArrayStoreException  if an element in the <code>src</code>
     *               array could not be stored into the <code>dest</code> array
     *               because of a type mismatch.
     * @exception  NullPointerException if either <code>src</code> or
     *               <code>dest</code> is <code>null</code>.
     */
    public static native void arraycopy(Object src,  int  srcPos,
                                        Object dest, int destPos,
                                        int length);

 

ArrayList 底层是链表,先看网址的链表结构:

https://www.cnblogs.com/beppezhang/p/6564633.html

public boolean add(E e) {
        linkLast(e);
        return true;
    }

 

/**
     * Links e as last element.
     */
    void linkLast(E e) {
        final Node<E> l = last;
        //新元素作为最后一个元素,新元素的prev指向原来的最后一个元素;最后一个元素的next为null
        final Node<E> newNode = new Node<>(l, e, null);
        last = newNode;
        if (l == null)
            //原来的list为空,则新元素既是第一个元素,也是最后一个元素
            first = newNode;
        else
        	  //原来的list非空,则原来的新元素的next指向新插入的元素
            l.next = newNode;
        size++;
        modCount++;
    }

add方法,在不指明插入位置的情况下,默认将元素插入list的最后。

 

linkedList的get方法,就比较消耗时间

public E get(int index) {
        checkElementIndex(index);
        return node(index).item;
    }
//使用了二分法查找,如果index在list的前面一半,从first开始查找;否则从last开始查找
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;
        }
    }

linkedList的remove方法,修改指向 即可

public E remove(int index) {
        checkElementIndex(index);
        return unlink(node(index));
    }
//逻辑是将上一个元素的next指向删除元素的下一个元素,将下一个元素的prev指向删除元素的上一个元素
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;
    }

Vector就不展开了,与Arraylist的区别 就是加了同步synchronized的功能。

Arraylist和Vector是采用数组方式存储数据,此数组元素数大于实际存储的数据以便增加插入元素,都允许直接序号索引元素,但是插入数据要涉及到数组元素移动等内存操作,所以插入数据慢,查找有下标,所以查询数据快,Vector由于使用了synchronized方法-线程安全,所以性能上比ArrayList要差,LinkedList使用双向链表实现存储,按序号索引数据需要进行向前或向后遍历,但是插入数据时只需要记录本项前后项即可,插入数据较快。

再看stack, stack继承的Vector, 所以底层也是 数组结构

参考网址: https://www.cnblogs.com/zj0208/p/6296709.html

将数据 压入栈:

public E push(E item) {
        addElement(item);

        return item;
    }
public synchronized void addElement(E obj) {
        modCount++;
        ensureCapacityHelper(elementCount + 1);
        //将数组的最后一个字段的值 置为 新增的值
        elementData[elementCount++] = obj;
    }

 

peek方法获取栈顶元素,但并不移除,如果是空栈,会抛出异常:EmptyStackException。

栈顶元素 对于数组来说,是数组的末尾元素。

public synchronized E peek() {
        int     len = size();

        if (len == 0)
            throw new EmptyStackException();
        return elementAt(len - 1);
    }
// pop方法移除并返回栈顶元素,如果是空栈,会抛出异常:EmptyStackException(pop
方法 效率低,因为有 System.arraycopy(elementData, index + 1, elementData, index, j); 动作
)
public synchronized E pop() {
        E       obj;
        int     len = size();

        obj = peek();
        removeElementAt(len - 1);

        return obj;
    }

 

queue队列(太多了, 进入下一章):

https://www.cnblogs.com/lemon-flm/p/7877898.html

 

java.util.concurrent

 

 


每个线程安全类的底层实现 做分类
https://blog.csdn.net/lh87522/article/details/45973373
https://blog.csdn.net/windsunmoon/article/details/36903901


java.util.concurrent.atomic
每个线程安全类的底层实现 使用CAS吗?

java.util.concurrent.locks?
看可重入锁, 读写锁

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值