关于JAVA集合类的源代码的一些记录(持续更新)
来源:互联网 发布:饿了么算法工程师 编辑:程序博客网 时间:2024/06/18 10:10
ArrayList ,LinkedList , HashSet ,HashMap , HashTable , LinkedHashMap , TreeMap , ConcurrentHashMap
ArrayList
存储结构 :
数组保存对应的数据
存储增长 :
理应添加当前大小 + 1/2当前长度,如果实际需要增长的长度更大,那就用实际增长的长度,否则用前面的理应长度
LinkedList
存储结构 :
节点存储 , next
存储增长 :
没有这种判断,一个个节点的顺序下去
HashSet
存储结构 :
依赖于HashMap
HashMap(Fail Fast Iterator)
基本:
HashMap可以保存null,保存在table为0的下标
遍历的时候,不能对,对应的迭代器操作(add,remove,update)
存储结构:
Entry数组保存,每个Entry都可以有next节点
存储增长:
在需要新增长度的时候,按照原来的长度的两倍增长
保存过程:
put进去的时候,会先indexFor 获取对应的index。
然后,通过这个下标,不断迭代next,获取对应的entry,如果两个key相等的话,就会覆盖。
然后,准备添加entry。如果对应index的数组有值并且当前的HashMap的长度(有值的Entry个数)大于一定的长度(HashMap设置的容量 * 比例因子(0.75))
那么就会将新的长度设成原来的长度的2倍,并且将原来的table的entry,都重新计算一次hash(包括next的也会重新计算),放到新的table内,
重新算一次现在这个新增的entry的hash,从而重新计算index。
最后新增entry,如果新的index还是有节点的话,当前新增节点作为next节点。否定,就是对应的index节点。
hash函数:
如果key是string,则用string的hashcode方法。否则,用他们自定义的hash方法
h = hashSeed
h ^= hashCode
然后,h ^= (h >>> 20) ^ (h>>>12)
最后 ,h ^ ( h >>> 7 ) ^ (h >>> 4)
上述的方法就是为了将这些hash值打算。
因为,这些hashCode是int,在值比较相近的时候,他们在低位有很多相同的地方,
为了将这个地方打散就用了上述方法打散低位的数值。
indexFor函数:
通过hash函数,拿到一个被打散的hash值(这样的hash值,在数值相邻的时候,hash值也大不一样)
然后将这个hash 与 table.length - 1 。 这里为什么不是hash % table.length 呢?
因为,hashMap的存储长度,初始长度是16,是按照2的倍数增长。所以,table.length - 1 对应的所有低位都是1。
最后,会发现 hash % table.length == hash & (table.length - 1)
HashTable(多线程强一致性)
与HashMap的实现都是一样,只是每个方法都是synchronized(调用这个方法的对象作为锁)
不可保存null
LinkedHashMap
重写了createEntry和addEntry等方法
在HashMap的基础上,额外新增了一个链表节点存储,保证插入有序
TreeMap
每次put的时候,都会做一次比较,比较后,再决定插入左边还是右边的节点
存储结构是红黑树,TreeMap保证值有序
ConcurrentHashMap(Fail Safe Iterator,多线程弱一致性)
基本 : 遍历的时候,可以对元素操作,因为遍历的时候,是对副本做操作。
存储 : 使用Segment保存,通过分段的方法,将大量的数据分到多个segment。
segment,内部再通过一些关键字(volatile),锁机制,去保存数据
比较 :相较于HashTable,ConcurrentHashMap,通过segment以及关键字,将锁的时间,减少了很多
因为 HashTable 迭代的时候,会比较久,占用的时间比较久。HashTable 在 量比较大的时候,会很慢。
弱一致性 : 无法保证,同时删除以及写入的时候,是否会出现写入的内容被删除。因为,clear是for循环将所有的segment,clear。并没有加锁。
Update At 2017-12-04 21:51:00
- 关于JAVA集合类的源代码的一些记录(持续更新)
- 关于FLEX的一些文章记录(持续更新中)
- JAVA的一些基础(持续更新)
- BUG记录之——关于AS的一些红buffer总结(持续更新中)
- 集合框架的一些问题(持续更新)
- 无聊时,看的一些关于java东西(持续更新)
- Java一些实用的类(持续更新)
- 图像形态学的一些开源库-记录(持续更新)
- 关于js的一些小结---持续更新
- 关于zend的一些常识(持续更新)
- 关于asterisk enum的一些资料(持续更新中)
- 关于链表的一些操作(持续更新中)
- 关于开发工具的一些快捷键收集(持续更新)
- 关于react性能优化的一些技巧(持续更新)
- Java内置集合类(持续更新)
- java 基础问题的一些处理,记录一下,持续更新呗
- 一些有用的技术网站记录--持续更新
- 一些小的代码功能,记录一下(持续更新)
- 自学Python之Python基础:(五)Python数据结构常用操作
- nginx 知识点列表
- 数据结构与算法基础
- pip常用命令
- UDP可靠性的增加之UNP22章读后感(一)
- 关于JAVA集合类的源代码的一些记录(持续更新)
- 深入Java集合学习系列:HashMap的实现原理
- 字符串数组与指针
- JAVA SkipList 跳表 的原理和使用例子
- CommonJS,AMD模块加载规范
- 关于MIPI协议(二)——利用Cypress的工具实例分析MIPI收发器时钟参数配置方法
- JavaScript 对象
- java连接数据库操作--第一个例子
- C++学习笔记--继承初识