动图+源码,演示Java中常用数据结构执行过程及原理
最近在整理数据结构方面的知识, 系统化看了下Java中常用数据结构, 突发奇想用动画来绘制数据流转过程.
主要基于jdk8, 可能会有些特性与jdk7之前不相同, 例如LinkedList LinkedHashMap中的双向列表不再是回环的.
HashMap中的单链表是尾插, 而不是头插入等等, 后文不再赘叙这些差异, 本文目录结构如下:
LinkedList
经典的双链表结构, 适用于乱序插入, 删除. 指定序列操作则性能不如ArrayList, 这也是其数据结构决定的.
add(E) / addLast(E)
add(index, E)
这边有个小的优化, 他会先判断index是靠近队头还是队尾, 来确定从哪个方向遍历链入.
靠队尾
get(index)
也是会先判断index, 不过性能依然不好, 这也是为什么不推荐用for(int i = 0; i < lengh; i++)的方式遍历linkedlist, 而是使用iterator的方式遍历.
remove(E)
ArrayList
底层就是一个数组, 因此按序查找快, 乱序插入, 删除因为涉及到后面元素移位所以性能慢.
add(index, E)
扩容
一般默认容量是10, 扩容后, 会length*1.5.
remove(E)
循环遍历数组, 判断E是否equals当前元素, 删除性能不如LinkedList.
Stack
经典的数据结构, 底层也是数组, 继承自Vector, 先进后出FILO, 默认new Stack()容量为10, 超出自动扩容.
push(E)
pop()
后缀表达式
Stack的一个典型应用就是计算表达式如 9 + (3 - 1) * 3 + 10 / 2, 计算机将中缀表达式转为后缀表达式, 再对后缀表达式进行计算.
中缀转后缀
- 数字直接输出
- 栈为空时,遇到运算符,直接入栈
- 遇到左括号, 将其入栈
- 遇到右括号, 执行出栈操作,并将出栈的元素输出,直到弹出栈的是左括号,左括号不输出。
- 遇到运算符(加减乘除):弹出所有优先级大于或者等于该运算符的栈顶元素,然后将该运算符入栈
- 最终将栈中的元素依次出栈,输出。
计算后缀表达
- 遇到数字时,将数字压入堆栈
- 遇到运算符时,弹出栈顶的两个数,用运算符对它们做相应的计算, 并将结果入栈
- 重复上述过程直到表达式最右端
- 运算得出的值即为表达式的结果
队列
与Stack的区别在于, Stack的删除与添加都在队尾进行, 而Queue删除在队头, 添加在队尾.
ArrayBlockingQueue
生产消费者中常用的阻塞有界队列, FIFO.
put(E)
put(E) 队列满了
take()
当元素被取出后, 并没有对数组后面的元素位移, 而是更新takeIndex来指向下一个元素.
takeIndex是一个环形的增长, 当移动到队列尾部时, 会指向0, 再次循环.
HashMap
最常用的哈希表, 面试的童鞋必备知识了, 内部通过数组 + 单链表的方式实现. jdk8中引入了红黑树对长度 > 8的链表进行优化, 我们另外篇幅再讲.
put(K, V)
put(K, V) 相同hash值
resize 动态扩容
当map中元素超出设定的阈值后, 会进行resize (length * 2)操作, 扩容过程中对元素一通操作, 并放置到新的位置.
具体操作如下:
- 在jdk7中对所有元素直接rehash, 并放到新的位置.
- 在jdk8中判断元素原hash值新增的bit位是0还是1, 0则索引不变, 1则索引变成"原索引 + oldTable.length".
LinkedHashMap
继承自HashMap, 底层额外维护了一个双向链表来维持数据有序. 可以通过设置accessOrder来实现FIFO(插入有序)或者LRU(访问有序)缓存.
put(K, V)
get(K)
accessOrder为false的时候, 直接返回元素就行了, 不需要调整位置.
accessOrder为true的时候, 需要将最近访问的元素, 放置到队尾.
removeEldestEntry 删除最老的元素
动图+源码,演示Java中常用数据结构执行过程及原理的更多相关文章
- 动图+源码,演示 Java 中常用数据结构执行过程及原理
阅读本文大概需要 3.7 分钟. 作者:大道方圆 cnblogs.com/xdecode/p/9321848.html 最近在整理数据结构方面的知识, 系统化看了下Java中常用数据结构, 突发奇想 ...
- Spring AOP 源码分析 - 拦截器链的执行过程
1.简介 本篇文章是 AOP 源码分析系列文章的最后一篇文章,在前面的两篇文章中,我分别介绍了 Spring AOP 是如何为目标 bean 筛选合适的通知器,以及如何创建代理对象的过程.现在我们的得 ...
- 从源码浅析Java中的Lock和AbstractQueuedSynchronizer
在之前的文章中我也曾经介绍过Lock,像ReentrantLock(可重入锁)和ReentrantReadWriteLock(可重入读写锁),这些所我们在说的时候并没有详细的说明它们的原理,仅仅说明了 ...
- 从源码看java中Integer的缓存问题
在开始详细的说明问题之前,我们先看一段代码 public static void compare1(){ Integer i1 = 127, i2 = 127, i3 = 128, i4 = 128; ...
- Mybatis3源码笔记(六)SqlSession执行过程
前几篇大致分析了初始化的过程,今天打算走一个SqlSession具体执行过程. @Test void shouldSelectAllAuthors() { try (SqlSession sessio ...
- python源码探秘:用户函数的执行过程
脚本函数编译后如何执行?脚本编译后是pyc码,pycodeobject对象的串行化.import时是对pyc文件反系列化.函数编译后会生成函数对象,函数对象的TP_call对应的是function_c ...
- java中for循环执行过程
for (int j = 0; j < newSize; j++) { //执行todo } 1.首先变量j初始化为0 2.然后j=0的值跟newSize进行比较,假如为true,则执行{}里面 ...
- Spring IOC 容器源码分析 - 创建单例 bean 的过程
1. 简介 在上一篇文章中,我比较详细的分析了获取 bean 的方法,也就是getBean(String)的实现逻辑.对于已实例化好的单例 bean,getBean(String) 方法并不会再一次去 ...
- Java中的数据结构有哪些?HashMap的工作原理是什么?
Java中常用数据结构 常用的数据结构有哈希表,线性表,链表,java.util包中有三个重要的接口:List,Set,Map常用来实现基本的数据结构 HashMap的工作原理 HashMap基于ha ...
随机推荐
- 【bfs】密码锁-C++
Description 现在一个紧急的任务是打开一个密码锁.密码由四位数字组成,每个数字从 1 到 9 进行编号.每次可以对任何数字加 1 或减 1.当将9加 1 时,数字将变为1,当1减 1 的时, ...
- ASP.NET 前端数据绑定---<%#%>及Eval()的使用
ASP.NET 前端html代码中会经常出现的<%%>的代码,里面的文本其实就是不能直接输出到客户端浏览器的文本,是需要服务器解释的. 在ASP中,<%%>里面的文本是vbsc ...
- 根据数据库帮助类采用事务插入图片到sql server数据库中
我们定义数据库为image类型,然后读取图片为字符流,再保存到数据库中,首先我们定义一个读取图片的公共类,此公共类以后会用到,所以可以建立相应的帮助类 public static byte[] Rea ...
- [opengl] 画一个可移动的自行车 二维几何变换(平移、旋转、缩放)
#include <cmath> #include "glut.h" #include "iostream" using namespace std ...
- Java秒杀系统实战系列~整体业务流程介绍与数据库设计
摘要: 本篇博文是“Java秒杀系统实战系列文章”的第三篇,本篇博文将主要介绍秒杀系统的整体业务流程,并根据相应的业务流程进行数据库设计,最终采用Mybatis逆向工程生成相应的实体类Entity.操 ...
- git取消链接并删除本地库
有的时候我们需要删除从GitHub上克隆下来的库 从github上clone一个仓库: git clone git@github.com:USERNAME/repo.git 在本地目录下关联远程rep ...
- JSP使用分层实现业务处理
在Java开发中,使用JDBC操作数据库的四个步骤如下: ①加载数据库驱动程序(Class.forName("数据库驱动类");) ②连接数据库(Connection co ...
- web设计_7_页面缺失图片或CSS的情况下仍然易读
1. 在任何可能使用背景图片的地方应设置同样的颜色的背景色. 防止图片不能加载的情况下,页面内容同样保持较好可读性. 例如文字为白色,背景图为深色,如果不设置背景色,当背景图未成功加载, 而浏览器多数 ...
- 【Python3爬虫】当爬虫碰到表单提交,有点意思
一.写在前面 我写爬虫已经写了一段时间了,对于那些使用GET请求或者POST请求的网页,爬取的时候都还算得心应手.不过最近遇到了一个有趣的网站,虽然爬取的难度不大,不过因为表单提交的存在,所以一开始还 ...
- 创建软RAID5
一 创建4块硬盘组软 RAID5 新增四块20G的新硬盘,将四块硬盘分别分区,全部大小都分为一个区,并改 id 为 “ fd ” 1创建阵列mdadm -Cv /dev/md5 - ...