当前位置: 首页 > news >正文

Java数据结构篇

Map体系

1.HashMap

  • 哈希冲突:开放定址法、再哈希法、链地址法
  • 插入元素先检查是否到达阈值,是则先数组扩容,然后再插入链表,链表长度超过8则转红黑树
  • 1.7之前由于扩容导致的头插法尾插法混合导致指针错误,出现死循环问题

2.TreeMap

基于红黑树,增加了排序功能,默认使用Java自带排序规则,没有则需要实现Comparable接口(大于等于小于分别返回1,0,-1)

🌟下面是并发安全容器,HashTable和ConcurrentHashMap基于HashMap,而ConcurrentSkipListMap基于TreeMap

3.HashTable

   在数据不断地写入和删除,且不存在数据量累积以及数据排序的场景下,我们可以选用Hashtable或ConcurrentHashMap。Hashtable使用Synchronized同步锁修饰了put、get、remove等方法,因此在高并发场景下,读写操作都会存在大量锁竞争,给系统带来性能开销。

4.ConcurrentHashMap

   相比Hashtable,ConcurrentHashMap在保证线程安全的基础上兼具了更好的并发性能。在JDK1.7中,ConcurrentHashMap就使用了分段锁Segment减小了锁粒度,最终优化了锁的并发操作。到了JDK1.8,ConcurrentHashMap做了大量的改动,摒弃了Segment的概念。由于Synchronized锁在Java6之后的性能已经得到了很大的提升,所以在JDK1.8中,Java重新启用了Synchronized同步锁,通过Synchronized实现HashEntry作为锁粒度。这种改动将数据结构变得更加简单了,操作也更加清晰流畅。

   与JDK1.7的put方法一样,JDK1.8在添加元素时,在没有哈希冲突的情况下,会使用CAS进行添加元素操作;如果有冲突,则通过Synchronized将链表锁定,再执行接下来的操作。因此按理说在性能上ConcurrentHashMap要好一些,通常为首选。但要注意一点,虽然ConcurrentHashMap的整体性能要优于Hashtable,但在某些场景中,ConcurrentHashMap依然不能代替Hashtable。例如,在强一致的场景中ConcurrentHashMap就不适用,原因是ConcurrentHashMap中的get、size等方法没有用到锁,ConcurrentHashMap是弱一致性的,因此有可能会导致某次读无法马上获取到写入的数据。

5.ConcurrentSkipListMap

   ConcurrentHashMap容器,该容器在数据量比较大的时候,链表会转换为红黑树。红黑树在并发情况下,删除和插入过程中有个平衡的过程,会牵涉到大量节点,因此竞争锁资源的代价相对比较高。而跳跃表的操作针对局部,需要锁住的节点少,在并发场景下的性能会更好一些,因此就实现了在非线程安全的Map容器中,用TreeMap容器来存取大数据;在线程安全的Map容器中,用SkipListMap容器来存取大数据。
在这里插入图片描述
在这里插入图片描述

List体系

1.LinkedList

  • 双向链表
  • 内部属性
    在这里插入图片描述

2.ArrayList

  • 实现接口List,Clonable,Serializable,RandomAccess(空接口,仅用于标识)
  • 从ArrayList属性来看,它没有被任何的多线程关键字修饰,但elementData被关键字transient修饰了。这就是我在上面提到的第一道测试题:transient关键字修饰该字段则表示该属性不会被序列化,但ArrayList其实是实现了序列化接口,这到底是怎么回事呢?

在这里插入图片描述  这还得从“ArrayList是基于数组实现“开始说起,由于ArrayList的数组是基于动态扩增的,所以并不是所有被分配的内存空间都存储了数据。  如果采用外部序列化法实现数组的序列化,会序列化整个数组。ArrayList为了避免这些没有存储数据的内存空间被序列化,内部提供了两个私有方法writeObject以及readObject来自我完成序列化与反序列化,从而在序列化与反序列化数组时节省了空间和时间。

  因此使用transient修饰数组,是防止对象数组被其他外部方法序列化。

  • 扩容策略,1.5倍+1,可以自行预估存储量指定初始容量,减少扩容次数,提高性能;
  • 插入和删除中间节点需要重排列位置,直接末尾操作则不需要;
  • 遍历过程中可以增加删除元素吗?可以使用iterator迭代器进行安全操作,hashmap同理;

3.vector

  Vector也是基于Synchronized同步锁实现的线程安全,Synchronized关键字几乎修饰了所有对外暴露的方法,所以在读远大于写的操作场景中,Vector将会发生大量锁竞争,从而给系统带来性能开销。

4.CopyOnWriteArrayList

