一、Map集合的概述
二、常用API
//创建HashMap的对象
HashMap map = new HashMap();
/*V put(K key, V value)
在此映射中关联指定值与指定键,添加元素进去 */
//null值也可作为键值
map.put(null, "123");
map.put(1, "456");
map.put(2, "789");
map.put(3, "asd");
System.out.println(map);
/*V get(Object key)
返回指定键所映射的值;如果对于该键来说,
此映射不包含任何映射关系,则返回 null*/
//查询值,通过键值
System.out.println(map.get(null));
/*Set<Map.Entry<K,V>> entrySet()
返回此映射所包含的映射关系的 Set 视图 */
//获得一个set类型集合,将键和值都存储在entrySet中
//键值对都存储在Map.entry类中,一个对象就是一个键值对
Set entrySet = map.entrySet();
System.out.println(entrySet);
/*Set<K> keySet()
返回此映射中所包含的键的 Set 视图 */
//获得map当中所有的键
Set keySet = map.keySet();
System.out.println(keySet);
/*boolean containsKey(Object key)
如果此映射包含指定键的映射关系,则返回 true*/
System.out.println(map.containsKey(null));
/*V remove(Object key)
如果存在一个键的映射关系,则将其从此映射中移除(可选操作)。 */
map.remove(null);
System.out.println(map);
三、底层实现原理
1、区分数据不能重复:
HashMap的底层使用的是 数组+链表 的形式在存储,而且集合区分数据不同是通过调用 Object中的HashCode和覆写equals方法。通过HashCode方法来计算哈希值,而哈希值是根据类型里面的属性来计算值,如果哈希值相同,就会调用equals方法来对比对象当中具体的值。
2、如何无序
底层默认的数据长度为16,当调用put方法传入数据的时候,会先计算对象的哈希值,然后通过哈希值加数组的长度来计算对象存储的位置,而数组当中其实存储的是对象的哈希值,而哈希值指向的是对象的地址,而数据的存储的位置实际上是在链表当中。
3、如何扩容
在底层当中,有一个东西叫做 加载因子(负载因子),而其默认为0.75,如果你传入的数据超过了 数组 * 加载因子 也就是12个元素,那么数组就会自动扩容两倍。
4、注意点
在jdk 1.8之前 HashMap的底层是 数组 + 链表的形式
但是在jdk 1.8之后 一旦超过 8 个数据 底层就会自动转换成为 数组 + 二叉树
这样的目的是提高其数据查询的效率。
5、HashMap内部是怎样存储数据的
HashMap当中定义了一个 Map.Entry内部类,而这个内部类就是存储数据的,每添加一对键值,就会创建一个Entry对象,而Entry对象实际存储在Node当中,Node也是HashMap当中的内部类,链表的节点。数组存储的是Entry对象的哈希值,Node存储的就是Entry的地址和数据
四、循环遍历Map
public class CircuMap {
public static void main(String[] args) {
HashMap map = new HashMap();
map.put(null, "123");
map.put(1, "456");
map.put(2, "789");
map.put(3, "asd");
System.out.println("----------第一种--------------");
System.out.println(map);
System.out.println("----------第二种--------------");
//使用entrySet获得set集合,通过foreach来遍历
Set entrySet = map.entrySet();
for (Object object : entrySet) {
System.out.println(object);
}
System.out.println("----------第三种--------------");
//使用迭代器来遍历
Set keySet = map.keySet();
Iterator iterator = keySet.iterator();
//定义一个中间变量来存储地址
Object temp;
while(iterator.hasNext()){
//将下一个地址赋值给temp
temp = iterator.next();
System.out.println("键:"+temp+" 值:"+map.get(temp));
}