目录
1. Map简介
2. 常用方法
2.1 添加元素
2.2 删除元素
2.3 判断集合中是否包含指定的键
2.4 根据键获取值
3. 遍历Map集合
3.1 通过键找值的方法
3.2 使用Entry对象遍历
4. Map常用实现类
4.1 HashMap
4.2 LinkedHashMap
4.3 Hashtable
Map是一个双列集合,一个元素包含两个值(一个key,一个value)。Map集合中的元素key和value的数据类型可以相同,也可以不同。Map中的元素,key不允许重复,value可以重复。Map里的key和value是一一对应的称为键值对。
创建Map集合的对象:
因为Map是接口,不能直接创建对象,所以我们可以使用多态的方式来创建(父类引用指向子类对象)实现类HashMap的对象 。
导入Map和HashMap包:
import java.util.HashMap;
import java.util.Map;
创建key为Integer类型,value为String类型的对象map:
Map map = new HashMap<>();
将指定的值与该映射中的指定键相关联(可选操作)。 如果映射先前包含了密钥的映射,则旧值将被指定的值替换。(映射m被认为包含关键字的映射k当且仅当m.containsKey(k)将返回true )。
实例如下:
Map map = new HashMap<>();
// 添加元素
map.put(1001, "张三");
map.put(1002, "李四");
map.put(1003, "王二");
System.out.println(map);// 输出结果:{1001=张三, 1002=李四, 1003=王二}
// 如果key存在,将会覆盖掉其对应的值
map.put(1002, "李五");
System.out.println(map);// 输出结果:{1001=张三, 1002=李五, 1003=王二}
将指定地图的所有映射复制到此映射(可选操作)。 该呼叫的效果与从指定地图中的关键字k到值v的每个映射一次对该地图一次调用put(k, v)的效果相当。 如果在操作进行中修改了指定的地图,则此操作的行为是未定义的。
实例如下:
Map map1 = new HashMap<>();
map1.put(1001, "张三");
map1.put(1002, "李四");
map1.put(1003, "王二");
Map map2 = new HashMap<>();
map2.put(2001, "刘三");
map2.put(2002, "赵四");
// 将map2中的元素全部存入map1中
map1.putAll(map2);
System.out.println(map1);// 输出结果:{2001=刘三, 2002=赵四, 1001=张三, 1002=李四, 1003=王二}
如果存在(从可选的操作),从该地图中删除一个键的映射。 更正式地,如果该映射包含从关键字k到值v的映射,使得(key==null ? k==null : key.equals(k))
,该映射被去除。 (地图最多可以包含一个这样的映射。)
实例如下:
Map map = new HashMap<>();
map.put(1001, "张三");
map.put(1002, "李四");
map.put(1003, "王二");
// 根据key删除一个key和它对应的值,key不存在返回null
// 存在返回key和它对应的值
System.out.println(map.remove(1005));// 输出结果:null
System.out.println(map.remove(1002));// 输出结果:李四
System.out.println(map);// 输出结果:{1001=张三, 1003=王二}
实例如下:
Map map = new HashMap<>();
map.put(1001, "张三");
map.put(1002, "李四");
map.put(1003, "王二");
// 根据key和value删除一个key和它对应的值,
// 删除成功返回true,否则返回false
System.out.println(map.remove(1002, "赵四"));// 输出结果:false
System.out.println(map.remove(1002, "李四"));// 输出结果:true
System.out.println(map);// 输出结果:{1001=张三, 1003=王二}
实例如下:
Map map = new HashMap<>();
map.put(1001, "张三");
map.put(1002, "李四");
map.put(1003, "王二");
// 判断集合中是否包含指定的键,有返回true,否则返回false
System.out.println(map.containsKey(1003));// 输出结果:true
System.out.println(map.containsKey(1006));// 输出结果:false
Map map = new HashMap<>();
map.put(1001, "张三");
map.put(1002, "李四");
map.put(1003, "王二");
// 返回到指定键所映射的值,没有这个键则返回null
System.out.println(map.get(1002));// 输出结果:李四
System.out.println(map.get(1005));// 输出结果:李四
使用setKey方法,将Map集合中的key值,存储到Set集合,用迭代器或foreach循环遍历Set集合来获取Map集合的每一个key,并使用get(key)方法来获取value值。
实例如下:
Map map = new HashMap<>();
map.put(1001, "张三");
map.put(1002, "李四");
map.put(1003, "王二");
// 将键值存放在Set集合中
Set keySet = map.keySet();
// 增强for循环遍历keySet
for (Integer integer : keySet) {
System.out.println(integer + "=" + map.get(integer));
}
// 输出结果:
// 1001=张三
// 1002=李四
// 1003=王二
Map.Entry
作用:当集合一创建,就会在Map集合中创建一个Entry对象,用来记录键与值(键值对对象,键值的映射关系)。
实例如下:
Map map = new HashMap<>();
map.put(1001, "张三");
map.put(1002, "李四");
map.put(1003, "王二");
// 将键值对存入Set集合中
Set> entrys = map.entrySet();
for (Map.Entry entry : entrys) {
System.out.println(entry);
}
// 输出结果:
// 1001=张三
// 1002=李四
// 1003=王二
特点:
1.HashMap底是哈希表,查询速度非常快(jdk1.8之前是数组+单向链表,1.8之后是数组+单向链表/红黑树 ,链表长度超过8时,换成红黑树)
2. HashMap是无序的集合,存储元素和取出元素的顺序有可能不一致.
3.集合是不同步的,也就是说是多线程的,速度快.
HashMap存储自定义类型键值:
HashMap存储自定义类型键值,Map集合保证key是唯一的:作为key的元素,必须重写hashCode方法和equals方法,以保证key唯一。
底层原理:哈希表+链表(记录元素顺序)
特点:
1.LinkedHashMap底层是哈希表+链表(保证迭代的顺序)
2.LinkedHashMap是一个有序的集合,存储元素和取出元素的顺序一致,改进之处是元素存储有序了。
Hashtable:底层也是哈希表,是同步的,是一个单线程结合,是线程安全的集合,速度慢。
HashMap:底层也是哈希表,但是线程不安全的集合,是多线程集合,速度快。
HashMap(还有之前学的所有集合):都可以存储null键,null值。
Hashtable:不能存储null键,null值。