Map接口
无序,唯一
HashMap
特点:无序。唯一,
特点是按照key进行总结的,因为底层key寻找哈希表的结构(数组+链表)
哈希表原理:如放入这个集合数据的对应的类,必须重写HashCode和equals这两个方法,否则结果就不符合唯一,无序的特点
添加:put(K key, V value), putAll(Map<? extends K,? extends V> m)
修改:
删除:clear(),remove(Object key)
查看:entrySet(), keySet(),size(),values()
判断: containsKey(Object key), containsValue(Object value), equals(Object o), get(Object key),isEmpty()
public static void main(String[] args) { /* * 添加:put(K key, V value), putAll(Map<? extends K,? extends V> m) * 修改: * 删除:clear(),remove(Object key) * 查看:entrySet(), keySet(),size(),values() * 判断: containsKey(Object key), containsValue(Object value), equals(Object o), get(Object key),isEmpty() * */ // 思考为什么键值对,键的值是一样的,但是value缺是第一个的值 HashMap<String,Integer> map = new HashMap<>(); map.put("lili",123123); System.out.println(map.put("nana", 12345)); map.put("feifei",34567); System.out.println(map.put("nana", 123123)); // 清空方法 // map.clear(); // map.remove("feifei");按照key移除 System.out.println(map.size()); System.out.println(map); System.out.println(map.containsKey("lili")); System.out.println(map.containsValue(123123)); HashMap<String,Integer> map2 = new HashMap<>(); map.put("lili",123123); System.out.println(map.put("nana", 12345)); map.put("feifei",34567); System.out.println(map.put("nana", 123123)); System.out.println(map==map2); System.out.println(map.equals(map2));//底层重写了equals比较集合中的值是否一致 System.out.println("判断是否为空"+map.isEmpty()); System.out.println(map.get("nana")); System.out.println(map.keySet());//查看集合中所有的k System.out.println(map.values());//查看集合中所有的v //通过k来遍历出v Set<String> set = map.keySet(); for (String s : set) { System.out.print(map.get(s)+" "); } System.out.println(); //entrySet 得到的是一对数据 Set<Map.Entry<String, Integer>> entrySet = map.entrySet(); for (Map.Entry<String, Integer> entry : entrySet) { System.out.println(entry); } }
HashMap和Hashtable
HashMap是1.2开始的,效率高,线程不安全 Key可以是空值,并且null值也遵照唯一特点
Hashtable是1.0开始的,效率低,效率安全,对于Hashtable的key不能为null值
如果我想按照加入顺序来输出,我们可以有一个LinkedHashMap
LinkedHashMap
特点,唯一,有序,按照输入顺序输出
小结
HashMap原理简单理解
HashMap源码重要属性:
hashMap构造器:
put方法:
新增方法中的hashCode算法:
计算位置的方法和entry对象:
经典面试题:
装填因子,负载因子,加载因子 为什么是0.75
装填因子设置为1:空间利用率得到了很大的满足,但是很容易碰撞,产生链表,查询效率边低
装填因子:0.5:碰撞几率低,扩容,产生链表几率低,查询快
于是HashMap做了个折中
主数组的长度为什么是2^n
原因1:
数组长度影响位置,H&length-1等效,等效的前提就是length必须是2的整数倍,
原因2:
防止哈希冲突,位置冲突
验证整数倍:
验证非正数倍
非整数倍,位置一样,会产生链表,导致效率变低