IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> java集合类总结 -> 正文阅读

[数据结构与算法]java集合类总结

HashMap

HashMap中的属性:

1.capacity:容量,Node数组的大小(桶的数量),值为2的N次幂
2.threshold:扩容阈值,等于capacity * load factor 当size大于此值时进行扩容
3.loadFactor:负载因子,默认为0.75f
4.size属性是指map中的键值对个数
5.initialCapacity hashMap初始化时设置的容量大小(Node数组的长度),initialCapacity = (需要存储的元素个数 / 负载因子) + 1,如果可以确定要存储的键值对个数可以通过该公式计算出
容量,然后threshold如果暂时无法确定初始值大小,请设置为16(即默认值)。如果,需要放置1024个元素,由于没有设置容量初始大小,
随着元素的不断增加,容量7次被迫扩大,resize需要重建hash,严重影响性能。
官方的建议是initailCapacity设置成2的n次幂;。

HashMap常见问题:

阿里巴巴开发规范中,推荐用户在初始化HashMap时,应指定集合初始值大小。
一、原因
当我们new一个HashMap没有对其容量进行初始化的时候,系统会默认创建一个16大小的集合。当我们使用的集合太小时,就会造成内存的浪费,而当HashMap的容量超过临界值时,HashMap就会扩容到下一个2的指数幂(2->4,4->8,8->16)。扩容(resize)时,HashMap会重新建立hash表,重新计算没个元素的位置,这是很消耗资源的。
二、合理的设置
当我们使用HashMap(int initialCapacity)来初始化容量的时候,jdk会默认帮我们计算出一个相对合理的值当做初始容量。当HashMap的容量值超过了临界值(threshold)时就会扩容,
threshold = HashMap的容量值0.75,比如初始化容量为8的HashMap当大小达到80.75=6时将会扩容到16。当我们设置HashMap的初始化容量是遵循expectedSize(预期大小)/0.75+1,比如expectedSize是6时 6/0.75+1=9,此时jdk处理后会被设置成16,大大降低了HashMap被扩容的几率。
当我们通过HashMap(int initialCapacity)设置初始容量时,HashMap不一定会采取我们设置的初始容量,会根据计算得到一个新的值(2的指数幂),以保证hash的效率。
PS.为什么容量一定要是2的指数幂?
简答:1.节约空间 2.让元素分布均匀,put和get获取map数组小标方式 h & (length-1),h:为插入元素的hashCode,length:为map长度;&:与操作,如果length为2的次幂 则length-1
转化为二进制必定是11111……的形式,再与h的二进制与操作效率会非常的快,而且空间不浪费;
如果length不是2的次幂,比如length为15,则length-1为14,对应的二进制为1110,再与h与操作,最后一位都为0,而0001,0011,0101,1001,1011,0111,1101这几个位置永远都不能存放元素了,空间浪费相当大,更糟的是这种情况中,数组可以使用的位置比数组长度小了很多,这意味着进一步增加了碰撞的几率,
减慢了查询的效率!这样就会造成空间的浪费。

ArrayList

初始时构造可以设置(initialCapacity参数)集合的大小,来避免多次的扩容浪费性能。
由数组组成,新增的时候如果空间不够 1.5倍数进行扩容,原数组数据通过Arrays.copyWrite到新的数组中
遍历的时候不能做修改操作,否则会抛异常,遍历的时候会记录当前的modCount,以为做修改操作会改变modCount值,比较发现改变抛出异常!

CopyOnWriteArrayList

CopyOnWrite容器即写时复制的容器。通俗的理解是当我们往一个容器添加元素的时候,不直接往当前容器添加,
而是先将当前容器进行Copy,复制出一个新的容器,然后新的容器里添加元素,添加完元素之后,
再将原容器的引用指向新的容器。这样做的好处是我们可以对CopyOnWrite容器进行并发的读,而不需要加锁,因为当前容器不会添加任何元素。
所以CopyOnWrite容器也是一种读写分离的思想,读和写不同的容器。

当每次添加一个元素时才动态扩展数组大小为1.每次扩展为size()+1; 这里不管数组大小是否足够,每次都会新建一个数组,大小为原数组+1。
注意到没,每次添加元素时都会复制原数组,在原数组上+1,进行添加元素。
在添加的时候加锁,但是读取元素时读取的还是老数组,所以读不用加锁,不影响读的问题。但是缺点也很明显,就是在某一个时刻内存中会多了一个数组,随着list的数组量多时,在添加一个元素时,内存会一倍的被占用。

数据一致性问题。CopyOnWrite容器只能保证数据的最终一致性,不能保证数据的实时一致性。所以如果你希望写入的的数据,马上能读到,请不要使用CopyOnWrite容器。
读的时候不需要加锁,因为读取到时候读的是array数组。如果这个时候有数据添加或者删除,操作的都是新数组,并不会影响到我们读。

Set和List的重要区别:不重复

HashSet 基于HashMap实现、非线程安全,初始化时初始化一个hashMap,存储key是传入的value,value是object
CopyOnWriteArraySet 基于CopyOnWriteArrayList 线程安全
ConcurrentSkipListSet 基于ConcurrentSkipListMap 线程安全,有序,查询快

  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2022-02-16 13:22:22  更:2022-02-16 13:24:21 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 17:24:33-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码