简单图:

1.List

  • Arraylist: Object数组
  • Vector: Object数组
  • LinkedList: 双向链表(JDK1.6之前为循环链表,JDK1.7取消了循环)

2.Set

  • HashSet(无序,唯一): 基于 HashMap 实现的,底层采用 HashMap 来保存元素
  • LinkedHashSet: LinkedHashSet 继承与 HashSet,并且其内部是通过 LinkedHashMap 来实现的。有点类似于我们之前说的LinkedHashMap 其内部是基于 Hashmap 实现一样,不过还是有一点点区别的。
  • TreeSet(有序,唯一): 红黑树(自平衡的排序二叉树。)

3.Map

  • HashMap: JDK1.8之前HashMap由数组+链表组成的,数组是HashMap的主体,链表则是主要为了解决哈希冲突而存在的(“拉链法”解决冲突)。JDK1.8以后在解决哈希冲突时有了较大的变化,当链表长度大于阈值(默认为8)时,将链表转化为红黑树,以减少搜索时间
  • LinkedHashMap: LinkedHashMap 继承自 HashMap,所以它的底层仍然是基于拉链式散列结构即由数组和链表或红黑树组成。另外,LinkedHashMap 在上面结构的基础上,增加了一条双向链表,使得上面的结构可以保持键值对的插入顺序。同时通过对链表进行相应的操作,实现了访问顺序相关逻辑。
  • Hashtable: 数组+链表组成的,数组是 HashMap 的主体,链表则是主要为了解决哈希冲突而存在的
  • TreeMap: 红黑树(平衡二叉排序树)

-----------------------------------------------------------------------

Arraylist说明:

底层是数组队列,相当于动态数组。与 Java 中的数组相比,它的容量能动态增长。在添加大量元素前,应用程序可以使用ensureCapacity操作来增加 ArrayList 实例的容量。这可以减少递增式再分配的数量。

它继承于 AbstractList,实现了 ListRandomAccessCloneablejava.io.Serializable 这些接口。

数据结构-线性表的顺序存储,插入删除元素的时间复杂度为O(n),求表长以及增加元素,取第 i 元素的时间复杂度为O(1)

  ArrayList 继承了AbstractList,实现了List。它是一个数组队列,提供了相关的添加、删除、修改、遍历等功能。

  ArrayList 实现了RandomAccess 接口, RandomAccess 是一个标志接口,表明实现这个接口的 List 集合是支持快速随机访问的。在 ArrayList 中,我们即可以通过元素的序号快速获取元素对象,这就是快速访问-随机存取。

  ArrayList 实现了Cloneable 接口,即覆盖了函数 clone(),能被克隆

  ArrayList 实现java.io.Serializable 接口,这意味着ArrayList支持序列化能通过序列化去传输

  和 Vector 不同,ArrayList 中的操作不是线程安全的!所以,建议在单线程中才使用 ArrayList,而在多线程中可以选择 Vector 或者 CopyOnWriteArrayList

什么是fail-fast?

fail-fast机制是java集合中的一种错误机制。

当使用迭代器迭代时,如果发现集合有修改,则快速失败做出响应,抛出ConcurrentModificationException异常。

这种修改有可能是其它线程的修改,也有可能是当前线程自己的修改导致的,比如迭代的过程中直接调用remove()删除元素等。

另外,并不是java中所有的集合都有fail-fast的机制。比如,像最终一致性的ConcurrentHashMap、CopyOnWriterArrayList等都是没有fast-fail的。

fail-fast是怎么实现的:

ArrayList、HashMap中都有一个属性叫modCount,每次对集合的修改这个值都会加1,在遍历前记录这个值到expectedModCount中,遍历中检查两者是否一致,如果出现不一致就说明有修改,则抛出ConcurrentModificationException异常。

底层数组存/取元素效率非常的高(get/set),时间复杂度是O(1),而查找(比如:indexOf,contain),插入和删除元素效率不太高,时间复杂度为O(n)。

插入/删除元素会触发底层数组频繁拷贝,效率不高,还会造成内存空间的浪费,解决方案:linkedList

查找元素效率不高,解决方案:HashMap(红黑树)

LinkedList说明:

