集合各实现类的底层实现原理

ArrayList实现原理要点概括

参考文献:
http://zhangshixi.iteye.com/blog/674856l
https://www.cnblogs.com/leesf456/p/5308358.html

特点:查询速度快,增加删除慢

  1. ArrayList是List接口的可变数组非同步(线程不安全)实现,并允许包括null在内的所有元素。
  2. 底层使用Object数组实现,默认的容量是10。
  3. 该集合是可变长度数组,数组扩容时,会将老数组中的元素重新拷贝一份到新的数组中,每次数组容量增长大约是其容量的1.5倍,这种操作的代价很高。若是能预估到顶峰容量,可以设置一个足够大的量以避免数组容量以后的扩展。
  4. 采用了Fail-Fast机制,面对并发的修改时,迭代器很快就会完全失败,而不是冒着在将来某个不确定时间发生任意不确定行为的风险
  5. remove方法会让下标到数组末尾的元素向前移动一个单位,并把最后一位的值置空,方便GC
  6. add、remove操作对于ArrayList其运行时间是O(N),因为在它当中在前端进行添加或移除构造新数组是O(N)操作;get方法的调用为O(1)操作。要是使用一个增强的for循环,对于任意List的运行时间都是O(N),因为迭代器将有效地从一项到下一项推进。

LinkedList实现原理要点概括

参考文献:
 http://www.cnblogs.com/ITtangtang/p/3948610.html
 https://www.cnblogs.com/leesf456/p/5308843.html

特点:查询速度慢,增加删除快,可以作为队列使用。

  1. LinkedList是List接口的双向链表非同步(线程不安全)实现,并允许包括null在内的所有元素。
  2. 底层的数据结构是基于双向链表的,该数据结构我们称为节点
  3. 双向链表节点对应的类Node的实例,Node中包含成员变量:prev,next,item。其中,prev是该节点的上一个节点,next是该节点的下一个节点,item是该节点所包含的值。在根据索引查找结点时,会有一个小优化,结点在前半段则从头开始遍历,在后半段则从尾开始遍历,这样就保证了只需要遍历最多一半结点就可以找到指定索引的结点。
  4. LinkedList底层是双向链表,查询数据依次遍历慢。写数据只需修改指针引用,所以效率高。
  5. add、remove操作对于LinkedList其运行时间是O(1);get方法的调用为O(N)操作。要是使用一个增强的for循环,对于任意List的运行时间都是O(N),因为迭代器将有效地从一项到下一项推进。                                                                                     
  6.  ArrayList和LinkedList都不是线程安全的,小并发量的情况下可以使用Vector,若并发量很多,且读多写少可以考虑使用CopyOnWriteArrayList。因为CopyOnWriteArrayList底层使用ReentrantLock锁,比使用synchronized关键字的Vector能更好的处理锁竞争的问题。                                                                                                                                                                           
  7.  LinkedList实现了Deque接口,Deque接口表示是一个双端队列,那么也意味着LinkedList是双端队列的一种实现,所以,基于双端队列的操作在LinkedList中全部有效。

 

Vector实现原理要点概括

参考文献:
 https://my.oschina.net/90888/blog/1625505
 https://blog.csdn.net/lingmao555/article/details/50736341

特点:查询速度快,增加删除慢,线程安全。

  1. Vector为存储的对象分配一块连续的地址空间,因此对vector中的元素随机访问效率很高。 
  2. 在Vector中插入或者删除某个元素,需要将现有元素进行复制,移动。如果vector中存储的对象很大,或者构造函数复杂,则在对现有元素进行拷贝时开销较大,因为拷贝对象要调用拷贝构造函数。           
  3.   对于简单的小对象,vector的效率优于arrayList。vector在每次扩张容量的时候,将容量扩展2倍,这样对于小对象来说,效率是很高的。                                                                                                                                 
  4. Vector是线程安全的,但是性能比ArrayList要低。

 

HashMap实现原理要点概括


