HashMap以及Android中特有数据结构分析(未完成)

281 阅读2分钟

要探究的问题

  • 1.HashMap的实现原理
  • 2.拉链法导致的链表过深问题为什么不用二叉查找树代替,而选择红黑树?为什么不一直使用红黑树?
  • 3.HashMap 的 table 的容量如何确定?loadFactor 是什么? 该容量如何变化?这种变化会带来什么问题?
  • 4.为什么HashMap是线程不安全的以及如何规避
  • SpareArray和ArrayMap

hash知识储备

存储key的地址和key之间需要建立映射关系,这个映射关系就是hash算法,也叫散列函数。通常情况下key1不等于key2,但会存在f(key1)=f(key2)的情况,这就是hash碰撞或者就hash冲突,解决方法有两种,开放寻址法和拉链法

开放寻址法

不断需要没有被占用的内存地址,存放key,这种方法需要的空间比较大

拉链法

key的内存地址不变,利用链表,不断插入后续的key,比较巧妙

HashMap

HashMap的数据结构通是数组、链表和红黑树,主要从三个方面put方法resize多线程不安全

put方法

先以Node<K,V>为元素存到数组里,数组的索引通过key的hash来计算,如果发生hash碰撞,则以链地址法链接到相应的链表里,如果阈值超过8,则转为红黑树

resize

超过最大容量,则触发扩容

扩容过程

  • 遍历旧数组的元素,添加到新数组中,新数组length是旧数组的两倍

线程不安全

会发生无限循环,多线程并发操作应该使用ConcurrentHashMap,因为HashMap的结果输出是无序的,可以使用LinkedHashMap

参考