HashMap总结

1.定义

基于哈希表Map接口实现类
继承了AbstractMap抽象类
实现了Map接口:拥有一组Map通用的操作
实现了Cloneable接口:可进行拷贝:HashMap实现的是浅层拷贝(即拷贝对象的改变会影响被拷贝的对象)
实现了Serializable接口:表示可实现序列化,可将HashMap对象保存至本地,之后可恢复状态

特点:允许键/值 为空对象(null)
    非线程安全:可通过Collections类的静态方法synchronizedMap获得线程安全的HashMap
        Map map=Collections.synchronizedMap(new HashMap());
    不保证有序(如插入顺序)、也不保证不随时间变化

2.数据结构

HashMap采用的数据结构=数组+单链表  (JDK1.7)JDK1.8是数组+单链表+红黑树。 该数据结构也称拉链法
数组:
    核心底层=1个数组(table[])(又称哈希数组)
    数组下标=经过处理的键key的hash值
    数组元素=1个键值对=Entry<K,V>=1个链表(头结点)
    数组大小=HashMap的容量(capacity)
单链表:
    每个链表=哈希表的桶
    链表的节点值=1个键值对
    链表长度=桶的大小
备注:链表主要用于解决hash冲突:若不同key值计算出来的hash值相同(即都需存储到数组的同1个位置),
    由于之前该hash值得数组位置已存放好元素,将原先位置的元素移到单链表中,冲突hash值对应的键值对放入到数组元素中
    该采用链表解决hash冲突的方法=链地址法
注:HashMap的键值对数量=数组的键值对+所有单链表的键值对

3.主要API(方法、函数)

V get(Object key); // 获得指定键的值
V put(K key, V value);  // 添加键值对
void putAll(Map<? extends K, ? extends V> m);  // 将指定Map中的键值对 复制到 此Map中
V remove(Object key);  // 删除该键值对

boolean containsKey(Object key); // 判断是否存在该键的键值对;是 则返回true
boolean containsValue(Object value);  // 判断是否存在该值的键值对;是 则返回true
 
Set<K> keySet();  // 单独抽取key序列,将所有key生成一个Set
Collection<V> values();  // 单独value序列,将所有value生成一个Collection

void clear(); // 清除哈希表中的所有键值对
int size();  // 返回哈希表中所有 键值对的数量 = 数组中的键值对 + 链表中的键值对
boolean isEmpty(); // 判断HashMap是否为空;size == 0时 表示为 空


4.源码分析(put() 、get()、 resize()操作等)见链接

HashMapJDK1.7源码分析

HashMapJDK1.8源码分析

5.主要应用场景

统计数据

HashMap和HashTable的异同点:

相同点:
1.继承:都是实现Map接口,可克隆,可序列化
2.迭代器:都可以使用Iterator迭代器
3.存储结构:都使用哈希表
4.重复性问题:key都不能重复,value值是都可以

不同点:

1.继承的父类不同
hashtable继承自Dictionary,而HashMap继承自AbstractMap类,但二者都实现了Map接口

2.线程安全性不同
hashtable线程是安全的,因为它每个方法中都加入了Synchronize
HashMap线程是不安全的,因为:
    HashMap底层是一个Entry数组,当发生hash冲突时,HashMap采用链表的方式解决冲突,
    在对应的数组位置存放链表的头结点,对链表而言,新加入的节点会从头结点加入

3.是否提供contains方法

HashMap把hashtable的contains方法去掉了,改成containsValue和containsKey方法,因为contains方法容易让人误解,
hashtable则保留contains,containsValue和containsKey三个方法,其中contains和containsValue功能相同

4.key值和value是否允许null值
其中key和value都是对象,并且不能包含重复key,但可以包含重复的value

hashtable中,key和value都不允许出现null值,但是HashMap中key和value可以为空,但key空值只能有一个
value可以重复

5.两个遍历方式的内部实现
hashtable、HashMap都使用了Iterator,HashTable还使用了枚举方式

6.hash函数:

哈希函数不同(都和key有关)

7.初始默认值
hashtable在不指定容量的情况下的默认容量为11,而HashMap为16,hashtable不要求底层数组的容量一定为2的整数次幂,而HashMap则要求一定为2的整数次幂。

8.扩容机制
hashtable扩容时,将容量变为原来的2倍加1:2*table.length+1
而HashMap扩容时,将容量变为原来的2倍:2*table.length
9.效率不同
单线程下hashMap效率比HashTable效率高


思考?为什么有了HashTable还要出现hashMap?
一般情况下集合类用在单线程下
HashTable效率较低

 

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值