6. Map集合体系
一、Map集合的概述
Map集合概述和使用
● Map集合是一种双列集合,每个元素包含两个数据。
● Map集合的每个元素的格式:key=value(键值对元素)。
● Map集合称为“键值对集合”。
Map集合整体格式
● Collection集合的格式:[元素1,元素2,元素3,...]
● Map集合的完整格式:{key1=value,key2=value2,key3=value3,...}
Map集合的使用场景之一:购物车系统
分析
● 购物车提供的四个商品和购买的数量在后台需要容器存储。
● 每个商品对象都一 一对应一个数量。
● 把商品对象看成是Map集合的键,购买数量堪称Map集合的值。
{商品1=2,商品2=3,商品3=2,商品4=3}
总结:
Map集合是什么?使用场景是什么样的?
● Map集合是键值对集合
● Map集合非常适合做类购物车这样的业务场景
二、Map集合体系特点
Map集合体系
说明
● 使用最多的Map集合是HashMap。
● 重点掌握HashMap,LinkedHashMap,TreeMap。
Map集合体系特点
● Map集合的特点都是由键决定的。
● Map集合的建是无序、不重复、无索引、值不做要求(可以重复)。
● Map集合后面重复的键对应的值会覆盖前面重复键的值。
● Map集合的键值对都可以为null。
Map集合实现类特点
● HashMap:无序、不重复、无索引、值不做要求。(与Map体系一致)
● LikedHashMap:有序、不重复、无索引、值不做要求。
● TreeMap:排序、不重复、无索引、值不做要求。
【代码示例】
/**
* 目标:认识Map特点体系:按照键无序、不重复、无索引、值不做要求
*/
public class MapDemo1 {
public static void main(String[] args){
//1.创建一个Map集合对象
Map<String, Integer> maps = new HashMap<>();
maps.put("鸿星尔克",3);
maps.put("Java",2);
maps.put("枸杞",100);
maps.put("安踏",4);
maps.put("Java",77); //覆盖前面的数据
maps.put(null,null);
System.out.println(maps);
Map<String, Integer> maps1 = new LinkedHashMap<>();
maps1.put("鸿星尔克",3);
maps1.put("Java",2);
maps1.put("枸杞",100);
maps1.put("安踏",4);
maps1.put("Java",77); //覆盖前面的数据
maps1.put(null,null);
System.out.println(maps1);
}
}
运行结果:
{null=null, Java=77, 枸杞=100, 鸿星尔克=3, 安踏=4}
{鸿星尔克=3, 枸杞=100, Java=77, 安踏=4, null=null}
三、Map集合常用API
Map集合
● Map是双列集合的祖宗接口,它的功能是全部双列集合都可以继承使用的。
Map API如下
方法名称 | 说明 |
V put(K key, V value) | 添加元素 |
V remove(Object key) | 根据键删除键值对元素 |
void clear( ) | 移除所有的键值对元素 |
boolean containsKey(Object key) | 判断集合是否包含指定的键 |
boolean containsValue(Object value) | 判断集合是否包含指定的值 |
boolean isEmpty( ) | 判断集合是否为空 |
int size( ) | 集合的长度,也就是集合中兼职对的个数 |
【代码示例1】添加元素
public class MapDemo {
public static void main(String[] args) {
// 1.添加元素: 无序、不重复、无索引
Map<String, Integer> maps = new HashMap<>();
maps.put("iphone",10);
maps.put("娃娃",20);
maps.put("iphone",100);
maps.put("huawei",100);
maps.put("生活用品",10);
maps.put("手表",10);
System.out.println(maps);
}
}
运行结果:
{huawei=100, 手表=10, 生活用品=10, 娃娃=20, iphone=100}
【代码示例2】清空集合
maps.clear();
System.out.println(maps); // {}
【代码示例3】判断集合是否为空,为空返回true,反之!
System.out.println(maps.isEmpty()); // false
【代码示例4】根据键获取对应值
Integer key = maps.get("huawei");
System.out.println(key); // 100
System.out.println(maps.get("生活用品")); // 10
System.out.println(maps.get("生活用品2")); // null
【代码示例5】根据键删除整个元素。(删除键会返回键的值)
System.out.println(maps.remove("iphone")); // 100
System.out.println(maps);
运行结果:
100
{huawei=100, 手表=10, 生活用品=10, 娃娃=20}
【示例代码6】判断是否包含某个键,包含返回true,反之!
System.out.println(maps.containsKey("娃娃")); // true
System.out.println(maps.containsKey("娃娃2")); // true
System.out.println(maps.containsKey("iphoneX")); // true
【示例代码7】判断是否包含某个值
System.out.println(maps.containsValue(100)); // true
System.out.println(maps.containsValue(10)); // true
System.out.println(maps.containsValue(22)); // false
【示例代码8】获取全部键的集合
// {huawei=100, 手表=10, 生活用品=10, 娃娃=20, iphone=100}
// 获取全部键的集合:public Set<K> keySet<>
// Set集合也是无序,不重复,无索引。底层原理一样。 所以可用Set收集
Set<String> keys = maps.keySet();
System.out.println(keys);
【代码示例9】获取全部值的集合
// 获取全部值的集合:Collection<V> values();
Collection<Integer> values = maps.values();
System.out.println(values); // [100, 10, 10, 20, 100]
【代码示例10】集合的大小
System.out.println(maps.size()); // 5
【代码示例11】合并其他集合
public class MapDemo {
public static void main(String[] args) {
Map<String, Integer> map1 = new HashMap<>();
map1.put("Java1",1);
map1.put("Java2",100);
System.out.println(map1);
Map<String, Integer> map2 = new HashMap<>();
map2.put("Java2",1);
map2.put("Java3",100);
System.out.println(map2);
System.out.println("-------合并后如下-------");
map1.putAll(map2);
System.out.println(map1);
System.out.println(map2);
}
}
运行结果:
{Java2=100, Java1=1}
{Java2=1, Java3=100}
-------合并后如下-------
{Java2=1, Java3=100, Java1=1}
{Java2=1, Java3=100}
四、Map集合的遍历方式一:键找值
Map集合的遍历方式一:键找值
● 先获取Map集合的全部键的Set集合。
● 遍历的Set集合,然后通过键提取对应值。
键找值涉及到的API
方法名称 | 说明 |
Set<K> keySet( ) | 获取所有键的集合 |
V get(Object key) | 根据键获取值 |
【代码示例】
public class MapDemo01 {
public static void main(String[] args){
Map<String, Integer> maps = new HashMap();
// 1.添加元素:无序、不重复、无索引
maps.put("娃娃",30);
maps.put("iphone",100);
maps.put("huawei",1000);
maps.put("生活用品",10);
maps.put("手表",10);
// 1.键找值:第一步:先拿到集合的全部键
Set<String> keys = maps.keySet();
System.out.println(keys);
// 2.第二步:遍历每个键,根据键提取值
for(String ele : keys){
Integer value = maps.get(ele);
System.out.println(ele + " ===> " + value);
}
}
}
运行结果:
[huawei, 手表, 生活用品, 娃娃, iphone]
huawei ===> 1000
手表 ===> 10
生活用品 ===> 10
娃娃 ===> 30
iphone ===> 100
五、Map集合的遍历方式二:键值对
● 遍历Map集合的遍历方式二:键值对
● 先把Map集合转换成Set集合,Set集合中每个元素都是键值对实体类型了。
● 遍历Set集合,然后提取键以及提取值。
键值对设计到的API
方法名称 | 说明 |
Set<Map.Entry<K,V>> entrySet( ) | 获取所有键值对对象的集合 |
K getKey( ) | 获取键 |
V getValue( ) | 获取值 |
【代码示例】
public class MapDemo02 {
public static void main(String[] args) {
Map<String , Integer> maps = new HashMap<>();
// 1.添加元素: 无序,不重复,无索引。
maps.put("娃娃",30);
maps.put("iphoneX",100);
maps.put("huawei",1000);
maps.put("生活用品",10);
maps.put("手表",10);
System.out.println(maps);
// maps = {huawei=1000, 手表=10, 生活用品=10, iphoneX=100, 娃娃=30}
/**
maps = {huawei=1000, 手表=10, 生活用品=10, iphoneX=100, 娃娃=30}
👇
使用foreach遍历map集合.发现Map集合的键值对元素直接是没有类型的。所以不可以直接foreach遍历集合。
👇
可以通过调用Map的方法 entrySet把Map集合转换成Set集合形式 maps.entrySet();
👇
Set<Map.Entry<String,Integer>> entries = maps.entrySet();
[(huawei=1000), (手表=10), (生活用品=10), (iphoneX=100), (娃娃=30)]
entry
👇
此时可以使用foreach遍历
*/
// 1、把Map集合转换成Set集合
Set<Map.Entry<String, Integer>> entries = maps.entrySet();
// 2、开始遍历
for(Map.Entry<String, Integer> entry : entries){
String key = entry.getKey();
int value = entry.getValue();
System.out.println(key + "====>" + value);
}
}
}
运行结果:
{huawei=1000, 手表=10, 生活用品=10, iphoneX=100, 娃娃=30}
huawei====>1000
手表====>10
生活用品====>10
iphoneX====>100
娃娃====>30
六、Map集合的遍历方式:Lambda表达式
待定中......
七、Map集合的实现类HashMap
Map集合案例-统计投票人数
需求
某个班级80名学生,现在需要组成秋游活动,班长提供了四个景点依次是(A,B,C,D),每个学生只能选择一个景点,请统计出最终哪个景点想去的人数最多。
分析
● 将80个学生选择的数据拿到程序中去。
定义Map集合用于存储最终统计的结果。
遍历80个学生选择的数据,看Map集合中是否存在,不存在存入“数据=1”,存在则其对应值+1
【代码示例】
/**
需求:统计投票人数
*/
public class MapTest1 {
public static void main(String[] args) {
// 1、把80个学生选择的数据拿进来。
String[] selects = {"A" , "B", "C", "D"};
StringBuilder sb = new StringBuilder();
Random r = new Random();
for (int i = 0; i < 80; i++) {
sb.append(selects[r.nextInt(selects.length)]);
}
System.out.println(sb);
// 2、定义一个Map集合记录最终统计的结果: A=30 B=20 C=20 D=10 键是景点 值是选择的数量
Map<Character, Integer> infos = new HashMap<>(); //
// 3、遍历80个学生选择的数据
for (int i = 0; i < sb.length(); i++) {
// 4、提取当前选择景点字符
char ch = sb.charAt(i);
// 5、判断Map集合中是否存在这个键
if(infos.containsKey(ch)){
// 让其值 + 1
infos.put(ch , infos.get(ch) + 1);
}else {
// 说明此景点是第一次被选
infos.put(ch , 1);
}
}
// 4、输出集合
System.out.println(infos);
}
}
Map集合实现类HashMap的原理
HashMap的特点
● HashMap是Map里面的一个实现类。特点都是由键决定的:无序、不重复、无索引。
● 没有额外需要学习的特有方法,直接使用Map里面的方法就可以了
● HashMap跟HashSet底层原理是一样的,都是哈希表结构,只是HashMap的每个元素包含两个值而已。
实际上:Set系列集合的底层就是Map实现的,只是Set集合中的元素只要键数据,不要值数据。
public HashSet(){
map = new HashMap<>();
}
【代码示例】
定义类:Student
点击查看代码
public class Student {
private String name;
private int age;
private char sex;
public Student() {
}
public Student(String name, int age, char sex) {
this.name = name;
this.age = age;
this.sex = sex;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public char getSex() {
return sex;
}
public void setSex(char sex) {
this.sex = sex;
}
/**
只要2个对象内容一样,结果一定是true
* @param o
* @return
*/
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Student student = (Student) o;
return age == student.age && sex == student.sex && Objects.equals(name, student.name);
}
/**
s1 = new Student("无恙", 20, '男')
s2 = new Student("无恙", 20, '男')
s3 = new Student("周雄", 21, '男')
*/
@Override
public int hashCode() {
return Objects.hash(name, age, sex);
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
", sex=" + sex +
'}';
}
}
测试类:
public class HashMapDemo1 {
public static void main(String[] args) {
// Map集合是根据键去除重复元素
Map<Student, String> maps = new HashMap<>();
Student s1 = new Student("无恙", 20, '男');
Student s2 = new Student("无恙", 20, '男');
Student s3 = new Student("周雄", 21, '男');
maps.put(s1, "北京");
maps.put(s2, "上海");
maps.put(s3, "广州");
System.out.println(maps);
}
}
运行结果:
{Student{name='无恙', age=20, sex=男}=上海, Student{name='周雄', age=21, sex=男}=广州}
总结:
HashMap的特点和底层原理
● 由键决定:无序、不重复、无索引。HashMap底层是哈希结表结构的
● 依赖hashCode方法和equals方法保证键的唯一。
● 如果键要存储的是自定义对象,需要重写hashCode和equals方法。
● 基于哈希表。增删改查性能都较好。
8. Map集合的实现类LinkedhashMap
LinkedHashMap集合概述和特点
● 由键决定:有序、不重复、无索引。
● 这里的有序指的是保证存储和取出的元素顺序一致。
● 原理:底层数据结构依然是哈希表,只是每个键值对元素又额外的多了一个双链表的机制记录存储的顺序。
【代码示例】
public class LikedHashMapDemo02 {
public static void main(String[] args) {
Map<String, Integer> maps = new LinkedHashMap<>();
maps.put("鸿星尔克",3);
maps.put("Java",1);
maps.put("枸杞",100);
maps.put("Java",100);
maps.put(null,null);
System.out.println(maps);
}
}
运行结果:
{鸿星尔克=3, Java=100, 枸杞=100, null=null}
9. Map集合的实现类TreeMap
TreeMap集合概述和特点
● 由键决定特性:不重复、无索引、可排序
● 可排序:按照键数据的大小默认升序(有小有大)排序,只能对键排序。
● 注意:TreeMap集合是一定要排序的,可以默认排序,也可以将键按照指定的规则进行排序
● TreeMap跟TreeSet底层原理是一样的。
TreeMap集合自定义排序规则有2种
● 类实现Comparable接口,重写比较规则。
● 集合自定义Comparator比较器对象,重写比较规则。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南