目录

一、主要内容

1.List

ArrayList

LinkedList

Vector

Vector与ArrayList的区别

Collections.SynchronizedList和Vector的区别

同步代码块和同步方法的区别

2.Map

HashMap

LinkedHashMap

HashTable

ConcurrentHashMap

3.Set

HashSet

LinkedHashSet

二、参考文献


一、主要内容

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线程不安全

原文:https://blog.csdn.net/lipinganq/article/details/78043065

Collections.SynchronizedList和Vector的区别

1) 如果使用add方法,那么他们的扩容机制不一样。

2) SynchronizedList可以指定锁定的对象。

(Collections.SynchronizedList只是使用同步代码块包裹了ArrayList的方法,而ArrayList和Vector中同名方法的方法体内容并无太大差异,所以在锁定范围和锁的作用域上两者并无却别。 在锁定的对象区别上,SynchronizedList的同步代码块锁定的是mutex对象,Vector锁定的是this对象。那么mutex对象是SynchronizedList在使用构造函数时可以传入一个Object,如果在调用的时候显示的传入一个对象,那么锁定的就是用户传入的对象。如果没有指定,那么锁定的也是this对象。)

同步代码块和同步方法的区别

1) 同步代码块在锁定的范围上可能比同步方法要小,一般来说锁的范围大小和性能是成反比的。

2) 同步块可以更加精确的控制锁的作用域(锁的作用域就是从锁被获取到其被释放的时间),同步方法的锁的作用域就是整个方法。

3) 静态代码块可以选择对哪个对象加锁,但是静态方法只能给this对象加锁。

静态变量与静态代码块加载时间:当类加载器将类加载到JVM中的时候就会创建静态变量,这跟对象是否创建无关。静态变量加载的时候就会分配内存空间。静态代码块的代码只会在类第一次初始化的时候执行一次。

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

HashMap结构:

相关参考:

Java中HashMap底层实现原理(JDK1.8)源码分析:

https://blog.csdn.net/tuke_tuke/article/details/51588156

LinkedHashMap

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

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

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

相关参考:https://www.cnblogs.com/whgk/p/6169622.html

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,则会由红黑树重新退化为链表。

相关参考:

[1] 深入学习Java集合之ConcurrentHashMap的实现原理(jdk1.7与1.8)

https://blog.csdn.net/J080624/article/details/86838129

[2] ConCurrentHashMap 在 jdk1.8

https://blog.csdn.net/bigtree_3721/article/details/84255655

3.Set

HashSet

1)HashSet由哈希表(实际上是一个HashMap实例)支持,不保证set的迭代顺序,并允许使用null元素。

2)基于HashMap实现,API也是对HashMap的行为进行了封装,可参考HashMap

相关参考:深入Java集合学习系列:HashSet的实现原理:

https://zhangshixi.iteye.com/blog/673143

LinkedHashSet

继承与HashSet、又基于LinkedHashMap来实现的(主要通过传递参数调用父类的构造函数实现)。LinkedHashSet底层使用LinkedHashMap来保存所有元素,它继承与HashSet,其所有的方法操作上又与HashSet相同。源码内部主要是四个不同的构造函数。

相关参考:深入Java集合学习系列:LinkedHashSet的实现原理:

https://zhangshixi.iteye.com/blog/673319

二、参考文献

[1] List、set、Map的底层实现原理(文章未包含的其余连接出处):

https://blog.csdn.net/xzp_12345/article/details/79251174

[2] Vector原理讲解:https://blog.csdn.net/lipinganq/article/details/78043065

[3] Java中HashMap底层实现原理(JDK1.8)源码分析:

https://blog.csdn.net/tuke_tuke/article/details/51588156

[4] LinkedHashMap图解:https://www.cnblogs.com/whgk/p/6169622.html

[5] 深入学习Java集合之ConcurrentHashMap的实现原理(jdk1.7与1.8):

https://blog.csdn.net/J080624/article/details/86838129

[6] ConCurrentHashMap 在 jdk1.8:

https://blog.csdn.net/bigtree_3721/article/details/84255655

[7] 深入Java集合学习系列: HashSet的实现原理:

https://zhangshixi.iteye.com/blog/673143

[8] 深入Java集合学习系列:LinkedHashSet的实现原理:

https://zhangshixi.iteye.com/blog/673319

