HashMap
hashMap基于哈希表,底层结果由数组实现,添加到map里的元素以 key-value的形式存储在数组中,在数组中key-value已一个实体的形式存储, 也就是继承至map接口中的entry,下图是map源码enrty 既然hashMap是基于哈希表,就会出现一个问题,就是哈希值重复,专业术语叫哈希碰撞......在hashMap中,如果出现hash值重复的情况的话,就会为重复的hash值创建一个链表(hash值是通过key来计算的),让他们按照插入顺序排列在链表中,注意,如果hash值相同,插入的key相同,会覆盖原有valuehashMap允许存入null键,null值(null值只能有一个,存在数组的第一个位置)
hashMap没有顺序,而且还随着元素的插入而改变
hashMap随着元素的添加自动扩容(扩容是2的整数次幂,也就是2的n次方), 当数组长度大于临界值时,会触发扩容(临界值=加载因子*当前数组大小)
hashMap的加载因子是0.75, 是因为因子越大,发生哈希冲突的可能性越大,因子越小,元素越少,但是会浪费很多空间,所以通过官网计算0.75是两者均衡最佳数
hashMap里的key不能重复,重复key会覆盖
hashMap线程不安全
>>>>>>>>>>>>>>>>>>>>>>>>源码解析>>>>>>>>>>>>>>>>>>>>>>>>>>>
hashMap在第一次初始化时是一个空数组,在首次put方法中会创建一个默认16大小的数组
当length为2的N次方的话,一定为偶数,这样length-1则一定为奇数,而奇数转换成二进制的话,最后一位定为1(可以自己测试下),这样当我们的hash值 与 奇数 进行与运算时候,得到的结果即可能为奇数,也可能为偶数(取决于hash值),此时的散列性更好,出现哈希冲突的情况就比较低,也就是说HashMap中形成链表的可能性更低;
而当length为奇数时,length-1为偶数,转换成二进制的话最后一位是0。根据上面的与运算实现来看,当用0来进行运算时,得到的结果均为0,既无论hash值是多少,最终都只能是偶数。相比于上面来说,length是奇数相当于浪费掉Entry数组一半的空间,更容易出现哈希冲突,形成链表,进而影响整个HashMap的性能。
为什么说hashMap线程不安全
在jdk7中, 当两个线程同时进行操作时, 如果他们的hash值和 bucketIndex值相同, 第二个线程会覆盖第一个线程的值,而且jdk7还会发生死循环的情况,如果在内部遍历数组时没有为Null的元素,单项链表变成循环链表,就会一直死循环下去, jdk8优化了死循环的情况,但是线程问题依旧没有解决,如果两个线程的hash值相同,并且该位置数据是null, 在第一个线程还未进行数据插入时第二个线程插入数据,这时第一个线程会覆盖第二个线程的数据
为什么hashMap会进入死循环
在jdk1.8之前扩容会发生死循环, 假设有两个值, key1, key2 , 当有两个线程同时进行扩容操作时,当a线程进行到Entry<K,V> next = e.next时挂起, b线程进行操作扩容后完毕,这时值得顺序变为了key2, key1(因为赋值操作是从头部开始,重新赋值后会颠倒顺序), 这时a线程进行newTable赋值操作,e=key2, next=key1, 将key2放入a线程表后, e变成了key1, next=null,这时再次将key1放入a线程表中,就变成了a线程头结点是key1,b线程头结点是key2, 他们的next分别是key2和key1, 这时就形成了循环依赖, 进行get操作的时候就会发送死循环情况
在jdk1.8解决了通过扩容产生死循环的情况,jdk1.7在赋值时是从头结点开始, jdk8改成了尾结点,但是虽然说解决了因为扩容产生死循环的问题, 但是还是有其他死循环的情况的 (红黑树死循环!!!!!!)
如果根节点、爷爷节点、父节点、左叔叔节点、右叔叔节点、新插入的节点都是一个元素,证明当前循环的树只有一个值,并且永远不会退出,因为它满足两个判断条件
HashTable
hashTable是线程安全的, 是因为他的每一个方法都加上了 synchronized 锁,所以才说他是线程安全的, 每一个线程访问都会锁住整个哈希表,下一个线程必须等待该线程执行反比释放锁之后才可以, 这样的话线程是安全的, 但是效率属实是太低了
hashTable中key或者是value都不能是null
所以不推荐使用hashTable, 如果想要保证效率的同时又保证线程的安全,可以学习一下 ConcurrentHashMap,学习资料在并发包里
标签:key,hash,hashMap,线程,HashTable,哈希,死循环,HashMap From: https://blog.csdn.net/Small_white_528/article/details/142483094