java高级工程师不得不知道的--集合底层实现原理

ArrayList实现原理要点概况

在这里插入图片描述

  • 底层是数组实现

,线程不安全,允许包含null在内的所有元素,允许存放相同元素

  • 数组扩容
    默认长度是10,每次数组容量增长大约是其容量的1.5倍,会将老数组中的元素重新拷贝到新数组中。

  • 查询快,增删慢
    add、remove操作对于ArrayList其运行时间是O(N),因为在它当中在前端进行添加或移除构造新数组是O(N)操作;get方法的调用为O(1)操作。要是使用一个增强的for循环,对于任意List的运行时间都是O(N),因为迭代器将有效地从一项到下一项推进。

LinkedList

  • 底层是双向链表,线程不安全
  • 它的查找是分两半查找,先判断index是在链表的哪一半,然后再去对应区域查找,这样最多只要遍历链表的一半节点即可找到
  • add、remove操作对于LinkedList其运行时间是O(1);get方法的调用为O(N)操作。要是使用一个增强的for循环,对于任意List的运行时间都是O(N),因为迭代器将有效地从一项到下一项推进。

HashMap

  • hashMap是基于哈希表的Map接口的非同步实现,允许使用Null值和Null键,但不保证映射的顺序。
  • 底层是使用数组实现,数组中每一项是个单向链表,即数组和链表的结合体;当链表长度的阈值大于8时,链表转换为红黑树,减少链表查询时间。
    HashMap的负载因子达到0.75的时候会扩容,需要重新计算扩容后每个元素在数组中的位置,比较耗性能

LinkedHashMap

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

ConcurrentHashMap

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

HashSet

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值