学习日记(集合内容之 Map 集合体系详述)

本文详细介绍了Map集合的特点、常用API及遍历方法,并通过具体案例展示了如何应用Map集合解决实际问题。此外,还深入探讨了HashMap、LinkedHashMap和TreeMap等不同实现类的特点及其应用场景。
摘要由CSDN通过智能技术生成

学习日记(集合内容之 Map 集合体系详述)

  • Map 集合是一种双列集合,每个元素包含两个数据,也被称为”键值对集合“。
  • Map 集合非常适合做购物车这样的业务场景。
  • Map 集合体系如下:

一、Map 集合特点

特点

  • Map 集合的特点都是由键决定的,键是无序、不重复、无索引的,值没有要求(可以重复)。
  • Map 集合后面重复的键对应的值会覆盖前面重复键的值。
  • Map 集合的键值对都可以为 null。


二、常用 API

方法名说明
put(K key, V value)添加键值对
get(Object key)根据键获取对应的值
remove(Object key)根据键删除整个元素,返回删除元素的值
boolean containsKey(Object key)判断是否包含某个键
boolean containsValue(Object value)判断是否包含某个值
Set keySet()获取全部的集合,返回集合为 Set 集合
Collection values()获取全部的集合,返回集合为 Collection 集合
int size()集合的大小
void putAll(Map<? extends K, ? extends V> m)合并其他集合
boolean isEmpty()判断集合是否为
void clear()清空集合

注意

  1. 获取全部键的集合时,返回集合为 Set 集合(无序、不重复、无索引)。
  2. 获取全部值的集合时,返回集合为 Collection 集合,如果值有重复,不会去掉
  3. 集合的大小指键值对的数目

三、遍历

遍历方式有三种:键找值(建议)、键值对、Lambda 表达式。

1. 键找值

步骤

  • 先获取 Map 集合中的全部键的 Set 集合;
  • 遍历 Set 集合,然后通过 get 方法通过键提取对应的值。

2. 键值对

若使用 foreach 遍历 Map 集合,但是 Map 集合中的键值对元素是没有类型的,所以不能用 foreach 直接遍历集合。因此,可以先调用 Map 集合中的 entrySet 方法将 Map 集合中的键值对元素转化为键值对实体类型,然后就可以用 foreach 直接遍历集合。

步骤

  • 先把 Map 集合转换为 Set 集合,这样 Set 集合中每个元素都是键值对实体类型
  • 使用 foreach 遍历 Set 集合,然后通过 getKey 和 getValue 方法提取键和值。
方法名说明
Set<Map.Entry<K, V>> entrySet()将 Map 集合中的键值对元素转化为键值对实体类型,存入到 Set 集合中
getKey()通过键值对实体类型的对象调用,获取键
getValue()通过键值对实体类型的对象调用,获取值

3. Lambda 表达式

Map 集合结合 Lambda 表达式遍历的 API:default void forEach(BiConsumer<? super K, ? super V> action)

分析

4. 案例

需求:一个班级 80 个学生,现在需要投票,有 A、B、C、D 四个选项,每个同学只能投一个,统计每个选项的人数。

思路:定义一个数组存放 80 个学生的选择 -> 定义一个 Map 集合存储最终统计的结果 -> 遍历学生的选择,看 Map 集合中是否存在键,若存在,则对应的值加 1;否则,存入该键,值为 1。

拓展:一个班级 80 个学生,现在需要投票,有若干选项,每个同学只能投一个,统计每个选项的人数。

package com.residue.Map;

import java.util.HashMap;
import java.util.Map;
import java.util.Set;

public class MapDemo04 {

    public static void main(String[] args) {
        //需求:一个班级 80 个学生,现在需要投票,有若干选项,每个同学只能投一个,统计每个选项的人数。
        String[] allVotes = {"A", "B", "C", "D", "A", "E", "B", "C", "D", "A",
                             "X", "K", "C", "D", "A", "A", "Y", "C", "R", "X",
                             "A", "B", "C", "D", "A", "A", "B", "Z", "D", "A",
                             "A", "H", "J", "D", "Y", "T", "B", "Y", "T", "A",
                             "A", "B", "C", "F", "A", "A", "B", "C", "H", "K",
                             "A", "B", "C", "D", "A", "A", "B", "C", "D", "A",
                             "X", "B", "T", "D", "Z", "A", "B", "G", "D", "A",
                             "A", "B", "C", "D", "A", "A", "Z", "C", "D", "A"};

        Map<String, Integer> result = new HashMap<>();

        for (int i = 0; i < allVotes.length; i++) {
            String vote = allVotes[i];
            if (result.containsKey(vote)) {
                result.put(vote, result.get(vote) + 1);
            } else {
                result.put(vote, 1);
            }
        }

        Set<String> votes = result.keySet();
        for (String vote : votes) {
            Integer nums = result.get(vote);
            System.out.println("选 " + vote + " 的人数为:" + nums);
        }
    }
}