相比之下,CopyOnWriteArrayList是java.util.concurrent包提供的方法,它实现了读操作无锁,写操作则通过操作底层数组的新副本来实现,是一种读写分离的并发策略。我们可以通过以下图示来了解下CopyOnWriteArrayList的具体实现原理。

在这里插入图片描述

回到案例中,我们知道黑名单是一个读远大于写的操作业务,我们可以固定在某一个业务比较空闲的时间点来更新名单。

这种场景对写入数据的实时获取并没有要求,因此我们只需要保证最终能获取到写入数组中的用户ID就可以了,而CopyOnWriteArrayList这种并发数组容器无疑是最适合这类场景的了。

Set体系

1.HashSet

HashSet的contains方法原理:主要就是一个查找过程,底层基于HashMap实现,就是查找哈希桶位,然后再遍历链表(红黑树)查找是否有目标元素。需要注意两点:

  • 重写equals()方法,判断相等的核心依据;
  • 重写hashcode()方法,确保哈希性能;

2.TreeSet

同TreeMap,可自定义排序,红黑树,插入值非空(1.8之后)

二叉树

BST、AVL、红黑树、B树、B+树

经典数据结构问题

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • arm-Pwn环境搭建+简单题目
  • hostnamectrl到底是什么命令?
  • 还在烦恼Cosplay论坛开发?探索PHP+Vue的完美解决方案!
  • JVM类加载机制—类加载器和双亲委派机制详解
  • Mybatis框架常见问题总结
  • 计算机毕业设计Spark+Tensorflow股票推荐系统 股票预测系统 股票可视化 股票数据分析 量化交易系统 股票爬虫 股票K线图 大数据毕业设计 AI
  • 基于YOLOv8的无人机高空红外(HIT-UAV)检测算法,新的混合型扩张型残差注意力(HDRAB)助力涨点(二)
  • 小琳AI课堂:AIGC
  • 香蕉梨:自然的甜蜜宝藏
  • C\C++ Sqlite3使用详解
  • 云计算实训34——docker环境配置、镜像基本操作、容器基本操作、设置远程连接管理
  • wpf DynamicResource的ResourceKey值进行绑定
  • vue2版本空目录下创建新项目的方法2024
  • RocketMQ~刷盘机制、主从复制方式、存储机制
  • Nginx - 反向代理、缓存详解
  • 2017前端实习生面试总结
  • C++回声服务器_9-epoll边缘触发模式版本服务器
  • Docker下部署自己的LNMP工作环境
  • flask接收请求并推入栈
  • Java新版本的开发已正式进入轨道,版本号18.3
  • JSONP原理
  • LeetCode18.四数之和 JavaScript
  • mongo索引构建
  • SegmentFault 2015 Top Rank
  • Spring-boot 启动时碰到的错误
  • Vue.js源码(2):初探List Rendering
  • 算法-插入排序
  • 小程序开发中的那些坑
  • 原创:新手布局福音!微信小程序使用flex的一些基础样式属性(一)
  • 在weex里面使用chart图表
  • JavaScript 新语法详解:Class 的私有属性与私有方法 ...
  • Nginx实现动静分离
  • ​七周四次课(5月9日)iptables filter表案例、iptables nat表应用
  • ###51单片机学习(2)-----如何通过C语言运用延时函数设计LED流水灯
  • #QT(智能家居界面-界面切换)
  • #基础#使用Jupyter进行Notebook的转换 .ipynb文件导出为.md文件
  • #中的引用型是什么意识_Java中四种引用有什么区别以及应用场景
  • (06)金属布线——为半导体注入生命的连接
  • (12)Hive调优——count distinct去重优化
  • (vue)el-cascader级联选择器按勾选的顺序传值,摆脱层级约束
  • (第27天)Oracle 数据泵转换分区表
  • (第一天)包装对象、作用域、创建对象
  • (二)原生js案例之数码时钟计时
  • (二刷)代码随想录第15天|层序遍历 226.翻转二叉树 101.对称二叉树2
  • (分享)一个图片添加水印的小demo的页面,可自定义样式
  • (强烈推荐)移动端音视频从零到上手(下)
  • (四十一)大数据实战——spark的yarn模式生产环境部署
  • (转)jQuery 基础
  • (轉貼) UML中文FAQ (OO) (UML)
  • .net core 的缓存方案
  • .Net Web窗口页属性
  • .NET/C# 在代码中测量代码执行耗时的建议(比较系统性能计数器和系统时间)...
  • .net实现客户区延伸至至非客户区
  • .NET之C#编程:懒汉模式的终结,单例模式的正确打开方式
  • .NET中的Exception处理(C#)