HashMap与HashTable

HashMap与Hashtable区别

1.(同分性)Hashtable是同步的,里面的方法都加了synchronized,所以是线程安全的,但是效率会很低,因为所有的线程进来都要排队。所以一般选用concurrentHashMap来实现线程安全,它是使用分段锁来实现的,不是全部锁住。

2.(继承的父类不同)hashtable是继承了Dictionary类,而hashMap是继承了AbstractMap类

3.(对null key 和null value支持不同)hashtable不允许null值(key和value都不行),hashmap允许null值(key和value都可以)。这样的key只有一个,而value可以多个。
从put()方法体现的:
在这里插入图片描述
key为null的话执行hashcode还是会报空指针异常。

hashmap的:
在这里插入图片描述
在这里插入图片描述
如果key == null,则直接定位为0

4.(初始化和扩容方式不同)(hashtable默认为11,默认加载因子:0.75),而hashmap默认为16 hashtable是在构造方法上初始化的,而hashmap是在进行第一次调用put()的时候再在resize()方法里才进行初始化。hashtable每次扩容为原来的2n+1倍,而hashmap是原来的2倍。

5.hash方法不同。
hashMap:
高16位向低16位右移,让高位和低位同时进行运算,为什么16位?因为是整型(32位),为的是让计算出的hash值分布均匀。避免只有低位相同的hash进行严重的碰撞。
在这里插入图片描述
hashtable:
直接进行hashcode
在这里插入图片描述
计算index不同:
hashtable:一开始就将符号位去掉,主要是取余操作:
在这里插入图片描述
hashmap:容量要为2的n次方,这跟与运算相关,保证算出来的index是在(0-n-1)的范围。
在这里插入图片描述
在这里插入图片描述

HashMap:

在这里插入图片描述
在这里插入图片描述

0.75:折中平衡,太高则减少空间的浪费,但是会增加查找的消耗,泊松概率

java7容易碰到死锁:

它的扩容是采用头插法造成死循环:

在这里插入图片描述
java7 hash表+链表
java8 hash表+红黑树

成树的阈值为8的原因:服从泊松分布,超过8的概率就很小了
java8的扩容是按顺序扩容的

在这里插入图片描述

两者都是List接口的实现类,即代表插入的元素是有序和可重复的!两者都不是线程安全的。

ArrayList

(底层主要是用动态数组来实现的,所以存储顺序是连续的,它的查找比较快,但是在插入和删除的时候,如果是在数组的中间添加(删除)数组则需要把其他的元素向后或者向左移动,主要是通过system.arraycopy()来实现数组的移动的,所以就比较耗时。但是如果直接在数组后面移动就直接在数组后面添加即可)

  1. 如果通过无参构造的话,初始数组容量为0,当真正对数组进行添加时,才真正分配容量,默认为10。
  2. 实现了Serializable接口,因此它支持序列化,能够通过序列化传输;
  3. 实现了RandomAccess接口,支持快速随机访问,实际上就是通过下标序号进行快速访问;
  4. 实现了Cloneable接口,能被克隆。
  5. 扩容升为原来的1.5倍,(10*1.5=15)每次扩容都是通过Arrays.copyOf(elementData, newCapacity) 这样的方式实现的。

LinkList

(底层采用了双向链表实现,它还实现了Deque接口,存储地址是不连续的,每个存储地址是通过指针来指向的,查找的时候需要遍历链表,所以比较慢,但插入和删除的时候不需要移动其他元素,所以就比较快,由于是双向链表,内部针对查找进行了优化,当查找的元素get(intdex)时会进行判断,当index < size()/2就从左往右查询,当index > size()/2时就从右往左查询,但还是很很慢,链表这边主要是通过for来遍历链表的)

  1. LinkList默认初始化为空。

HashMap

put()的过程(拉链法):桶位置是根据index=(n-1)&hash计算的
1.当Node数组没被初始化的时候,则初始化容量为16,并将threshold初始化为12.
2.如果key==null,则计算hash为0,直接定位在桶为0的位置上
3.根据index找到桶位置,如果桶位置没有元素,则直接new一个Node并插入,看hashmap中的元素是否超过阈值,超过则调用resize()进行2倍扩容,新建一个2倍大小的数组,将老的数组中元素复制到新的数组里,老的数组被GC。
4.如果有元素,则取出节点p,判断传入的值的key以及key所产生的hash和取出来的p的key以及hash值是否相等,相等则进行替换,不相等,则判断取出的p是否是红黑树,(如果不是,则直接插入到链表末尾,然后判断后面元素是否超过8个,如果超过8个且Node数组空间元素超过64个就将单链表转化成双向链表再转换成红黑树,如果没有超过8个,就调用resize()进行扩容),如果是则采用红黑树的插入。

红黑树特点:

  • 根结点一定是黑色
  • 红色结点下面如果有孩子的话,一定是两个黑色结点
  • 每次往红黑树里面插入元素的话,一定是红色
  • 结点到其叶子结点黑色结点的数量一定相同
  • 3
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值