四、实现类 HashMap 集合

特点:由键决定,无序、不重复、无索引。

方法:用 Map 中的 API。

底层原理:HashMap 和 HashSet 的底层原理一模一样,都是哈希表结构,因此增删改查的性能都较好,只不过 HashMap 的每个元素包含两个值而已。

自定义类型保证键的唯一:依赖 hashCode 和 equals 方法,所以自定义类型需要重写这两个方法。

注意:实际上,Set 系列集合的底层就是 Map 实现的,只是 Set 集合中的元素只要键数据,不要值数据而已。


五、实现类 LinkedHashMap 集合

特点:由键决定,有序(保证存储和取出的元素顺序一致)、不重复、无索引。

原理:底层数据结构依然是哈希表,只是每个键值对元素又额外多了一个双链表的机制记录存储的顺序。


六、实现类 TreeMap 集合

特点:由键决定,可排序(一定要排序,只能对键排序,可以默认升序排序,也可以自定义排序规则)、不重复、无索引。

排序规则(两种):键的类实现 Comparable 接口,重写比较规则;集合自定义 Comparator 比较器对象,重写比较规则。

原理:TreeMap 集合和 TreeSet 集合的底层原理一样。

第一种排序

在这里插入图片描述

第二种排序


七、集合的嵌套

案例再拓展:有 3 个学生,现在需要投票,有 A、B、C、D 等多个选项,每个同学可以投多个,统计每个选项的票数。

package com.residue.Map;

import java.util.*;

public class MapDemo07 {

    public static void main(String[] args) {

        //有 3 个学生,现在需要投票,有 A、B、C、D 等多个选项,每个同学可以投多个,统计每个选项的票数。

        //定义一个 Map 集合,存储每个学生的选择,如:Sun3285=[A, B, C]
        Map<String, List<String>> select = new HashMap<>();

        List<String> list1 = new ArrayList<>();
        Collections.addAll(list1, "A", "B", "F");
        select.put("Sun3285", list1);           //第一个学生

        List<String> list2 = new ArrayList<>();
        Collections.addAll(list2, "D", "E");
        select.put("Sun4399", list2);           //第二个学生

        List<String> list3 = new ArrayList<>();
        Collections.addAll(list3, "B", "C");
        select.put("Sun7849", list3);           //第三个学生

        System.out.println(select);

        System.out.println("===================================");

        //定义一个 Map 集合,统计每个选项的人数,如:A=2
        Map<String, Integer> result = new HashMap<>();

        Collection<List<String>> selects = select.values();

        System.out.println(selects);

        //把选项都存储到 list 集合中
        List<String> list = new ArrayList<>();
        for (List<String> strings : selects) {
            System.out.println(strings);
            for (String string : strings) {
                list.add(string);
            }
        }
        System.out.println(list);

        //统计选项
        for (String s : list) {
            if (result.containsKey(s)) {
                result.put(s, result.get(s) + 1);
            } else {
                result.put(s, 1);
            }
        }
        System.out.println(result);

    }
}

八、不可变集合

  • 不可变集合就是不可被修改的集合,集合的数据项在创建的时候提供,并且在整个生命周期中都不可改变,否则报错。

  • 不可变集合创建的原因:想让集合中的数据在后续操作中不被修改,或者集合对象在被不可信的库调用时,不可变的形式是安全的。

  • 创建不可变集合:调用 of 方法,如:List<Integer> lists = List.of(1, 2, 3, 4, 5, 6, 7);Map<String, Integer> map1 = Map.of("Sun3285", 1, "Sun3271", 2);

集合类型方法说明
Listof()静态方法,通过类直接调用,创建一个不可变的 List 集合
Setof()静态方法,通过类直接调用,创建一个不可变的 Set 集合
Mapof()静态方法,通过类直接调用,创建一个不可变的 Map 集合

注意:Set<Integer> set1 = Set.of(1, 2, 3, 2, 1); 会报错,原因:出现重复元素,不能自动去除。


注意:

  1. 选中某几行代码快捷键Shift + 方向键
  2. 选中某几行代码并上下移动快捷键Shift + Alt + 方向键
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Sun 3285

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值