HashMap和HashTable的简单比较
来源:互联网 发布:淘宝虚假交易处罚2016 编辑:程序博客网 时间:2024/05/22 08:04
(1)HashMap:线程不安全
l hashMap是基于哈希表实现的,其内部通过单链表来解决冲突,容量不足,超过阈值,会自动增长
l 两个重要参数:初始容量和加载因子
n 初始容量initialCapacity:哈希数组的长度,默认为16,如果初始容量较大,会使迭代器效率降低;
u 哈希表的容量要是2的整数次幂,好处:
l 位与,计算key=hash&(length-1),如果length为2的整数次幂,就相当于对length取摸,散列比较均匀,并且效率相对于除留取余法(hash值对length取摸)
l 若不是2的整数次幂,则length-1就是偶数,这样位与的时候得到的值,数组的下标就一定是偶数,这样就会造成空间的浪费,散列的不均匀(为了使不同的hash值发生碰撞的概率降低)
n 加载因子loadFactor:默认值是0.75,如果值过大,空间利用率高,但链表长度增长,存取效率降低
n 扩容机制:增加hash桶的数量,当size>initialCapacity*loadFactory,进行容量扩充,一般扩大一倍,但是当JVM内存用完了,或者这个HashMap的capacity达到2^30时,表示键值已经放满。
u Resize():从底层重新创建一个数组,长度为之前的两倍,重新计算数组的位置并进行复制处理,相当耗时
l Hash值=使用hash函数,对key的hashcode进行重新计算;索引值=hash值&(length-1)
l Key或者value可以为null,key只能有一个为null,但是value则可以有多个可以为null。key为null的,永远放在哈希表的第一个位置的链表中
l Jdk7和jdk8的区别:参考:https://my.oschina.net/hosee/blog/618953
a) 当同一个hash值的节点数不小于8时,将不再使用单链表的方式存储,而是改为“红黑树”方式存储。单链表的时间复杂度是O(N),红黑树是0(logN)
b) Jdk7采用的是Entry来存储节点信息,jdk8采用的是Node来存储,和红黑树的TreeNode关联
c) Put方法改变:
a) 先判断该位置上是否有元素
i. 没有的,直接封装成Node对象存放,
ii. 有的话,
1. 若key值相同,则直接覆盖
2. 若不相同,判断节点类型
a) 如果当前节点类型是TreeNode,则执行putTreeVal
b) 不是的话,就和jdk7相同,遍历链表
(2)HashTable :线程安全,使用synchronized关键字
l Key和value都不能为null
l 有初始容量和加载因子:初始容量为11,加载因子为0.75,容量不要求是2的整数次幂,扩容方式:old*2+1
l 计算索引值使用的是除留取余法,且hash值就是key的hashcode()
(4) HashTable和 HashMap的区别?
l 线程安全方面:hashTable线程安全
l Key和value值可不可以为空:hashMap可以为空
l 扩容方法不一致:hashTable=old*2+1,hashMap=old*2
l 通过Hash值散列到hash表中的算法不一样:hashTable是除留取余法,hashMap是位与
l 迭代器不一样。hashMap是fail-fast迭代器(Iterator),hashTable的迭代器(Enumerator)不是。Fail-fast迭代器,指的就是当在使用迭代器的时候,其他线程修改map的结构,则抛出ConcurrentModificationException异常
(5)为什么HashMap是线程不安全的?
l 多线程同时put的时候,两个线程put的key发生碰撞,hash值一样,则会覆盖掉一个线程的数据
l 多线程同时检测到元素的个数超过阈值,同时进行扩容,但是最终只会有一个线程的扩容后的数组会赋值给table,这样就会造成其他线程丢失,数据丢失,且引起死循环
(6) 使HashMap线程安全的方案?
l 使用hashTable,但是会造成方法阻塞,并且同时不能使用put和get方法,现在基本不用
l 使用Collections.synchronizeMap(hashMap)进行同步
l 直接使用ConcurrentHashMap
参考:https://zhuanlan.zhihu.com/p/24338517
- HashMap和HashTable的简单比较
- HashMap和HashTable的比较
- HashTable和HashMap的比较
- HashTable和HashMap的比较
- HashMap和Hashtable的比较
- Hashtable和HashMap的比较
- HashMap和Hashtable的比较
- HashTable和HashMap的比较
- HashMap和Hashtable的比较
- HashMap和 Hashtable的比较
- hashtable 和hashmap比较
- hashtable和hashmap比较
- 比较HashMap和HashTable
- Hashmap和Hashtable比较
- HashMap和Hashtable的比较,区别
- HashMap、Hashtable、HashSet 和 ConcurrentHashMap 的比较
- 比较学习HashMap和Hashtable
- HashMap、HashTable、HashSet分析比较以及TreeSet的简单介绍
- Gym
- Javascript--Array数组的splice()方法之删除、插入、替换
- 高德地图Marker与InfoWindow定位居中冲突问题
- CodeForces
- Laravel 引入没有命名空间的第三方类库
- HashMap和HashTable的简单比较
- C++之循环结构
- HDU_3791 二叉搜索树
- 《leetCode》:Remove Duplicates from Sorted Array
- 符号定义伪指令
- 设计模式-职责链模式
- iOS iPad开发~demo
- ubuntu python 安装使用的问题
- 用Huffman树实现文件压缩与解压