参考文献:http://zhangshixi.iteye.com/blog/672697
参考文献:http://blog.csdn.net/lizhongkaide/article/details/50595719

  1. HashMap是基于哈希表的Map接口的非同步(线程不安全)实现,允许使用null值和null键,但不保证映射的顺序。
  2. 底层使用数组实现,数组中每一项是个单向链表,即数组和链表的结合体;当链表长度大于一定阈值时,链表转换为红黑树,这样减少链表查询时间。源码是链表长度大于阈值(默认为8),但是数组长度小于64时会首先进行扩容,否则才会转化为红黑树。
  3. HashMap在底层将key-value当成一个整体进行处理,这个整体就是一个Node对象。HashMap底层采用一个Node[]数组来保存所有的key-value对,当需要存储一个Node对象时,会根据key的hash算法来决定其在数组中的存储位置,在根据equals方法决定其在该数组位置上的链表中的存储位置;当需要取出一个Node时,也会根据key的hash算法找到其在数组中的存储位置,再根据equals方法从该位置上的链表中取出该Node。
  4. HashMap进行数组扩容需要重新计算扩容后每个元素在数组中的位置,很耗性能。
  5. 采用了Fail-Fast机制,通过一个modCount值记录修改次数,对HashMap内容的修改都将增加这个值。迭代器初始化过程中会将这个值赋给迭代器的expectedModCount,在迭代过程中,判断modCount跟expectedModCount是否相等,如果不相等就表示已经有其他线程修改了Map,马上抛出异常。


Hashtable实现原理要点概括

参考文献:http://blog.csdn.net/zheng0518/article/details/42199477  

  1. Hashtable是基于哈希表的Map接口的同步实现,不允许使用null值和null键
  2. 底层使用数组实现,数组中每一项是个单链表,即数组和链表的结合体
  3. Hashtable在底层将key-value当成一个整体进行处理,这个整体就是一个Entry对象。Hashtable底层采用一个Entry[]数组来保存所有的key-value对,当需要存储一个Entry对象时,会根据key的hash算法来决定其在数组中的存储位置,在根据equals方法决定其在该数组位置上的链表中的存储位置;当需要取出一个Entry时,也会根据key的hash算法找到其在数组中的存储位置,再根据equals方法从该位置上的链表中取出该Entry。
  4. synchronized是针对整张Hash表的,即每次锁住整张表让线程独占


ConcurrentHashMap实现原理要点概括


参考文献:https://blog.csdn.net/zheng0518/article/details/51704878

  1. ConcurrentHashMap允许多个修改操作并发进行,其关键在于使用了锁分离技术。
  2. 它使用了多个锁来控制对hash表的不同段进行的修改,每个段其实就是一个小的hashtable,它们有自己的锁。只要多个并发发生在不同的段上,它们就可以并发进行。
  3. ConcurrentHashMap在底层将key-value当成一个整体进行处理,这个整体就是一个Entry对象。Hashtable底层采用一个Entry[]数组来保存所有的key-value对,当需要存储一个Entry对象时,会根据key的hash算法来决定其在数组中的存储位置,在根据equals方法决定其在该数组位置上的链表中的存储位置;当需要取出一个Entry时,也会根据key的hash算法找到其在数组中的存储位置,再根据equals方法从该位置上的链表中取出该Entry。
  4. 与HashMap不同的是,ConcurrentHashMap使用多个子Hash表,也就是段(Segment)
  5. ConcurrentHashMap完全允许多个读操作并发进行,读操作并不需要加锁。如果使用传统的技术,如HashMap中的实现,如果允许可以在hash链的中间添加或删除元素,读操作不加锁将得到不一致的数据。ConcurrentHashMap实现技术是保证HashEntry几乎是不可变的。


LinkedHashMap实现原理要点概括

参考文献:http://zhangshixi.iteye.com/blog/673789l

  1. LinkedHashMap继承于HashMap,底层使用哈希表和双向链表来保存所有元素,并且它是非同步,允许使用null值和null键。
  2. 基本操作与父类HashMap相似,通过重写HashMap相关方法,重新定义了数组中保存的元素Entry,来实现自己的链接列表特性。该Entry除了保存当前对象的引用外,还保存了其上一个元素before和下一个元素after的引用,从而构成了双向链接列表。

HashSet实现原理要点概括


参考文献:http://zhangshixi.iteye.com/blog/673143l

  1. HashSet由哈希表(实际上是一个HashMap实例)支持,不保证set的迭代顺序,并允许使用null元素。
  2. 基于HashMap实现,API也是对HashMap的行为进行了封装,可参考HashMap

LinkedHashSet实现原理要点概括


参考文献:http://zhangshixi.iteye.com/blog/673319l

  1. 对于LinkedHashSet而言,它继承与HashSet、又基于LinkedHashMap来实现的。LinkedHashSet底层使用LinkedHashMap来保存所有元素,它继承与HashSet,其所有的方法操作上又与HashSet相同。

————————————————
版权声明:本文为CSDN博主「金霖」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_25868207/article/details/55259978

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值