java中Map集合关键点
Map接口
1. 特点
无序且唯一
2. 常用方法
增加:put(k,v)
删除:clear(); remove()
判断:containsKey(k); isEmpty(); containsValue(); equals(o);
查看:entrySet()(k,v); get(k); keySet(); values(); size()
3.TreeMap实现类
3.1特点
唯一且有序
3.2 原理
二叉树的中序遍历;
放入集合key的类一定要实现比较器。
4.HashMap实现类
4.1特点
无序且唯一
按照key 为依据,底层key遵照哈希表结构
放入集合数据的类,必须重写hashCode方法和equals方法
4.2 面试题
HashMap,Hashtable, LinkedHashMap 之间的区别?
答:HashMap 效率高,不安全,key可null,同样唯一
Hashtable 效率低,安全,key不可null
LinkedHashMap 唯一,有序(哈希表+中链表)
4.3 实现原理
哈希数组初始长度为16;类型为Entry类型; 负载因子为0.75;
当发生Hash碰撞时,jdk7 采用头插法,jdk8采用尾插法;
jdk1.8后,当HashMap链表长度超过8时,改用红黑树存储。
4.4put方法
-
put方法在计算HashCode时,还要进行二次散列。
-
发生哈希碰撞时,先比较哈希值;
-
比较key是否为一个对象,若是,就不比较equals方法;
若不是则比较equals方法;
-
若哈希值一样,equals方法结果也一样,则将新的value值替换旧的value值,并返回旧value值;
if (e.hash == hash && ((k=e.key)==key || key.equals(k))){
//获取老value值
V oldValue = value;
//新value替换老value,但是key值不变
e.value = value;
e.recordAccess(this);
return oldValue;
}
- 若当前数组长度不够,扩容长度为之前的2倍;并将之前的数据放入新数组
4.5 经典面试题
- 为什么负载因子为0.75?
答:若负载因子较小,空间利用率太低;
若负载因子较大,数组元素容易发生碰撞并产生链表,会导致查询效率低下;
所以对时间和空间取舍中平衡;
- 主数组的长度为什么一定是2^n ?
答:1.只有当长度为2的整数倍时,与运算操作和除以2取余等效;
2.防止哈希冲突和位置冲突。