HashMap, HashTable, ConcurrentHashMap,在攀比中学习他们

HashMap和HashTable异同

1. 相同点:

  1. 基于哈希表实现,内部维护了一个存储数据的Entry数组,每一个元素都是key-value对,元素内部通过单链表解决冲突问题。
  2. Entry数组容量不够时,会进行resize扩容,size为底层数组已用槽的数量,threshold=容量*加载因子(默认是0.75)是阈值。当size大于threshold的时候会进行扩容。新建一个底层数组,然后把原来数组的全部元素重新添加到新的数组中,需要重新计算位置。
  3. 实现了Serializable接口,可以序列化;实现了Cloneable接口,能够被克隆
  4. 都含有containsKey和containerValue方法
  5. 都实现了Map接口

2.不同点:

  1. 继承父类不同,HashMap是继承AbstractMap类的,Hashtable继承Dictionary类(已废弃)
  2. Hashmap没有container方法,Hashtable是有的
  3. HashMap允许key和value都是null,Hashtable是不可以的
  4. 计算hash值的方式不同:
    HashMap:(h == key.hashcode())^(h >>> 16)
    Hashtable:key.hashcode()
  5. 扩容的机制不同:
    HashMap:默认容量是16,每次扩容都是原数组容量的2倍
    Hashtable:默认容量是11,每次扩容都是原数组的2倍+1
  6. 计算索引位置不同:
    HashMap:
int hash = hash(key)
int index = indexFor(hash, length)
int hash(object x){
	int h = x.hashcode();
	h += ~(h << 9);
	h ^= (h >>> 14);
	h += (h << 4);
	h ^= (h >>> 10);
	return h;
}
int indexFor(int h, int length){
	return h&(length - 1);
}

Hashtable:

int index = (key.hashcode() & 0x7FFFFFFF) % length
  1. Hashmap是线程不安全的,Hashtable是线程安全的,Hashtable中大多数方法是synchronized

ConcurrentHashMap的诞生

由segment数组和HashEntry数组组成的,segment是一种可重入锁reantrantLock。

  1. 初始化:输入参数initialCapacity是初始化容量,默认16,loadFactor是每个segment的负载因子,默认0.75
  2. get操作:先哈希,使用该值通过哈希运算定位到segment,再通过哈希算法定位到元素。
    注意:get操作不加锁。get方法里将要使用的共享变量都定义成volatile,如统计当前segment大小的count字段和用于存储值的HashEntry的value值。 定义成了volatile,线程之间保持可见性,被多线程同时读。
  3. put操作:操作共享变量时必须加锁,先定位到segment,再在segment里进行插入操作。
    插入:1. 判断是否需要对segment里的HashEntry数组进行扩容:插入前先判断是否超过threshold,如超过则进行扩容。与HashMap有所不同,Hashmap是插入后判断是否达到threshold,如果达到了进行一次扩容,带来的问题是有可能是扩容之后再也没有新元素插入,本次扩容就是无效的。 2. 定位位置并插入。
  4. size操作:先尝试2次通过不锁住segment方式来统计segment大小,如果容器的count发生了变化,再采用加锁的方式来统计所有segment大小。那么如何判断统计的时候容器是否变化呢:使用modCount变量,在put,remove和clean等操作元素前会将变量modeCount+1,在统计size的前后比较modCount是否发生了变化。
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值