Java集合系列(一):List、Map、Set的基本实现原理总结相关推荐

  1. Java 集合系列14之 Map总结(HashMap, Hashtable, TreeMap, WeakHashMap等使用场景)

    概要 学完了Map的全部内容,我们再回头开开Map的框架图. 本章内容包括: 第1部分 Map概括 第2部分 HashMap和Hashtable异同 第3部分 HashMap和WeakHashMap异 ...

  2. Java 集合系列目录(Category)

    Java 集合系列目录(Category) 转自:Java 集合系列目录(Category) 01. Java 集合系列01之 总体框架 02. Java 集合系列02之 Collection架构 0 ...

  3. 新手菜鸟 Java 集合系列目录(Category)

    Java 集合系列01之 总体框架 http://www.cnblogs.com/skywang12345/p/3308498.html (笔记:Java集合是java提供的工具包,包含了常用的数据结 ...

  4. Java集合系列之四大常用集合(ArrayList、LinkedList、HashSet、HashMap)的用法

    Java集合系列之四大常用集合(ArrayList.LinkedList.HashSet.HashMap)的用法 ArrayList ArrayList就是传说中的动态数组,用MSDN中的说法,就是A ...

  5. Java 集合系列 16 HashSet

    java 集合系列目录: Java 集合系列 01 总体框架 Java 集合系列 02 Collection架构 Java 集合系列 03 ArrayList详细介绍(源码解析)和使用示例 Java ...

  6. java集合系列——java集合概述(一)

    在JDK中集合是很重要的,学习java那么一定要好好的去了解一下集合的源码以及一些集合实现的思想! 一:集合的UML类图(网上下载的图片) Java集合工具包位置是java.util.* 二:集合工具 ...

  7. Java 集合系列02之 Collection架构

    概要 首先,我们对Collection进行说明.下面先看看Collection的一些框架类的关系图: Java 集合系列02之 Collection架构 Collection是一个接口,它主要的两个分 ...

  8. Java 集合系列06: Vector深入解析

    戳上面的蓝字关注我们哦! 精彩内容 精选java等全套视频教程 精选java电子图书 大数据视频教程精选 java项目练习精选 概论 这是接着以前的文章分享的,这里给出以前的文章的连接,供小伙伴们回顾 ...

  9. Java 集合系列(一)

    Java集合系列文章将以思维导图为主要形式来展示知识点,让零碎的知识形成体系. 这篇文章主要介绍的是[Java 集合的基本知识],即Java 集合简介. 毕业出来一直使用 PHP 进行开发,对于大学所 ...

  10. 深入Java集合系列之五:PriorityQueue

    转载自  深入Java集合系列之五:PriorityQueue 前言 今天继续来分析一下PriorityQueue的源码实现,实际上在Java集合框架中,还有ArrayDeque(一种双端队列),这里 ...

最新文章

  1. 综述:NLP中的深度学习优势
  2. 日本“女机器人”畅销全球,有三个地方最吸引人,网友:想拥有
  3. 山东大学和哈工大的教师招聘条件对比,心里要有点数
  4. 设计模式(Design Pattern)
  5. Flutter 之 StatefulWidget和StatelessWidget
  6. VS2010调试小技巧
  7. java 异常处理 简书_Java基础知识8-异常处理
  8. opencv-api minEnclosingCircle
  9. 【编程开发】 C与C++中的关于函数指针的强制类型转换与指针函数的关系
  10. solr的索引库配置
  11. java中handler机制_自己动手撸一个Handler,让你彻底搞懂Handler机制,揍吻你服不服?...
  12. 设计模式之观察者模式(Java实现)
  13. Pandas读取excel数据——pearson相关性分析
  14. [Constraints 18-5210] No constraints selected for write.
  15. 由frankmocap得到的.pkl文件转为.bvh或者.fbx
  16. 网络发现自动关闭不能启用、无法启用文件和打印共享的解决办法
  17. mysql报1142错误
  18. python情人节之玫瑰花与表白方式,用python画一朵玫瑰花,拿去表白趴
  19. LiteOS 消息队列
  20. 计算机二级报名时间2020年12月江苏省,2020年12月计算机二级考试报名时间及考试安排...

热门文章

  1. stm32时钟问题简单介绍
  2. 我在atcoder打比赛
  3. OA系统以项目管理为中心,为会计事务所打造内外协同一体化平台
  4. nfsd linux是什么进程,如何从NFS启动Linux及原理
  5. 计算机高中期末总结作文,期末考试总结作文(精选5篇)
  6. Filament介绍
  7. 在计算机语言中go是什么意思,golang中的断言是什么意思
  8. 【数据库数据恢复】华为云mysql数据库数据被delete的数据恢复案例
  9. MySQL inet aton函数_MySQL INET_ATON()用法及代码示例
  10. C-Kermit在linux 下的安装和使用