zoukankan      html  css  js  c++  java
  • 容器总结

    容器总结(不是详解)

    - List
    	ArrayList
    	LinkedList
    	Vector
    	Stack
    	CopyOnWriteArrayList
    - Set
    	HashSet
    	TreeSet
    	LinkedHashSet
    	ConcurrentSkipListSet
    - Map
    	HashMap
    	LinkedHashMap
    	ConcurrentHashMap
    	HashTable
    	TreeMap
    	ConcurrentSkipListMap
    - Queue
    	ConcurrentLinkedQueue
    	LinkedBlockingQueue
    	ArrarBlocakingQueue
    	PriorityQueue
    

    一、概览

    1.List、Set、Map是否继承自Collection接口?

    List、Set 是,Map 不是。Map是键值对映射容器,与List和Set有明显的区别,而Set存储的零散的元素且不允许有重复元素(数学中的集合也是如此),List是线性结构的容器,适用于按数值索引访问元素的情形。
    

    2、Collection和Collections的区别?

    Collection是一个接口,它是Set、List等容器的父接口;
    Collections是个一个工具类,提供了一系列的静态方法来辅助容器操作,这些方法包括对容器的搜索、排序、线程安全化等等。
    

    二、List

    1、各个List的存储性能和特性

    - ArrayList
    	底层:数组
    - Vector
    	底层:数组
    	Vector是线程安全的容器,性能上较ArrayList差
    - Stack
    	底层:Vector
    - LinkedList
    	底层:双向链表
    	从JDK1.7开始,LinkedList 由双向循环链表改为双向链表
    - CopyOnWriteArrayList
    	原理:写复制
    	在很多应用场景中,读操作都远远多于写操作,对于这些场景,我们希望其读操作尽可能快,即使写操作慢一些也没关系。而因为读操作不会对数据进行修改,所以产生了读写锁,其读与读之间不会阻塞,但是读与写、写与写之间还是会阻塞。而CopyOnWriteArrayList进一步优化,将读取性能发挥到了极致,这个容器读与读之间不会阻塞,读与写之间也不会阻塞,只有写与写之间需要同步等待,这样读操作性能得到了提升
    	其原理就是写复制,当这个List需要修改时,并不改变原有内容,而是将原有数据进行复制出一个副本,对副本内容进行修改,修改完成后用修改后的副本替换原有数据。这样就保证写操作不会影响读操作了,而且其内部数组使用了volatile修饰,读取线程可以立即察觉到这个修改。
    	存在问题
    	1.内存占用问题:因进行写操作的时候,内存里会同时驻扎两个对象的内存,旧的对象和新写入的对象。如果这些对象占用的内存比较大,那么这个时候很有可能造成频繁的 GC。
    	数据一致性问题:CopyOnWrite 容器只能保证数据的最终一致性,不能保证数据的实时一致性。所以如果希望写入的的数据马上能读到,就不要使用此容器。
    
    - ArrayList和LinkedListed都是非线程安全的,可以通过工具类Collections中的synchronizedList方法将其转换成线程安全的容器(这是对装潢模式的应用,将已有对象传入另一个类的构造器中创建新的对象来增强实现)
    

    三、Set

    - HashSet
    	底层使用HashMap,遇到hashcode相同的元素不会直接拉链,而是使用equals进行比对,确认不重复再进行插入
    	元素是无序的add(),remove(),contains()方法的时间复杂度是O(1)
    - TreeSet 
    	底层使用TreeMap,TreeMap是底层是红黑树
    	它里面的元素是有序的,add(),remove(),contains()方法的时间复杂度是O(logn) 
    - LinkedHashSet
    	继承自HashSet,内部使用LinkedHashMap
    - ConcurrentSkipListSet
    	底层使用ConcurrentSkipListMap,跳表,输出有序
    

    四、Map

    HashMap
    	以前有写过
    HashTable
    	HashTable和HashMap内部原理相同,Hashtable使用了synchronized关键字,是线程安全的,而HashMap不是线程安全的
    	HashMap允许K/V都为null  HashMapK/V都不允许为null
    TreeMap
    	红黑树
    LinkedHashMap
    	继承自HashMap,每个节点变为双向链表,可以实现按照插入顺序输出元素
    ConcurrentHashMap
    	HashMap不是线程安全的,基于减小锁粒度的原理,我们将HashMap内部分为16段分别加锁,相互之间不需要同步,从而提升其吞吐量
    ConcurrentSkipListMap
    	原理: 跳表,对内部Node所有操作都时基于CAS
    

    五、Queue

    - ConcurrentLinkedQueue
    	基于CAS
    - BlockingQueue
    	- 内部使用生产者消费者模式,当有线程来取数据时,若队列为空,则将其休眠,有数据时将其唤醒。
    - LinkedBlockingQueue
    	-内部使用链表的阻塞队列,适合做无界队列,内部元素可以动态增加,不会因为初始值很大,而占据很大的内存
    - ArrarBlockingQueue
    	- 内部使用队列,适合做有界队列,存取快,但是在创建时需要指定队列大小,提前创建好队列。创建完成后大小不能调整。类似循环链表,有takeIndex和putIndex两个指针,每次从putIndex处存,从takeIndex处取。
    - PriorityQueue
    	-优先队列,使用小顶堆实现,保证根节点为最小元素,每次存取后需要重新调整堆
    

    五、异同

    List和Set区别

    List元素以线性方式存储,集合中可以存放重复对象
    Set集合中的对象不按特定的方式排序,并且没有重复对象
    

    ArrayList和Array有什么区别?

    Array可以容纳基本类型和对象,而ArrayList只能容纳对象。
    Array是指定大小的,而ArrayList大小是固定的
    
  • 相关阅读:
    python对打印出中文乱码问题的解决方案
    git常用操作
    如何创建git开发环境
    对自然界的三种花进行分类
    创建第一个简单的AI分类器
    使用TensorFlow创建第变量定义和运行方式
    MySQL的left,substr,instr截取字符串函数使用实例
    构建之法阅读笔记05
    找水王2
    第十二周学习进度
  • 原文地址:https://www.cnblogs.com/INnoVationv2/p/13169390.html
Copyright © 2011-2022 走看看