Java 入门,详解List,Map集合使用

一.List

在 Java 中,List 是一个接口‌,属于 java.util 包,是 Java 集合框架(Java Collections Framework)的重要组成部分。List(列表)是一种有序 的集合,它允许存储重复的元素。你可以把它想象成一个排队列表或者购物清单:

  • 有序:你添加元素的顺序就是它们存储的顺序。
  • 可重复:你可以添加多个相同的元素(比如买了两个苹果)。
  • 通过索引访问:就像数组一样,可以通过下标(从 0 开始)来获取元素。
  • 动态容量‌:实现类(如 ArrayList)会自动扩容,无需手动指定大小。

最常用的实现类是 ArrayList
注意:List 是接口,‌不能直接实例化‌。应使用接口引用 + 实现类实例的方式,例如

java 复制代码
List<String> list = new ArrayList<>();

代码例子:一个简单的待办事项列表

java 复制代码
import java.util.ArrayList;
import java.util.List;

public class ListDemo {
    public static void main(String[] args) {
        // 1. 创建 List
        // 这里我们创建一个存储 String (字符串) 的列表
        List<String> todoList = new ArrayList<>();

        // 2. 添加数据 (add)
        todoList.add("买牛奶");       // 索引 0
        todoList.add("写Java代码");    // 索引 1
        todoList.add("跑步");          // 索引 2
        
        // 在指定位置插入元素 (例如在索引 1 的位置插入,原来的元素后移)
        todoList.add(1, "回复邮件");   
        // 现在列表顺序: ["买牛奶", "回复邮件", "写Java代码", "跑步"]

        System.out.println("--- 初始列表 ---");
        System.out.println(todoList); 

        // 3. 获取数据 (get)
        // 注意:索引从 0 开始
        String firstTask = todoList.get(0);
        System.out.println("第一个任务 is: " + firstTask); // 输出: 买牛奶

        // 4. 修改数据 (set)
        // 将索引为 2 的元素修改为 "学习Python"
        todoList.set(2, "学习Python");
        System.out.println("--- 修改后 ---");
        System.out.println(todoList); // 输出: [买牛奶, 回复邮件, 学习Python, 跑步]

        // 5. 删除数据 (remove)
        // 方式 A: 根据索引删除
        todoList.remove(0); // 删除第一个元素 "买牛奶"
        
        // 方式 B: 根据对象内容删除 (删除第一个匹配到的 "跑步")
        todoList.remove("跑步");
        
        System.out.println("--- 删除后 ---");
        System.out.println(todoList); // 输出: [回复邮件, 学习Python]

        // 6. 检查是否存在 (contains)
        boolean hasJava = todoList.contains("写Java代码");
        System.out.println("还有写Java代码这个任务吗? " + hasJava); // 输出: false (因为之前被替换了)

        // 7. 获取大小 (size)
        System.out.println("当前任务数量: " + todoList.size()); // 输出: 2

        // 8. 遍历 List (三种常用方式)
        System.out.println("--- 遍历所有任务 ---");

        // 方式 A: 传统 for 循环 (通过索引)
        for (int i = 0; i < todoList.size(); i++) {
            System.out.println("任务 " + (i + 1) + ": " + todoList.get(i));
        }

        // 方式 B: 增强 for 循环 (foreach) - **最推荐,简洁**
        for (String task : todoList) {
            System.out.println("正在做: " + task);
        }
        
        // 方式 C: forEach + Lambda (Java 8+)
        todoList.forEach(task -> System.out.println("Lambda: " + task));
    }
}
操作 方法 说明
创建 new ArrayList<>() 创建一个空的动态数组列表
添加 add(element) 在末尾添加元素
插入 add(index, element) 在指定索引位置插入元素
获取 get(index) 根据索引获取元素
修改 set(index, element) 替换指定索引位置的元素
删除 remove(index) 或 remove(object) 根据索引或删除第一个匹配的对象
判断存在 contains(object) 判断列表中是否包含某个元素
大小 size() 获取列表中元素的数量
清空 clear() 删除所有元素

注意事项

  • 索引从 0 开始:这和数组一样。如果有 3 个元素,索引分别是 0, 1, 2。如果你尝试 get(3),会抛出IndexOutOfBoundsException(下标越界异常)。
  • 泛型:同样强烈建议使用泛型。List 表示这个列表只能存字符串。如果你尝试add(123),编译器会直接报错,防止运行时错误。
  • ArrayList vs LinkedList
    ArrayList:底层是数组。查询快(通过索引直接定位),增删慢(中间插入/删除需要移动后续元素)。大多数情况下首选
    ArrayList。 LinkedList:底层是链表。增删快,查询慢。只有在频繁在列表中间进行插入/删除操作时才考虑使用。
  • 基本数据类型:和 Map 一样,List 不能直接存 int, double 等基本类型,必须使用包装类 Integer, Double等。例如:List numbers = new ArrayList<>();

二.Map

在 Java 中,Map(映射)是一种存储 键值对 (Key-Value Pair) 的数据结构。是一种双列集合接口,你可以把它想象成一个字典或通讯录:
Key (键) :就像人的名字(唯一,用来查找)。
Value (值) :就像人的电话号码(对应的数据)。

最常用的实现类是 HashMap
核心特性:

  • 键值对存储‌:每个元素由一个键(key)和一个值(value)组成。 ‌
  • 键唯一‌:Map中‌不能包含重复的键‌;若尝试添加重复键,新值会覆盖旧值。 ‌
  • 值可重复‌:多个键可以对应相同的值。
  • 一对一映射‌:每个键最多对应一个值,体现数学中的函数概念

代码示例:一个简单的学生成绩表

java 复制代码
import java.util.HashMap;
import java.util.Map;

public class MapDemo {
    public static void main(String[] args) {
        // 1. 创建 Map
        // Key 是 String (学生姓名), Value 是 Integer (分数)
        Map<String, Integer> scoreMap = new HashMap<>();

        // 2. 添加数据 (put)
        scoreMap.put("张三", 90);
        scoreMap.put("李四", 85);
        scoreMap.put("王五", 92);
        
        // 如果 key 已经存在,新的 value 会覆盖旧的
        scoreMap.put("张三", 95); // 张三的分数从 90 变成了 95

        System.out.println("--- 初始数据 ---");
        System.out.println(scoreMap); // 输出: {张三=95, 李四=85, 王五=92}

        // 3. 获取数据 (get)
        int zhangSanScore = scoreMap.get("张三");
        System.out.println("张三的分数是: " + zhangSanScore); // 输出: 95

        // 如果 key 不存在,get 返回 null
        Integer zhaoLiuScore = scoreMap.get("赵六");
        System.out.println("赵六的分数是: " + zhaoLiuScore); // 输出: null

        // 4. 检查是否存在 (containsKey / containsValue)
        boolean hasLiSi = scoreMap.containsKey("李四");
        System.out.println("是否有李四? " + hasLiSi); // 输出: true

        // 5. 删除数据 (remove)
        scoreMap.remove("王五");
        System.out.println("--- 删除王五后 ---");
        System.out.println(scoreMap); // 输出: {张三=95, 李四=85}

        // 6. 遍历 Map (三种常用方式)
        System.out.println("--- 遍历所有数据 ---");
        
        // 方式 A: 遍历所有的 Key,然后通过 Key 获取 Value (最常用)
        for (String name : scoreMap.keySet()) {
            Integer score = scoreMap.get(name);
            System.out.println("学生: " + name + ", 分数: " + score);
        }

        // 方式 B: 直接遍历 Entry (键值对对象),效率稍高
        for (Map.Entry<String, Integer> entry : scoreMap.entrySet()) {
            System.out.println("学生: " + entry.getKey() + ", 分数: " + entry.getValue());
        }
    }
}

核心知识点总结:

操作 方法 说明
创建 new HashMap<>() 创建一个空的 Map
添加/修改 put(key, value) 如果 Key 不存在则添加;如果存在则覆盖旧值
获取 get(key) 根据 Key 获取 Value。如果 Key 不存在,返回 null
删除 remove(key) 根据 Key 删除整个键值对
判断存在 containsKey(key) 判断是否包含某个 Key
大小 size() 获取 Map 中有多少个键值对
清空 clear() 删除所有元素

注意事项

  • Key 的唯一性:Map 中的 Key 必须是唯一的。如果你 put 了两个相同的 Key,后面的值会覆盖前面的值。
  • Null 值:HashMap 允许 Key 和 Value 为 null(但 Key 为 null 只能有一个)。 调用 get() 时,如果返回null,可能是因为 Key 不存在,也可能是因为 Value 本身就是 null。建议先用 containsKey() 判断。
  • 泛型<String, Integer>:强烈建议使用泛型指定 Key 和 Value的类型,这样编译器会在写代码时就帮你检查类型错误,避免运行时出错。
  • 为什么用 Integer 而不是 int?:因为 Map 的Value 必须是对象(Object),int 是基本数据类型,不能直接放入 Map。Java 会自动装箱(Auto-boxing)将int 转为 Integer,所以你可以直接写 put("张三", 90),编译器会自动处理。
相关推荐
ZenosDoron2 小时前
函数形参传数组
java·jvm·算法
一只幸运猫.2 小时前
字节跳动Java大厂面试版
java·开发语言·面试
xier_ran2 小时前
【C++】“内部”、“外部”、“派生类”、“友元“类
java·开发语言·c++
凭君语未可2 小时前
从静态代理走向动态代理:理解 JDK 动态代理的本质
java·开发语言
黑风风2 小时前
在 Windows 上设置 MAVEN_HOME 环境变量(完整指南)
java·windows·maven
Rsun045512 小时前
15、Java 观察者模式从入门到实战
java·python·模板方法模式
珹洺2 小时前
Java-Spring入门指南(二十三)俩万字超详细讲解利用IDEA手把手教你实现SSM(Spring + SpringMVC + MyBatis)整合,并构建第一个SSM基础系统
java·spring·intellij-idea
yaaakaaang3 小时前
十九、观察者模式
java·观察者模式
小碗羊肉3 小时前
【从零开始学Java | 第三十八篇】序列化流(Object Stream)
java·开发语言