LinkedList是一个实现了List接口和Deque接口的双端链表。 LinkedList底层的链表结构使它支持高效的插入和删除操作,另外它实现了Deque接口,使得LinkedList类也具有队列的特性; LinkedList不是线程安全的,如果想使LinkedList变成线程安全的,可以调用静态类Collections类中的synchronizedList方法:

List list=Collections.synchronizedList(new LinkedList(...));

HashMap 说明:

DK1.8 之前 HashMap 由 数组+链表 组成的,数组是 HashMap 的主体,链表则是主要为了解决哈希冲突而存在的(“拉链法”解决冲突).JDK1.8 以后在解决哈希冲突时有了较大的变化,当链表长度大于阈值(默认为 8)时,将链表转化为红黑树,以减少搜索时间。所谓扰动函数指的就是 HashMap 的 hash 方法。使用 hash 方法也就是扰动函数是为了防止一些实现比较差的 hashCode() 方法 换句话说使用扰动函数之后可以减少碰撞。

DK 1.8 的 hash方法 相比于 JDK 1.7 hash 方法更加简化,但是原理不变。static final int hash(Object key) {int h;// key.hashCode():返回散列值也就是hashcode// ^ :按位异或// >>>:无符号右移,忽略符号位,空位都以0补齐return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);}
对比一下 JDK1.7的 HashMap 的 hash 方法源码.static int hash(int h) {// This function ensures that hashCodes that differ only by// constant multiples at each bit position have a bounded// number of collisions (approximately 8 at default load factor).h ^= (h >>> 20) ^ (h >>> 12);return h ^ (h >>> 7) ^ (h >>> 4);
}
相比于 JDK1.8 的 hash 方法 ,JDK 1.7 的 hash 方法的性能会稍差一点点,因为毕竟扰动了 4 次。

HashMap多线程操作导致死循环问题----

主要原因在于并发下的Rehash 会造成元素之间会形成一个循环链表。不过,jdk 1.8 后解决了这个问题,但是还是不建议在多线程下使用 HashMap,因为多线程下使用 HashMap 还是会存在其他问题如数据丢失。并发环境下推荐使用 ConcurrentHashMap 。

【为什么我们调用 start() 方法时会执行 run() 方法,为什么我们不能直接调用 run() 方法?

这是另一个非常经典的 java 多线程面试问题,而且在面试中会经常被问到。很简单,但是很多人都会答不上来!

new 一个 Thread,线程进入了新建状态;调用 start() 方法,会启动一个线程并使线程进入了就绪状态,当分配到时间片后就可以开始运行了。 start() 会执行线程的相应准备工作,然后自动执行 run() 方法的内容,这是真正的多线程工作。 而直接执行 run() 方法,会把 run 方法当成一个 main 线程下的普通方法去执行,并不会在某个线程中执行它,所以这并不是多线程工作。

总结: 调用 start 方法方可启动线程并使线程进入就绪状态,而 run 方法只是 thread 的一个普通方法调用,还是在主线程里执行。】

JDK提供的并发容器大部分在 java.util.concurrent 包中。

  • ConcurrentHashMap: 线程安全的HashMap
  • CopyOnWriteArrayList: 线程安全的List,在读多写少的场合性能非常好,远远好于Vector.
  • ConcurrentLinkedQueue: 高效的并发队列,使用链表实现。可以看做一个线程安全的 LinkedList,这是一个非阻塞队列。
  • BlockingQueue: 这是一个接口,JDK内部通过链表、数组等方式实现了这个接口。表示阻塞队列,非常适合用于作为数据共享的通道。
  • ConcurrentSkipListMap: 跳表的实现。这是一个Map,使用跳表的数据结构进行快速查找。

...待更新

java-集合框架底层数据结构总结相关推荐

  1. Java集合框架底层原理

    Java集合框架 Java集合框架 List集合 ArrayList底层实现原理 ArrayList数组扩容技术(数组拷贝) 扩容大小 查询和删除 集合中的泛型 LinkedList Vector 线 ...

  2. Java集合框架底层源码

    集合底层源码 Collection List ArrayList public abstract class AbstractList<E>{//操作数protected transien ...

  3. 容器(一)剖析面试最常见问题之 Java 集合框架

    转载自https://github.com/Snailclimb/JavaGuide/blob/master/docs/java/collection/Java%E9%9B%86%E5%90%88%E ...

  4. java list有序还是无序_牛批!2w字的Java集合框架面试题精华集(2020最新版),赶紧收藏。...

    一个多月前,作者和一些小伙伴决定做一系列的 Java 知识点常见重要问题的小册,方便用来夯实基础!小册的标准就一个,那就是:取精华,取重点.每一本小册,我们都会充分关注我们所总结的知识点是否达到这个标 ...

  5. 「Java面试题精华集」1w字的Java集合框架篇(2022最新版)附PDF版

    昨天晚上终于把 Java 集合框架部分的的知识点肝完了,转换成 PDF 一共 25 页,后台回复:"面试突击" 即可免费获取下载地址(同样提供了夜间阅读版本). 集合概述 Java ...

  6. Java集合框架(JCF)归纳总结

    Java集合框架--JCF,在java 1.2版本中被加入,它包含了大量集合操作,是Java体系中的重要组成部分.网上已有很多JCF的框架图,这里根据自己的理解整理了一份JCF框架图如下: JCF主要 ...

  7. Java集合框架综述,这篇让你吃透!

    点击上方"方志朋",选择"设为星标" 回复"666"获取新整理的面试文章 作者:平凡希 cnblogs.com/xiaoxi/p/60899 ...

  8. 【Java集合框架】ArrayList类方法简明解析(举例说明)

    本文目录 1.API与Java集合框架 2.ArrayList类方法解析 2.1 add() 2.2 addAll() 2.3 clear() 2.4 clone() 2.5 contains() 2 ...

  9. java集合框架史上最详解(list set 以及map)

    title: Java集合框架史上最详解(list set 以及map) tags: 集合框架 list set map 文章目录 一.集合框架总体架构 1.1 集合框架在被设计时需满足的目标 1.2 ...

  10. java集合框架综述

    一.集合框架图 简化图: 说明:对于以上的框架图有如下几点说明 1.所有集合类都位于java.util包下.Java的集合类主要由两个接口派生而出:Collection和Map,Collection和 ...

最新文章

  1. visual studio 2013 中配置OpenCV2.4.13 姿势
  2. 特征工程在实际业务中的应用!
  3. 没有数据也能翻译?一文读懂「无监督」机器翻译
  4. 《为了你我愿意热爱整个世界》
  5. 微服务架构 — 服务治理 — 服务注册与发现、服务订阅与通知
  6. 中小型企业开展网站关键词优化,怎样才能达到理想优化效果?
  7. gview java_java - 如何在干净模式下运行eclipse? 如果我们这样做会发生什么?
  8. 数据结构 --- 堆
  9. mac 不能连接wi-fi_如何在Mac OS X中查看当前的Wi-Fi连接速度
  10. 霍普分叉matlab程序,基于MATLAB_GUI的Kalman滤波程序
  11. input组件android,React-Native TextInput组件详解及实例代码
  12. 德力西双电源自动转换开关说明书_聊聊双电源转换的那点事。
  13. python+selenium自动化driver.switch_to.frame用法
  14. 贴片电容COG、NPO、X7R、Y5V、X5R介质的区别
  15. 如何简单有效的同步油猴插件
  16. 芝麻信用分有哪些计算维度?关于大数据风控的87个问题
  17. struts2漏洞批量检查
  18. 如何查看.net core 最新版本的功能
  19. (16) 基于图卷积神经网络的轨道交通流量预测
  20. stata移动平均插值法mipolate命令

热门文章

  1. python如何读取tfrecord_TFRecord格式存储数据与队列读取实例
  2. Adams无法正常退出问题解决办法
  3. [附源码]Python计算机毕业设计Django健康医疗体检
  4. 任务计划清单便签,对时间进行项目化管理
  5. 监控ajax请求的时间,找出完成Ajax请求所需的时间
  6. 虚拟机centos7 配置网络不成功问题
  7. undo表空间误删后的恢复
  8. 打开计算机5037端口,adb 5037端口被占用
  9. 应急响应典型案例分析
  10. 第1讲 Android Camera性能分析 课程组织安排