Collection集合,Map两种接口;Vector,LinkedList,ArrayList区别 堆栈;

归纳总结在这:https://blog.csdn.net/u014044812/article/details/48325307

collection不能直接继承,只能通过继承它的子接口set List;

如何遍历collection集合的元素?

Iterator it = collection.iterator(); // 获得一个迭代子
    while(it.hasNext()) {
      Object obj = it.next(); // 得到下一个元素
    }

set接口是无序的,但元素不可重复;

hashset的底层就是hashmap,但是改写了put方法(变成了add方法):就算是equal和hashcode都相同,也不会更改原来的存进去的数据,从而实现了hashset中无重复元素;

List接口是有序的,但元素能重复;

Map就是依靠名-值;

ArrayList不是线程安全的,基于数组实现了一个自动扩容的动态数组;

ArrayList扩容机制:

默认的list长度是10

每次调用add的时候,会去通过ensureCapacityInternal方法确保容量够了;

arraylist中实现的容量增加的方法;

ensureCapacityInternal方法中可以看到每次都是扩容1.5倍;且采用的是Arrays.copyOf方法进行整体拷贝,如果频繁的扩容就会降低性能

可以在已知list长度的时候,指定arraylist初始化的长度,这样可避免自动扩容操作;

ArrayList和Vector都是采用数组来储存数据,都是采用下标查询数据,都不便于插入和删除数据(要前移和后移其他数据);Vector采用了synchronize(多线程情况下,会等前一个线程执行完毕在执行下一个线程),使得它比ArrayList效率更低;

LinkedList:底层是双向链表,遍历数据只能从头或者尾开始查询,非常不便;插入数据和删除数据不需要移动其他数据;

若想线程安全的用ArrayList的话可以用 copyonwriteArrayList

copyonwriteArrayList总结:普通情况下和正常的arraylist增删改查一样,但是当进行了增删改操作时,这时copyonwirteArraylist会先copy出一个容器,然后对这个容器进行刚刚的增删改操作,如果再这个操作期间进行读操作,那么依旧读的是原来的值,而不是正在操作容器里的值,当增删改操作结束后,会把新容器的引用地址赋给原来旧容器的地址;

这个新容器是一个volatile数组,增删改操作是先获取互斥锁,修改数据完毕后再释放互斥锁,将数据更新到volatile数组达到保护数据效果;

Q&A:

  • CopyOnWrite容器即写时复制的容器。通俗的理解是当我们往一个容器添加元素的时候,不直接往当前容器添加,而是先将当前容器进行Copy,复制出一个新的容器,然后新的容器里添加元素,添加完元素之后,再将原容器的引用指向新的容器。这样做的好处是我们可以对CopyOnWrite容器进行并发的读,而不需要加锁,因为当前容器不会添加任何元素。所以CopyOnWrite容器也是一种读写分离的思想,读和写不同的容器

在这里插入图片描述

  • 那为什么不直接修改,而是要拷贝一份修改呢?

        这是为了在“读”的时候不加锁。(以空间换时间的策略)

  • 为了提升读取的效率,修改时不在原数据上修改,而是在复制的数组上修改,改完之后再设置回来,这样做就不会阻塞读的线程

 

栈Stack和队列Queue都可以用Deque来表示:

都用Deque<类型> deque = new LinkedList();来进行初始化

Deque当作使用:

入栈 push(E e)

出栈 poll()

查看栈顶 peek()

Deque当队列使用:

入队列 offer(E e)

出队列 poll()

查看队列首个 peek()

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值