Java HashMap解读

Java HashMap解读

Hash表介绍

Hash函数本质是建立一个值-索引的映射关系,通过这个映射关系来节约遍历列表的时间,是一种权衡了时间和空间消耗的算法,当出现Hash冲突后,可以采用链地址,哈希再散列等方法来解决

Java中计算HashCode

Java中自带的hashCode方法是一个Native方法,具体实现在C代码中,主要通过将对象的地址位移来制造随机数,进而作为对象的哈希值

但是对于不同的类来说,hashCode的方法又有所不同,这是因为相同值需要相同的hashcode,但是传统的hashcode是以地址为凭证的,所以重写了equal的方法的类,那么他的hashcode也同样需要重写,因此对于String,Integer等类来说,各自hashcode方法都各不相同

HashMap
主要变量介绍

变量名 介绍 默认值
DEFAULT_INITIAL_CAPACITY 默认初始大小 16
MAXIMUM_CAPACITY 最大大小 1<<31
DEFAULT_LOAD_FACTOR 负载因子 0.75

初始化
初始大小为2的倍数,例如用户指定大小为24,那边系统就会创建一个大小为32的HashMap,负责大小的阈值为32*0.75=24,也就是当数据超过24时,HashMap便会执行一次扩容操作

put操作
首先对key的哈希值进行二次哈希,然后&(length-1),二次哈希是为了解决两个哈希值低位相同时,碰撞的问题,让数据散布地更加分散,然后再把数据插入到其哈希对对应的数据位置中去,如果此处已有值,那么比较key是否相同,如果key相同,那么新的value替换旧的value,值得一提的是,当key为null时,则插入到数据的头部[0],如果key不同,则插入到链表的头部,在JAVA8中,当链表的长度大于8时,将会采用红黑树来代替链表

get操作
get按找二次哈希的值去对应的索引查找,注意HashMap是非线程安全的,因此扩容时,并发有可能造成循环链表,那么此时get就会进入死循环

扩容resize操作
当大小超过阈值时,整个对象容量会扩容1倍,同时重新计算每个key的hash值,并重新排列在数组中

你可能感兴趣的:(Java多线程,杂谈)