Java集合 :List、Map、Set的基本实现原理总结

一、主要内容

1.List

ArrayList

1)ArrayList是List接口的可变数组非同步实现,并允许包括null在内的所有元素。

2)底层使用数组实现

3)该集合是可变长度数组,数组扩容时,会将老数组中的元素重新拷贝一份到新的数组中,每次数组容量增长大约是其容量的1.5倍,这种操作的代价很高。

4)采用了Fail-Fast机制(通过记录modCount参数来标识多个线程操作),面对并发的修改时,迭代器很快就会完全失败,而不是冒着在将来某个不确定时间发生任意不确定行为的风险

5)remove方法会让下标到数组末尾的元素向前移动一个单位,并把最后一位的值置空,方便GC

LinkedList

1)LinkedList是List接口的双向链表非同步实现,并允许包括null在内的所有元素。

2)底层的数据结构是基于双向链表的,该数据结构我们称为节点

3)双向链表节点对应的类Node的实例,Node中包含成员变量:prev,next,item。其中,prev是该节点的上一个节点,next是该节点的下一个节点,item是该节点所包含的值。

4)(没找到对应方法,indexof方法实现是从头开始循环判断元素)它的查找是分两半查找,先判断index是在链表的哪一半,然后再去对应区域查找,这样最多只要遍历链表的一半节点即可找到

Vector

1)动态数组实现的List,跟ArrayList一样,其容量能自动增长

2)JDK1.0引入了,它的很多实现方法都加入了同步语句,因此是线程安全的(在操作数据的方法声明时加synchronized关键字:同步方法,在内部的迭代器操作数据的方法内部的代码块加Vector的synchronized的同步对象锁:同步代码块)

3)适用于快速访问和修改,不适用随机插入和删除(底层实现是对象数组的原因)

4)初始容量大小为10,扩容由初始容量和capacityIncrement共同决定

5)元素允许为null

6)现在已经基本不再使用,如果不需要线程安全的实现,推荐使用ArrayList代替Vector

Vector与ArrayList的区别

最大的是Vector是线程安全的,而ArrayList不是线程安全的。

1)ArrayList不可以设置扩展的容量,默认1.5倍;Vector可以设置扩展的容量,如果没有设置,默认2倍

2)ArrayList的无参构造方法中初始容量为0(初次调用add()会更新为10);Vector的无参构造方法中初始容量为10

3)Vector线程安全,ArrayList线程不安全

2.Map

HashMap

1)HashMap是基于哈希表的Map接口的非同步实现,允许使用null值和null键,但不保证映射的顺序。

2)底层使用数组实现(Node<K,V>数组),数组中每一项是个单向链表,即数组和链表的结合体;

当链表长度大于一定阈值时,链表转换为红黑树,这样减少链表查询时间。

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,马上抛出异常

LinkedHashMap

1)LinkedHashMap继承于HashMap,底层使用哈希表和双向链表来保存所有元素,并且它是非同步,允许使用null值和null键。

2)基本操作与父类HashMap相似,通过重写HashMap相关方法,重新定义了数组中保存的元素Entry,来实现自己的链接列表特性。

该Entry除了保存当前对象的引用外,还保存了其上一个元素before和下一个元素after的引用,从而构成了双向链接列表,用于记录前一个插入的元素和记录后一个插入的元素

HashTable

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

1)ConcurrentHashMap允许多个修改操作并发进行,其关键在于使用了锁分离技术。

2)它使用了多个锁来控制对hash表的不同段进行的修改,每个段其实就是一个小的hashtable,它们有自己的锁。只要多个并发发生在不同的段上,它们就可以并发进行。

3)ConcurrentHashMap在底层将key-value当成一个整体进行处理,这个整体就是一个Entry对象。

4)与HashMap不同的是,ConcurrentHashMap使用多个子Hash表,也就是段(Segment),1.8中改用CAS+synchronized保证并发安全性,将存放数据的 HashEntry 改为 Node

5)ConcurrentHashMap完全允许多个读操作并发进行,读操作并不需要加锁。如果使用传统的技术,如HashMap中的实现,如果允许可以在hash链的中间添加或删除元素,读操作不加锁将得到不一致的数据。ConcurrentHashMap实现技术是保证HashEntry几乎是不可变的。

6)ConCurrentHashMap 在 jdk1.8 中主要做了两方面的改进。

(1) 取消segments字段,直接采用transient volatile HashEntry<K,V>[] table保存数据,

 采用table数组元素作为锁,从而实现了对每一行数据进行加锁,进一步减少并发冲突的概率。

(2) 把Table数组+单向链表的数据结构 变成为 Table数组 + 单向链表 + 红黑树的结构。

 注: 当链表长度超过8以后,单向链表变成了红黑树;  在哈希表扩容时,如果发现链表长度小于 6,则会由红黑树重新退化为链表。
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 205,033评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,725评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,473评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,846评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,848评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,691评论 1 282
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,053评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,700评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,856评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,676评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,787评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,430评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,034评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,990评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,218评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,174评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,526评论 2 343

推荐阅读更多精彩内容