欢迎光临
我们一直在努力

Java学习22

下午 2.5h

3. Map 集合入门 & HashMap 核心

3.1 核心概念

  • Map 是双列集合:存储键值对(Key-Value)
  • Key:唯一、不可重复;Value:可重复
  • HashMap:开发最常用,底层哈希表,线程不安全,效率高
  • 键和值都可以为null(但键只能有一个 null)
  • 3.2 计划遗漏重要知识点

    • Hashtable:线程安全、效率低、不允许 null 键 null 值(老版本用)
    • TreeMap:可对键自动排序

    4. HashMap 四大核心方法(必默写)

    4.1 方法详解

  • put(K key, V value):添加 / 覆盖
    • key 不存在 → 添加
    • key 已存在 → 用新 value 覆盖旧 value
  • get(K key):根据 key 获取 value,key 不存在返回 null
  • remove(K key):根据 key 删除整个键值对
  • containsKey(key):判断是否包含指定键
  • containsValue(value):判断是否包含指定值
  • 4.2 完整实战代码(学号 – 学生对象)

    java

    运行

    import java.util.HashMap;

    public class HashMapMethodDemo {
    public static void main(String[] args) {
    // 1. 创建HashMap:键=学号(String),值=学生对象
    HashMap<String, Student> map = new HashMap<>();

    // 2. put 添加元素
    map.put("001", new Student("001", "张三"));
    map.put("002", new Student("002", "李四"));
    map.put("001", new Student("001", "张三三")); // 键重复 → 覆盖

    // 3. get 根据键取值
    Student s = map.get("002");
    System.out.println("学号002的学生:" + s);

    // 4. containsKey 判断键是否存在
    System.out.println("是否包含003:" + map.containsKey("003"));

    // 5. remove 根据键删除
    map.remove("001");
    System.out.println("删除后集合:" + map);
    }
    }


    晚上 1.5h

    5. HashMap 两种基础遍历

    5.1 遍历方式 1:遍历所有 key(最常用)

    步骤:keySet() → 得到所有键的集合 → 遍历键 → get() 取值

    java

    运行

    System.out.println("—–遍历key—–");
    Set<String> keys = map.keySet();
    for (String key : keys) {
    Student value = map.get(key);
    System.out.println("键:" + key + ",值:" + value);
    }

    5.2 遍历方式 2:直接遍历所有 value

    步骤:values() → 得到所有值的集合

    java

    运行

    System.out.println("—–遍历value—–");
    Collection<Student> values = map.values();
    for (Student value : values) {
    System.out.println(value);
    }

    计划遗漏补充(高频面试)

    HashMap 第三种遍历:entrySet ()(企业开发首选)

    java

    运行

    // 键值对一起遍历,效率最高
    Set<Map.Entry<String, Student>> entries = map.entrySet();
    for (Map.Entry<String, Student> entry : entries) {
    System.out.println(entry.getKey() + "=" + entry.getValue());
    }


    Day22 过关标准(自测)

  • 能口述 HashSet 去重完整流程
  • 能给自定义对象实现去重
  • 能默写 HashMap 增删查改方法
  • 会写 key、value、entrySet 三种遍历
  • 能完成:学号 – 学生、姓名 – 分数的增删改查
  • 上午 3h

    1. 泛型深度进阶

    1.1 泛型作用(必须理解)

  • 类型约束:限定集合存储的数据类型
  • 避免强制类型转换
  • 编译期安全:编译时报错,而非运行时报错
  • 1.2 泛型分类

  • 泛型类:class 类名<T>
  • 泛型方法:public <T> 返回值 方法名(T t)
  • 通配符?:表示任意类型
  • 受限泛型
    • ? extends 类:上限,只能是该类或其子类
    • ? super 类:下限,只能是该类或其父类
  • 1.3 泛型类 完整代码

    java

    运行

    // T:泛型标识,代表任意引用类型
    public class GenericClass<T> {
    private T data;

    public GenericClass(T data) {
    this.data = data;
    }

    public T getData() {
    return data;
    }
    }

    // 测试
    public class Test {
    public static void main(String[] args) {
    // 存储字符串
    GenericClass<String> g1 = new GenericClass<>("Java");
    // 存储整数
    GenericClass<Integer> g2 = new GenericClass<>(100);
    }
    }

    1.4 泛型方法 完整代码

    java

    运行

    public class GenericMethod {
    // 泛型方法:打印任意类型数组
    public static <T> void printArray(T[] arr) {
    for (T t : arr) {
    System.out.print(t + " ");
    }
    System.out.println();
    }

    public static void main(String[] args) {
    Integer[] arr1 = {1,2,3};
    String[] arr2 = {"A","B","C"};

    printArray(arr1); // 1 2 3
    printArray(arr2); // A B C
    }
    }

    这一部分的解释

    逐行运行逻辑(从上到下执行)

  • 程序入口Java 运行自动找 main 方法,从 main 里面第一行开始执行。

  • 执行代码①

  • java

    运行

    GenericClass<String> g1 = new GenericClass<>("Java");

    • 声明泛型类型:<String>
    • 调用构造方法,传入参数:"Java"
    • 进入构造方法:this.data = data;→ 把传入的 Java 赋值给成员变量 private T data
    • 此时:g1 对象内部的 data = 字符串 Java
  • 执行代码②
  • java

    运行

    GenericClass<Integer> g2 = new GenericClass<>(100);

    • 声明泛型类型:<Integer>
    • 调用构造方法,传入参数:100
    • 给成员变量 data 赋值:data = 100
    • 此时:g2 对象内部的 data = 整数 100
  • 执行打印
  • java

    运行

    g1.getData()

    • 调用 getData() 方法
    • 方法内部 return data
    • 取出 g1 存的 Java → 打印输出

    java

    运行

    g2.getData()

    • 取出 g2 存的 100 → 打印输出

    三、泛型 <T> 核心运行规则

  • 你写 GenericClass<String>👉 整个类里所有 T 全部替换成 String
  • 你写 GenericClass<Integer>👉 整个类里所有 T 全部替换成 Integer
  • 等价理解

    • g1 生效时:

    java

    运行

    private String data;
    public GenericClass(String data){}
    public String getData(){}

    • g2 生效时:

    java

    运行

    private Integer data;
    public GenericClass(Integer data){}
    public Integer getData(){}


    四、一句话总结整体逻辑

  • 创建对象时,指定泛型类型
  • 构造方法接收数据,存入成员变量
  • 调用 getData() 取出保存的数据
  • 控制台打印输出
  • 1.5 通配符?完整代码

    java

    运行

    // 接收任意泛型集合
    public static void printList(List<?> list) {
    for (Object o : list) {
    System.out.println(o);
    }
    }


    2. 泛型代码实操(已包含在上面,直接运行)


    下午 2.5h

    3. Collections 工具类(集合专用)

    3.1 重要区分

    • Collection:List/Set 的根接口
    • Collections:操作集合的工具类,全是静态方法

    3.2 核心静态方法(完整代码)

    java

    运行

    import java.util.ArrayList;
    import java.util.Collections;

    public class CollectionsDemo {
    public static void main(String[] args) {
    ArrayList<Integer> list = new ArrayList<>();

    // 1. 批量添加
    Collections.addAll(list, 5,3,8,1);

    // 2. 升序排序
    Collections.sort(list);

    // 3. 打乱顺序
    Collections.shuffle(list);

    // 4. 最大值、最小值
    System.out.println(Collections.max(list));
    System.out.println(Collections.min(list));

    // 5. 反转
    Collections.reverse(list);
    }
    }

    计划遗漏补充

  • 空集合:Collections.emptyList()(不存储元素,节省内存)
  • 不可变集合:List.of()、Map.of()(JDK9+,不能增删改)

  • 晚上 1.5h

    4. 综合大练习:集合版学生管理系统

    功能清单

    • 添加学生
    • 删除学生(按学号)
    • 修改学生信息
    • 查询单个学生
    • 查询所有学生
    • 按学号 / 成绩排序
    • 泛型 + HashMap/ArrayList 实现

    完整可运行代码(直接复制使用)

    java

    运行

    import java.util.*;

    // 学生类
    class Student {
    private String id;
    private String name;
    private int score;

    public Student(String id, String name, int score) {
    this.id = id;
    this.name = name;
    this.score = score;
    }

    // getter、setter、toString
    public String getId() {return id;}
    public String getName() {return name;}
    public int getScore() {return score;}
    public void setName(String name) {this.name = name;}
    public void setScore(int score) {this.score = score;}

    @Override
    public String toString() {
    return "学号:"+id+",姓名:"+name+",分数:"+score;
    }
    }

    // 学生管理系统
    public class StudentManager {
    // 用HashMap存储:key=学号,value=学生
    private static HashMap<String, Student> stuMap = new HashMap<>();
    private static Scanner sc = new Scanner(System.in);

    public static void main(String[] args) {
    while (true) {
    System.out.println("=====学生管理系统=====");
    System.out.println("1.添加 2.删除 3.修改 4.查询 5.全部展示 6.排序 0.退出");
    int choice = sc.nextInt();
    switch (choice) {
    case 1: addStu(); break;
    case 2: deleteStu(); break;
    case 3: updateStu(); break;
    case 4: findStu(); break;
    case 5: showAll(); break;
    case 6: sortStu(); break;
    case 0: return;
    }
    }
    }

    // 添加
    private static void addStu() {
    System.out.print("输入学号:");
    String id = sc.next();
    if (stuMap.containsKey(id)) {
    System.out.println("学号已存在!");
    return;
    }
    System.out.print("输入姓名:");
    String name = sc.next();
    System.out.print("输入分数:");
    int score = sc.nextInt();
    stuMap.put(id, new Student(id, name, score));
    System.out.println("添加成功");
    }

    // 删除
    private static void deleteStu() {
    System.out.print("输入要删除的学号:");
    String id = sc.next();
    if (stuMap.remove(id) != null) System.out.println("删除成功");
    else System.out.println("学号不存在");
    }

    // 修改
    private static void updateStu() {
    System.out.print("输入要修改的学号:");
    String id = sc.next();
    Student s = stuMap.get(id);
    if (s == null) {
    System.out.println("学号不存在");
    return;
    }
    System.out.print("输入新姓名:");
    s.setName(sc.next());
    System.out.print("输入新分数:");
    s.setScore(sc.nextInt());
    System.out.println("修改成功");
    }

    // 查询单个
    private static void findStu() {
    System.out.print("输入学号:");
    Student s = stuMap.get(sc.next());
    System.out.println(s == null ? "无此学生" : s);
    }

    // 展示全部
    private static void showAll() {
    for (Student s : stuMap.values()) System.out.println(s);
    }

    // 排序(Collections.sort)
    private static void sortStu() {
    ArrayList<Student> list = new ArrayList<>(stuMap.values());
    // 按分数升序
    Collections.sort(list, Comparator.comparingInt(Student::getScore));
    for (Student s : list) System.out.println(s);
    }
    }


    Day22 过关标准(自测)

  • 能区分泛型类、泛型方法、通配符?
  • 能独立使用 Collections 排序、打乱、批量添加
  • 能独立写出学生管理系统
  • 能使用 HashMap + ArrayList 完成增删改查
  • 能使用泛型保证类型安全
  • 今日重点理解

    Student s = stuMap.get(id);

    stuMap.put(id, new Student(id, name, score));这两句

    先看整行

    java

    运行

    Student s = stuMap.get(id);

    1. 逐个单词翻译

    • Student :学生类型(引用类型)
    • s :自定义变量名,用来接收学生对象
    • stuMap :你创建的 HashMap 集合
    • .get(键) :Map 专属方法作用:根据【key 键】,取出对应的【value 值】
    • id :你键盘输入的学号(就是 Map 里的 key)

    2. 整句话完整意思

    java

    运行

    // 根据输入的学号id,去map集合里找对应的学生
    // 找到就把学生对象 赋值给变量 s
    Student s = stuMap.get(id);

    大白话:拿着学号,去集合里查这个人,查到就把这个人拿出来交给 s


    3. 结合你项目的数据结构

    你的 map:

    java

    运行

    HashMap<String, Student> stuMap
    key(键) = 学号 String
    value(值) = 学生对象 Student

    存入时:

    java

    运行

    stuMap.put(学号, 学生对象);

    取出时:

    java

    运行

    stuMap.get(学号) 👉 返回 对应的学生对象


    4. 两种结果(重点必考)

  • 如果集合里有这个学号s = 真实的学生对象后面可以:s.setName()、s.getScore() 正常使用

  • 如果没有这个学号s = null代表:空、没找到这个人

  • 所以代码里会判断:

    java

    运行

    if(s == null){
    System.out.println("学号不存在");
    }


    5. 超短背诵版

  • map.get(键) → 通过键拿值
  • 这里键是学号,值是学生
  • 查到返回学生对象,查不到返回 null
  • Student s 用来接收取出来的学生
  • stuMap.put(id, new Student(id, name, score))

    原代码

    java

    运行

    stuMap.put(id, new Student(id, name, score));


    第一步:先认识每个东西

  • stuMap你定义的:
  • java

    运行

    HashMap<String,Student> stuMap

    作用:存「学号 → 学生对象」

  • .put(键,值)Map 固定方法作用:往集合里添加一组 键值对数据

  • 第一个参数 id就是你键盘输入的学号,作为 Map 的 key (键)

  • 第二个参数 new Student(id, name, score)

    • new Student() :新建一个学生对象
    • 括号里三个参数:把输入的 学号、姓名、分数,传给学生构造方法直接创建出一个完整学生

    第二步:整句拆开

    java

    运行

    // 左边键:id(学号)
    // 右边值:new出来的学生对象
    stuMap.put( 键 , 值 );

    完整翻译:

    拿着输入的学号当做 key新建一个学生对象当做 value把这一对数据,存入 stuMap 集合


    第三步:拆成两行等价写法(更好理解)

    java

    运行

    // 1. 先创建学生对象
    Student oneStu = new Student(id, name, score);
    // 2. 再存入map
    stuMap.put(id, oneStu);

    你原来那一行,只是合并写成一行,效果完全一样。


    第四步:运行流程(一步不落)

  • 你输入学号 id
  • 你输入姓名 name
  • 你输入分数 score
  • 执行这句:
    • 自动 new 一个学生,打包好三个数据
    • 以学号为钥匙,把这个学生放进 HashMap
  • 存完,系统里就有这个学生了

  • 第五步:必考核心

    • put = 新增 / 覆盖
    • key(学号)唯一
    • 如果学号重复执行 put,会覆盖旧学生数据所以代码前面会先判断:

    java

    运行

    if(stuMap.containsKey(id)){
    学号已存在,不让添加
    }


    大白话终极总结

    java

    运行

    stuMap.put(id, new Student(id, name, score));

    👉 新建一个学生,用学号当钥匙,存进集合里。

    赞(0)
    未经允许不得转载:171主机测评 » Java学习22
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址