一、Map集合介绍及特点
Map集合简介
- Map<Key, Value> 集合是一个键值对集合或者叫双列集合
- 有别于Collection集合中存储的是单列(可以用一个类型对元素进行描述)
Map集合的描述需要既要描述Key的类型也要描述Value的类型
Map集合的特点
- 通过key映射Value(可以通过key而访问Value)
- Map集合中Value元素可以重复,但Key元素不能重复
二、HashMap介绍及特点
HashMap是采用哈希表的Map
-
什么是哈希表:
哈希表的本质是数组,数组类型是链表 -
哈希表的元素存储
- 调用要存储的元素对象的hashCode()方法获取该对象的hashCode值
- 根据hashCode值%数组长度=余数,该余数就是此元素在哈希表存储的索引位置
情况一:该索引位没有元素,那么直接将新元素存储在此
情况二:该索引位存在已有元素,那么将新元素加到己有元素的尾部,形成链表
- 哈希表的元素访问
- 根据要访问的元素对象获取到该对象的hashCode值
- 根据hashCode值%数组长度=余数,根据该余数(索引值)查询数组,如果该索引位没有元素代表查询的元素对象不存在
- 如果该索引位存在元素那么根据链表的线性查询该元素对象有则返回
- HashMap的特点
- HashMap的实现的基础数据结构是数组(数组长度默认是16位),每一对Key-Value键值对组成一个Entity对象,以双向链表的形式存放到这个数组中
- 元素在数组的位置(索引)是由Key.hashCode ( ) 来决定的,如果说两个Key的hashCode值一样的话,这种情况叫做哈希碰撞,那么这两个key所组成的Entity对象会以链表的形式存在在数组中
- 在HashMap中访问某个Entity对象时首先会计算Key的hashCode值继而找到key所对应的索引值然后遍历该链表查到对应的对象
- 为了提升整个HashMap的读写效率,当HashMap中存储的元素大小等于数组大小乘以负载因子的时候(16*0.75=12)时,整个HashMap将进行扩容(为了减少哈希碰撞)
- 在jdk8中如果数组中的某一索引位置上的链表数量超过一定阈值(8),那么整个链表将会转化成为红黑树。如果数量低于一定阈值(6),那么红黑树将会转成链表
三、HashMap集合的api用法
- 增加元素:put(key, value) → 在map集合中增加一对key-value键值对, 如果key重复的话则值会进行覆盖, 允许key和value为null
- 查询元素:get (key) →根据输入的key值查询map集合中的对应的value值, 如果输入的key在map集合中不存在那么返回null
- 删除元素:remove(key) →根据输入的key删除map集合中对应的key-value键值对,如果输入的key不存在于map集合中,则返回null
- 判断元素是否存在:判断key是否存在于map集合,可用containsKey (key) →查询输入的key是否存在于map集合存在返回true不存在返回false,同理,判断value是否存在于map集合,可用 containsValue (value)
- 遍历map集合: entrySet() → 获取map集合中所有的entry对象返回的类型是Set ; keySet() →返回map集合中的所有key返回类型是Set
// 增加元素
// put(key, value):在map集合中增加一对key-value键值对
// 如果key重复的话则值会进行覆盖
// 允许key和value为null
HashMap<String,String> hashMap = new HashMap<>(;
hashMap.put("司马相如","卓文君");
hashMap.put("刘秀","阴丽华");
hashMap.put("刘彻","卫子夫");
hashMap.put("项羽","虞姬");
hashMap.put("项羽","吕雉");
hashMap.put("项羽","卓文君");
hashMap.put(null, null);
// 查询元素
// get (key):根据输入的key值查询map集合中的对应的value值
// 如果输入的key在map集合中不存在那么返回null
String value1 = hashMap.get("123");
System.out.println(value1);
System.out.println("---------");
String value2 = hashMap.get("刘秀");
System.out.println(value2);
// 删除元素
// remove(key):根据输入的key删除map集合中对应的key-value键值对
// 如果输入的key不存在于map集合中,则返回null
String result2 = hashMap.remove("456");
System.out.println (hashMap.get("刘秀"));
System.out. println(result2);
System.out. println("---------");
String name = "123";
// 判断key是否存在于map集合
// containsKey (key):查询输入的key是否存在于map集合存在返回true不存在返回false
boolean result3 = hashMap.containsKey(name) ;
System.out.println("输入的key:"+name+"在map集合中是否存在:"+result3);
System.out.println("---------");
String valueName = "789";
boolean result4 = hashMap.containsValue(valueName) ;
System.out.println("输入的value:"+valueName+"在map集合中是否存在:"+result4);
System.out.println("---------");
// 遍历map集合
// entrySet():获取map集合中所有的entry对象返回的类型是Set
Set<Map.Entry<String,String>> entries = hashMap.entrySet();
//获取迭代器对象
Iterator<Map.Entry<String,String>> iterator = entries.iterator
System.out.println("第一种遍历方式:");
while (iterator.hasNext()){
Map.Entry<String,String>next = iterator. next();String key = next.getKey ();
String value = next.getValue () ;System. out. print(key);
System. out. println("\t\t"+value);
}
System.out.println("---------");
System.out.println("第二种遍历方式:");
for (Map. Entry<String,String> next : entries){
String key = next.getKey () ;
String value = next. getValue() ;System. out. print(key);
System.out.println("\t\t"+value);
}
System.out.println("---------");
// keySet():返回map集合中的所有key返回类型是Set
Set<String> keySet = hashMap.keySet() ;
System.out.println("遍历map集合中的所有key值");
for (String s : keySet){
System.out.printin(s);
}
四、HashMap结构及put方法图解
HashMap基本结构:
HashMap源码结构:
HashMap中put方法流程图: