2025/10/14日 每日总结 设计模式实践:迭代器模式玩转Java与C++学生信息遍历

设计模式实践:迭代器模式玩转Java与C++学生信息遍历

在处理集合数据时,我们经常需要遍历元素,但不同集合(如数组、列表、链表)的存储结构差异很大,直接暴露内部实现会导致代码耦合度高。迭代器模式通过提供统一的遍历接口,屏蔽集合的底层实现细节,让客户端可以用相同方式遍历不同集合。本文将分别使用Java内置迭代器和C++ STL迭代器,实现学生信息的有序遍历(学号升序/降序),带你直观感受迭代器模式的魅力。

一、迭代器模式核心思想

迭代器模式是一种行为型设计模式,核心目标是统一集合遍历方式,其关键结构包括:

  1. 迭代器(Iterator):定义遍历集合的接口(如hasNext()判断是否有下一个元素、next()获取下一个元素);

  2. 具体迭代器(Concrete Iterator):实现迭代器接口,适配特定集合的遍历逻辑;

  3. 聚合对象(Aggregate):定义创建迭代器的接口,持有待遍历的元素集合;

  4. 具体聚合对象(Concrete Aggregate):实现聚合接口,返回适配自身的具体迭代器。
    实际开发中,Java和C++已内置成熟的迭代器实现(如Java的Iterator接口、C++ STL的iterator),我们无需手动实现迭代器核心逻辑,直接使用即可快速实现集合遍历。

二、实践场景:学生信息遍历需求

需实现以下功能:

  1. 封装学生类(包含学号、姓名、年龄属性);

  2. 存储多名学生信息到集合中;

  3. 分别按学号升序降序遍历输出学生信息;

  4. 分别使用Java和C++实现,对比两种语言的迭代器使用方式。

三、Java实现:使用内置Iterator遍历

Java的集合框架(如ArrayListLinkedList)已实现迭代器模式,通过iterator()方法获取Iterator实例,即可统一遍历集合。

1. 完整代码

import java.util.*;
// 学生类:封装学号、姓名、年龄属性
class Student {
int id; // 学号
String name; // 姓名
int age; // 年龄
// 构造方法:初始化学生信息
public Student(int id, String name, int age) {
this.id = id;
this.name = name;
this.age = age;
}
}
// 迭代器模式演示:学生信息遍历
public class StudentIteratorDemo {
/**
* 通用遍历方法:使用Iterator遍历学生集合
* @param list 学生集合
*/
public static void printStudents(List<Student> list) {
// 获取迭代器实例
Iterator<Student> iterator = list.iterator();
// 遍历逻辑:hasNext()判断是否有下一个元素,next()获取元素
while (iterator.hasNext()) {
Student student = iterator.next();
// 输出学生信息
System.out.printf("学号: %d, 姓名: %s, 年龄: %d%n", 
student.id, student.name, student.age);
}
}
public static void main(String[] args) {
// 1. 创建集合,存储学生信息
List<Student> studentList = new ArrayList<>();
// 添加示例学生数据(共10名学生)
studentList.add(new Student(20213971, "门殿宇", 20));
studentList.add(new Student(20211234, "张三", 20));
studentList.add(new Student(20214352, "李四", 20));
studentList.add(new Student(20210123, "王五", 20));
studentList.add(new Student(20214444, "小明", 20));
studentList.add(new Student(20215423, "小李", 20));
studentList.add(new Student(20217462, "小王", 20));
studentList.add(new Student(20212344, "小张", 20));
studentList.add(new Student(20213888, "小刘", 20));
studentList.add(new Student(20219999, "小马", 20));
// 2. 按学号升序排序(使用Comparator指定排序规则)
Collections.sort(studentList, Comparator.comparingInt(s -> s.id));
System.out.println("=== 按学号升序遍历 ===");
printStudents(studentList);
// 3. 反转集合,实现学号降序
Collections.reverse(studentList);
System.out.println("\n=== 按学号降序遍历 ===");
printStudents(studentList);
}
}

2. 核心说明

  • 迭代器获取:List集合通过iterator()方法返回Iterator实例,无需关心ArrayList的底层数组实现;

  • 遍历逻辑:hasNext()判断是否还有未遍历元素,next()获取当前元素并移动指针;

  • 排序方式:使用Collections.sort()结合Comparator实现按学号升序,Collections.reverse()反转集合实现降序。

    四、C++实现:使用STL迭代器遍历

    C++ STL(标准模板库)为容器(如vectorlistmap)提供了统一的迭代器接口,通过begin()(起始迭代器)和end()(结束迭代器)控制遍历范围。

    1. 完整代码

    #include <iostream>
    #include <vector>
    #include <algorithm> // 用于sort排序
    #include <string>
    using namespace std;
    // 学生类:封装学号、姓名、年龄属性
    class Student {
    public:
    int id; // 学号
    string name; // 姓名
    int age; // 年龄
    // 构造方法:初始化学生信息
    Student(int id, string name, int age) : id(id), name(name), age(age) {}
    };
    /**
    * 比较函数:按学号升序排序
    * @param a 学生对象a
    * @param b 学生对象b
    * @return a的学号 < b的学号时返回true
    */
    bool compareAsc(const Student& a, const Student& b) {
    return a.id < b.id;
    }
    /**
    * 比较函数:按学号降序排序
    * @param a 学生对象a
    * @param b 学生对象b
    * @return a的学号 > b的学号时返回true
    */
    bool compareDesc(const Student& a, const Student& b) {
    return a.id > b.id;
    }
    /**
    * 通用遍历方法:使用STL迭代器遍历学生容器
    * @param students 存储学生的vector容器
    */
    void printStudents(vector<Student>& students) {
    // 遍历逻辑:迭代器从begin()开始,到end()结束
    for (auto it = students.begin(); it != students.end(); ++it) {
    // 通过迭代器指针访问学生属性
    cout << "学号: " << it->id 
    << ", 姓名: " << it->name 
    << ", 年龄: " << it->age << endl;
    }
    }
    int main() {
    // 1. 创建vector容器,存储学生信息
    vector<Student> students;
    // 添加示例学生数据(共10名学生)
    students.emplace_back(20213971, "门殿宇", 20);
    students.emplace_back(20211234, "张三", 20);
    students.emplace_back(20214352, "李四", 20);
    students.emplace_back(20210123, "王五", 20);
    students.emplace_back(20214444, "小明", 20);
    students.emplace_back(20215423, "小李", 20);
    students.emplace_back(20217462, "小王", 20);
    students.emplace_back(20212344, "小张", 20);
    students.emplace_back(20213888, "小刘", 20);
    students.emplace_back(20219999, "小马", 20);
    // 2. 按学号升序排序(传入升序比较函数)
    sort(students.begin(), students.end(), compareAsc);
    cout << "=== 按学号升序遍历 ===" << endl;
    printStudents(students);
    // 3. 按学号降序排序(传入降序比较函数)
    sort(students.begin(), students.end(), compareDesc);
    cout << "\n=== 按学号降序遍历 ===" << endl;
    printStudents(students);
    return 0;
    }
    

    2. 核心说明

  • 迭代器类型:vector的迭代器为vector<Student>::iterator,可简化为auto(C++11及以上);

  • 遍历逻辑:begin()返回指向第一个元素的迭代器,end()返回指向最后一个元素之后的迭代器,++it移动迭代器;

  • 排序方式:使用sort()函数,传入自定义比较函数(compareAsc/compareDesc)控制排序规则。

    五、Java与C++迭代器使用对比

    特性 Java实现 C++ STL实现
    迭代器获取方式 集合调用iterator()方法 容器调用begin()获取起始迭代器
    遍历控制 hasNext()判断、next()获取元素 迭代器 != end()判断、++it移动指针
    元素访问方式 next()返回元素对象,直接访问属性 迭代器指针->访问属性(如it->id
    排序实现 Collections.sort()+Comparator sort()函数+自定义比较函数
    适用容器 ArrayListLinkedList等集合 vectorlistmap等STL容器

    六、迭代器模式的核心优势与适用场景

    核心优势

  1. 统一遍历接口:无论集合底层是数组、链表还是其他结构,客户端都用相同方式遍历,降低学习和使用成本;

  2. 解耦客户端与集合实现:客户端无需知道集合的存储细节,集合底层修改时(如ArrayList改为LinkedList),遍历代码无需改动;

  3. 支持多种遍历方式:可为同一集合实现不同迭代器(如正序、逆序),客户端按需选择;

  4. 简化集合类代码:集合只需负责元素存储,遍历逻辑委托给迭代器,符合“单一职责原则”。

适用场景

  1. 遍历多种集合:需要统一处理不同类型的集合(如同时遍历ArrayListLinkedList);

  2. 隐藏集合实现细节:不希望暴露集合的内部存储结构(如自定义容器,避免客户端直接操作内部数组);

  3. 复杂遍历需求:需要实现特殊遍历逻辑(如跳跃遍历、条件过滤遍历);

  4. 跨语言/框架适配:不同框架或语言的集合需统一遍历方式(如Java与C++代码交互时的遍历逻辑对齐)。

七、实践总结

  1. 迭代器模式的核心是“分离集合与遍历逻辑”,通过统一接口让遍历更简洁、灵活;

  2. Java和C++已内置成熟的迭代器实现,实际开发中无需重复造轮子,直接使用框架提供的迭代器即可;

  3. 两种语言的迭代器使用逻辑一致:获取迭代器→控制遍历范围→访问元素,仅语法细节有差异;

  4. 迭代器模式是集合框架的基础,掌握它能更好地理解Java集合、C++ STL等框架的设计思想。
    通过本次学生信息遍历的实践,我深刻体会到迭代器模式在统一集合操作中的价值。无论是Java还是C++,合理运用迭代器都能让代码更简洁、耦合度更低,尤其在处理多种集合时,优势更为明显。

posted @ 2025-12-29 14:37  Moonbeamsc  阅读(18)  评论(0)    收藏  举报
返回顶端